--- what's feeling reasonable for me here is having the real case function differently from the imaginary case, in that (for now) the user must .view(float) the complex frequency data to process it. the idea of this code would be to bundle the functionality into a class, so it doesn't matter too much what the interface is, but it is nice ot have it small and somewhat repluggable with numpy. 0425 0435 Interestingly, numpy's real-domain FFT is not idempotent for odd-lengthed vectors ! The code assumes an even-lengthed vector. Here you can see me performing a numpy real-domain FFT on a 15-lengthed vector, then a numpy real-domain inverse FFT, and getting back a 14-lengthed vector with differing content: (Pdb) p np.fft.rfft(randvec[:15]).shape (8,) (Pdb) p np.fft.irfft(np.fft.rfft(randvec[:15])).shape (14,) (Pdb) p np.fft.irfft(np.fft.rfft(randvec[:15])) array([0.56987486, 0.76018321, 0.64798214, 0.52903067, 0.52608816, 0.63919848, 0.55517019, 1.19692063, 0.57350214, 0.66362825, 0.74056271, 0.47672495, 1.03527704, 0.1288166 ]) (Pdb) p randvec[:15] 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]) I checked the help and it explains that there are further parameters to provide for this. The help also mentions the Hermitian-symmetry i discovered and learned of by poking at this. ----- Returns the real valued `n`-point inverse discrete Fourier transform of `a`, where `a` contains the non-negative frequency terms of a Hermitian-symmetric sequence. `n` is the length of the result, not the input. If you specify an `n` such that `a` must be zero-padded or truncated, the extra/removed values will be added/removed at high frequencies. One can thus resample a series to `m` points via Fourier interpolation by: ``a_resamp = irfft(rfft(a), m)``. The correct interpretation of the hermitian input depends on the length of the original data, as given by `n`. This is because each input shape could correspond to either an odd or even length signal. By default, `irfft` assumes an even output length which puts the last entry at the Nyquist frequency; aliasing with its symmetric counterpart. By Hermitian symmetry, the value is thus treated as purely real. To avoid losing information, the correct length of the real input **must** be given. 0443 i have a failing assertion at the start of the file now. on to make a real-valued matrix. 0456 array([[ 0.25-0.j , 0.25-0.j , 0.25-0.j , 0.25-0.j ], [ 0.25-0.j , 0. +0.25j, -0.25+0.j , -0. -0.25j], [ 0.25-0.j , -0.25+0.j , 0.25-0.j , -0.25+0.j ], [ 0.25-0.j , -0. -0.25j, -0.25+0.j , 0. +0.25j]]) thinking about how to do multiplication 0515 so, basically the output is real * real - 2 * imag * imag i'm making a matrix, but i'm confused about reshaping it. the complex matrix has [freq, sample], where freq = sample = 28 the real matrix will have shape [freq_components, sample], where freq_components = 30 (2*15). the rows of the real matrix will be composed of alternating real and imaginary parts. the imaginary parts will be negated. and for the doubled frequencies, the imaginary parts will be doubled. the axes are numbered starting from 0. so 0 = frequency, and 1 = sample. numpy has "concatenate" and "stack" operations. if i make a complex matrix, to troubleshoot-bisect clearly with working code, i could then extract the real and imaginary components with mat.real and mat.imag, or with .view(float) . .view(float) would extract them adjacent to each-other in rows, increasing the sample count in the matrix. i want them adjacent to each-other in columns. and .view only works if the matrix is not transposed, kinda. so i might have the real and imaginary components as two separate matrices. i then want to interweave the columns of those matrices. first one value, then another. a way to interwave is to place them adjacent to each other and then reshape the matrix to exclude the dimension -- _i think_; i might be misthinking something here. for the reshape-to-interweave path, the matrix axis to be interwoven needs to be the last one, or at least the smallest index in the underlying storage. so i might transpose the matrix, to make frequencies be rows, and samples be columns. once frequencies are rows, i would add a further dimension of complex and imaginary. this is equivalent to transposing and then doing .view() i think a simple approach would be complex_mat.T.copy().view(float).T . this then leaves out negating the imaginary component. so maybe not using .view() could be clearer to implement. [i could also negate the frequency passed to the wave function, or swap them] here's what i've got:
a array([[1.+2.j, 3.+4.j], [5.+6.j, 7.+8.j]]) np.stack([a.real.T, -a.imag.T], axis=-1).reshape(a.shape[1], a.shape[0]*2).T array([[ 1., 3.], [-2., -4.], [ 5., 7.], [-6., -8.]])
.T is transpose. 0527 0536