1024 With this approach, I'm thinking of how I noted the frequencies are basically the same: one is just evaluated in more places. So the situation where wavelet parameters are placed into a matrix could likely be changed to meet the goal. It's a little confusing in that complex numbers are stored there. Basically, each wavelet has two parameters: its real magnitude, and its imaginary magnitude. These are then combined to produce its output wave. Right? Wrong? Let's find out: - The frequency data has a real and imaginary magnitude for each frequency - The matrices contain real and imaginary magnitudes for each frequency/offset pair So the wavelet is first encoded into the matrix with its 0 degree and 90 degree values stored as real and complex components. Then the wavelet is reproduced using the real and imaginary magnitudes. For real-valued waves, though, it's simpler, because of the complex conjugate situation. Each 0 degree value is paired with positive and negative 90 degree values. The output becomes (real_magnitude * real_value - imag_magnitude * imag_value) * 2 . That works fine with sinusoids, I think? I think it's something like (real_mag * cos(x) - imag_mag * sin(x)) * 2? Actually, that doesn't look quite right. I'm testing it with numbers and it kind of looks like changing the phase changes the frequency ...
x = np.arange(16)*np.pi*4/16; ((np.cos(x) - np.sin(x))*2).round(2) array([ 2. , 0. , -2. , -2.83, -2. , -0. , 2. , 2.83, 2. , 0. , -2. , -2.83, -2. , 0. , 2. , 2.83])
I've made a mistake, as the magnitude is now 2.83 and the period is shorter than 2pi. 1035 when the matrix is generated for cosine, i believe the real component is the cosine samp*freq, and the imaginary component is the sine of samp*freq . making the spirals. then, the input needs to phase shift that. i'm mostly concerned with real-valued signals atm, so i can simplify the math. the frequency magnitudes will by m_r + m_i j and m_r - m_i j then i think in the matrix, it also has s_r + s_i j and s_r - s_i j ? so the output sample value is (m_r + m_i j) * (s_r + s_i j) + (m_r - m_i j) * (s_r - s_i j) expanding -> m_r * (s_r + s_i j) + m_i j * (s_r + s_i j) + m_r * (s_r - s_i j) - m_i j * (s_r - s_i j) -> m_r * s_r + m_r * s_i j + m_i j * s_r + m_i j * s_i j + m_r * s_r - m_r * s_i j - m_i j * s_r - m_i j * s_i j -> m_r s_r + m_r s_i j + m_i s_r j - m_i s_i + m_r s_r - m_r s_i j - m_i s_r j + m_i s_i -> 2 m_r s_r ok, um, i just got that all the imaginary parts cancel. i must have made another mistake? - in the code, i have written that the negative frequencies are stored in their matrices as conjugates. this makes sense because the real value is an even function, and the imaginary value is an odd function. - when i take an fft, i see that the frequency magnitudes are also conjugates - in the code, i have written to subtract the imaginary product from the real product ok, i think i failed to handle a double negative sign in the expansion. trying again. [1050] -> (m_r + m_i j) * (s_r + s_i j) + (m_r - m_i j) * (s_r - s_i j) -> m_r * (s_r + s_i j) + m_i j * (s_r + s_i j) + m_r * (s_r - s_i j) - m_i j * (s_r - s_i j) -> m_r * s_r + m_r * s_i j + m_i j * s_r + m_i j * s_i j + m_r * s_r - m_r * s_i j - m_i j * s_r + m_i j * s_i j there's the double-negative i missed. - m_i j * - s_i j == + m_i j * s_i j -> m_r s_r + m_r s_i j + m_i s_r j - m_i s_i + m_r s_r - m_r s_i j - m_i s_r j - m_i s_i -> 2 m_r s_r - 2 m_i s_i there we go. whew. So it takes the real magnitude and multiplies that by the 0 degree value, and the imaginary magnitude and multiplies that by the 90 degree value, and does indeed subtract the other from the one. It's clear that works for 90 degree phases, because then we get the -90 degree value, rather than the 0 degree value. For 45 degree phases, it seems a little different? Maybe not? I think the key could be related to the imaginary and complex parts of the spectrum being already axially projected: they're already cosines and sines. So if the phase is phi, then then the imaginary magnitude is sin phi, and the real magnitude is cos phi. If we imagine the wave as an actual spiral, one can finally see how the phase comes out. The magnitude is the coefficients of sine and cosine. The actual magnitudes of the sine and cosine of the angle. So multiplying them by the sine or by the cosine of the wave, can actually reproduce it: scaling each component appropriately. Each side of the matrix is kind of asking, how much is the cosine scaled? and how much is the sine scaled? and then they reproduce those. [... then why is the wave produced via cos - sin? instead of some kind of dot product maybe?] [ ok .. uh .. how are real-domain waves produced. what if the magnitude is 1.0 for both sin and cosine. this makes for cos(time) - sin(time) ... cos(time) - sin(time) are going to have minima and maxima whenever their values are most extreme, and they're in-phase, so i think this would be at 45 degrees, not sure .. i tried some numbers and it looks like 3pi/4 is a rough minimum. that is indeed about 45 degrees. this minimum value is apparently -sqrt(2). maybe there is some trigonometric identity that converts that, not sure. but sqrt(2) is indeed the magnitude of [1,1]. so that's the right magnitude. and then 45 degrees is the right phase. it's interesting that x*cos(t) - y*sin(t) projects on time that way, making a sine wave with phase equal to atan2(y, x) and magnitude equal to sqrt(x*x+y*y). although i only checked with 45 degrees, this is apparently true since the fourier transform assumes it. ] it would help me figure this out to understand why that happens: why it is that x *cos(t) - y*sin(t) makes a real-domain sine wave with phase == atan2(y, x). I guess I could think of it as a linear interpolation across 90 degrees. Considering that, I can almost see how it might work. We can think of sin(t) == 0 point as one projection line, and the cos(t) == 0 point as another projection line. It interpolates in a circular manner, projecting between these. Let's see, um ... so it starts at sin(t) == 0, and here it projects solely the cosine component. As it moves from sin(t) == 0, increasing t until cos(t) == 0, the projection changes. The cosine component reduces, and the sine component increases. The amounts these happen are exactly proportional to the orthographic projection of a circle, cylinder, or spiral, when viewed from the side and rotated. So, two things are changing. "t" is changing as we move from sin(t)=0 to cos(t)=0. At the same time, "phi" changes as we change the phase fo the wave from m_s = 0 to m_c = 0; that is, from sin(phi) = 0 to cos(phi) = 0. Each of these projections is the X and Y coordinates of an angle. [uhhhhh !!!] so we might think of the angle as a rod sticking out of a center. It's projected onto two dimensions: the X axis and the Y axis. Each of these two values is two views of the same rod reprsenting the angle. This rod could instead be a point along a spiral, or a plane cutting a cylinder. The cylinder view could overlay a view of the wvae, but I'm not yet sure if that choice helps things line up. Then when we move across time, the same thing is happening. There is some rod, that is now spinning with angle t, and if the wave is charted we see its Y or X coordinate move up and down. We only see one projection of this one, but it is calculated from both. it is so hard to hold these things in my mind. OK, so that X or Y coordinate is made from an underlying X or Y coordinate used to calculate it. There is a "model wave" that might better be considered something other than a wave for this, that has _both_ X and Y coordinates. These X and Y coordinate values help it track where it is. grrrrrr ok um 3 parts - the magnitude and phase - the model wave - the actual wave for the magnitude, we have the X and Y coordinates. We can view it from the X axis, or from the Y. for the model wave, we also have the X and Y coordinates at every point the actual wave is X_mag * X_model - Y_mag * Y_model one thing we can think of is how the phases line up as X_mag goes to 0, this means that the phase is entering all of the Y_mag space this aligns with where Y_model is 0 or 1 i've written and looked at that repeatedly if we are at a shallow angle, say X_mag is small and Y_mag is big this means we are only a bit off from being aligned with X_model so, X_model has a little bit, but it is mostly Y_model so what's key here is that X_mag is the cosine of phi and Y_mag is the sine of phi whereas X_model is the cosine of time and Y_model is the sine of time then after that: sines and cosines are orthogonal projections of rotations. i'm having a lot of inhibition around this conclusion and i'm not sure all the parts are present enough to write enough logical steps to retain it. but i know there is a way. so not only are X_mag and Y_mag the cosine and sine of phi, the wave phase, they are also the X and Y projections of it, and can be used to scale something into that angle. They can also be used to perform those orthogonal projections, or to rotate and scale an axial vector into their space. well, skipping a lot of projection, i tried websearching for "rotation formula" and found cos theta - sin theta . basically, multiplying an axis by cos theta - sin theta projects a rotation of a vector lying in that axis, of theta, back onto the axis. so no longer a need for projection planes that spin at 90 degree offsets around cylinders and spirals and rods. so what this result, 2(cos phi * cos t - sin phi * sin t) is doing, is rotating the real component of the wave by phi and by t both, treating it as a 2-dimension vector. so if my square wave spews out a step function, that step function will be treated as a vector to then be rotated and reprojected. it's not really accurate to use just the step function, when the phase shifting is still mag_x * wave(t) - mag_y * wave(t+0.25) . and this linear product is performed in the matrix multiplication, so if i were to draft massaging it into sinusoidal space then back to square wave space, it would presently add code outside the implementation functions. the phase change is made by applying the rotation function to the sampled model wave, and directly taking and using the output. phase change is made by applying the rotation function (cos * a - sin * b) to the sampled model wave, and directly taking and using the output. I think this means that as the phase is changed, the output wave will actually smoothly slide up and down, if it's a step function! For my idea of using square waves or step functions, I imagine a phase change shifting them left and right, not sliding them up and down. This makes it relatively clear that non-sinusoid wave models would probably want a different matrix, in this approach, because how the multiplication is done assumes that rotating the model samples produces phase shift. [ Thinking about this, one can see how the meaning of complex multiplication is angle addition, by seeing how distributed multiplication (a + bi)(c + di) makes a rotation matrix as its expansion. ]