the comparison is failing, [although the sample_idcs look right now,] so given fourier.py passes its internal tests, the difference must lie in how waveform is being sampled compared to the assumptions that fourier.py is making 0843
i can go into both functions and again examine the first few data items 7 def sample_sinusoids_funny(data, fractional_indices, max_period): 8 -> return np.array([ 9 ((np.exp(2j * sample_idx * np.pi * np.fft.fftfreq(len(data)))) * np.fft.fft(data)).sum() / len(data) for sample_idx in fractional_indices 10 ]) (Pdb) p data array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 , 0.64589411, 0.43758721, 0.891773 , 0.96366276, 0.38344152, 0.79172504, 0.52889492, 0.56804456, 0.92559664, 0.07103606, 0.0871293 ]) (Pdb) p fractional_indices array([ 0. , 13.83351839, 27.66703678, 41.50055518, 55.33407357, 69.16759196, 83.00111035, 96.83462875, 110.66814714, 124.50166553, 138.33518392, 152.16870232, 166.00222071, 179.8357391 , 193.66925749, 207.50277589]) i'm struggling .. i'm going to skip into the fourier.py data 4 def create_freq2time(freq_rate, time_rate, freq_count, time_count): 5 freqs = np.fft.fftfreq(freq_count) 6 offsets = np.arange(freq_count) * freq_rate / time_rate 7 -> mat = np.exp(2j * np.pi * np.outer(freqs, offsets)) 8 return mat / freq_count # scaled to match numpy convention (Pdb) p freq_rate / time_rate 0.07228818957167302 (Pdb) p offsets array([0. , 0.07228819, 0.14457638, 0.21686457, 0.28915276, 0.36144095, 0.43372914, 0.50601733, 0.57830552, 0.65059371, 0.7228819 , 0.79517009, 0.86745827, 0.93974646, 1.01203465, 1.08432284]) huh. it's using the old shorter offsets (Pdb) p freq_rate, time_rate (1.1566110331467683, 16) the rates are samples / unit, I think. time here is recording, and freq is waveform. so it's saying the recording goes at 16 samples / unit . the unit must be the whole recoridng. the waveform frequency would then be 16 / max_period * 16, I guess. i'm just passing max_period. i decided 1 recording sample is 1 time unit which simplifies the expressions. waveform_rate = waveform_N / max_period. recording_rate = 1 the offsets in create_freq2time are now the same as the fractional indices in the sampler. 0852 here's [two rows of] the resulting matrix before it's scaled. these would be the DC frequency multipliers, and then the 1st frequency's multipliers: (Pdb) p mat[:2] array([[ 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j , 1. +0.j ], [ 1. +0.j , 0.65940045-0.75179189j, -0.13038209-0.99146382j, -0.83134847-0.55575149j, -0.96600102+0.25853825j, -0.44261455+0.89671197j, 0.38228055+0.92404631j, 0.94676649+0.32192113j, 0.86631595-0.49949643j, 0.19573177-0.98065747j, -0.60818472-0.79379553j, -0.99780632-0.06620079j, -0.70772316+0.70648987j, 0.06446038+0.99792027j, 0.79273357+0.60956828j, 0.98099736-0.19402106j]]) as i do this i find earlier assertions i can add that simplify the problem. 0854 (Pdb) n > /shared/src/scratch/test2_upsamplish.py(21)<module>() -> waveform_freq_2_recording_time = fourier.create_freq2time(waveform_rate, recording_rate, waveform_N, recording_N) (Pdb) n > /shared/src/scratch/test2_upsamplish.py(22)<module>() -> assert np.allclose(np.fft.fft(waveform) @ waveform_freq_2_recording_time, recording) (Pdb) n > /shared/src/scratch/test2_upsamplish.py(23)<module>() -> waveform_freq_reconstructed = np.linalg.solve(waveform_freq_2_recording_time, recording) It passed the first assertion. The matrix returned from fourier.py produces the same sampled recording as the sampler function. So it's all logical errors in running the test. 0855