CodePlexProject Hosting for Open Source Software

For more details about the Fourier transformation have a look at Wikipedia:

Time Space h(t) |
(formal) |
<=> | Frequency Space H(f) |
(formal) |
---|---|---|---|---|

real | Im{h} = 0 | <=> | Re{H} part even, Im{H} odd | H(-f) = (H(f))* |

imaginary | Re{h} = 0 | <=> | Re{H} part odd, Im{H} even | H(-f) = -(H(f))* |

even | h(-t) = h(t) | <=> | even | H(-f) = H(f) |

odd | h(-t) = -h(t) | <=> | odd | H(-f) = -H(f) |

real even | Im{h} = 0, h(-t) = h(t) | <=> | real even | Im{H} = 0, H(-f) = H(f) |

real odd | Im{h} = 0, h(-t) = -h(t) | <=> | imaginary odd | Re{H} = 0, H(-f) = -H(f) |

imaginary even | Re{h} = 0, h(-t) = h(t) | <=> | imaginary even | Re{H} = 0, H(-f) = H(f) |

imaginary odd | Re{h} = 0, h(-t) = -h(t) | <=> | real odd | Im{H} = 0, H(-f) = -H(f) |

**Default**: Uses a negative exponent sign in forward transformations, and symmetric scaling (that is, sqrt(1/N) for both forward and inverse transformation). This is the convention used in Maple and is widely accepted in the educational sector (due to the symmetry).**AsymmetricScaling**: Set this flag to suppress scaling on the forward transformation but scale the inverse transform with 1/N.**NoScaling**: Set this flag to suppress scaling for both forward and inverse transformation. Note that in this case if you apply first the forward and then inverse transformation you won't get back the original signal (by factor N/2).**InverseExponent**: Uses the positive instead of the negative sign in the forward exponent, and the negative (instead of positive) exponent in the inverse transformation.**Matlab**: Use this flag if you need Matlab compatibility. Equals to setting the*AsymmetricScaling*flag.**NumericalRecpies**: Use this flag if you need Numerical Recipes compatibility. Equal to setting both the*InverseExponent*and the*NoScaling*flags.

The ordering is equivalent to that of Numerical Recipes:

Complex numbers may be represented either as

In multiple dimensions, the data is always (expected to be) ordered such that the last index (the last dimension) changes most rapidly. If you have an image with two dimensions (y,x) and is indexed it with [y,x], this means the array has to be stored row-by-row, so the x coordinate changes more rapidly than the y coordinate.

In frequency space Iridium

You may generate the expected scales for both frequency and time space using the two helper methods

We first generate a real even signal. In Matlab this could be done like this: samples_t = 1.0 ./ (([-16:1:15] ./ 16) .^ 2 + 1.0)

int numSamples = 32; int length = 2 * numSamples; double[] data = new double[length]; for(int i = 0; i < length; i += 2) { double z = (double)(i - numSamples) / numSamples; data[i] = 1.0 / (z * z + 1.0); // real part data[i + 1] = 0.0; // imaginary part }

Result (only real values): 0.5000 0.5322 0.5664 0.6024 0.6400 ... 0.6400 0.6024 0.5664 0.5322

Then we can simply create complex transformation and use the

ComplexFourierTransformation cft = new ComplexFourierTransformation(TransformationConvention.Matlab); cft.TransformForward(data);

Result (only real values): 25.1275 -3.6230 -0.3105 -0.1888 -0.1064 ... -0.1064 -0.1888 -0.3105 -3.6230

Note that the result is again real and even as expected.

The inverse transformation is just as simple:

cft.TransformBackward(data);

Matlab:{BR}

samples_t = 1.0i * (<nowiki>[-16:1:15]</nowiki> ./ 16) ./ (([-16:1:15] ./ 16) .^ 2 + 1.0) + 1.0 ./ ((<nowiki>[-16:1:15]</nowiki> ./ 16) .^ 2 + 1.0) samples_t(1) = real(samples_t(1)) samples_f = fft(samples_t)

int numSamples = 32; int length = 2 * numSamples; double[] data = new double[length]; for(int i = 0; i < length; i += 2) { double z = (double)(i - numSamples) / numSamples; data[i] = 1.0 / (z * z + 1.0); data[i + 1] = z / (z * z + 1.0); } data[1] = 0.0; // peridoic continuation; force odd cft.Convention = TransformationConvention.Matlab; cft.TransformForward(data);

int numSamples = 32; int half = numSamples >> 1; double[] data = new double[numSamples]; for(int i = 0; i < numSamples; i++) { double z = (double)(i - half) / half; data[i] = 1.0 / (z * z + 1.0); } double[] freqReal, freqImag; RealFourierTransformation rft = new RealFourierTransformation(); // default convention rft.TransformForward(data, out freqReal, out freqImag);

And the inverse transformation:

double[] data2 rft.TransformBackward(freqReal, freqImag, out data2);

int numSamples = 32; int half = numSamples >> 1; double[] dataEven = new double[numSamples]; double[] dataOdd = new double[numSamples]; for(int i = 0; i < numSamples; i++) { double z = (double)(i - half) / half; dataEven[i] = 1.0 / (z * z + 1.0); dataOdd[i] = z / (z * z + 1.0); } dataOdd[0] = 0.0; // peridoic continuation; force odd double[] evenReal, evenImag, oddReal, oddImag; // Forward Transform rft.Convention = TransformationConvention.Default; rft.TransformForward(dataEven, dataOdd, out evenReal, out evenImag, out oddReal, out oddImag); // Backward Transform double[] dataEven2, dataOdd2; rft.TransformBackward(evenReal, evenImag, oddReal, oddImag, out dataEven2, out dataOdd2);

Last edited Jul 29, 2012 at 4:43 PM by cdrnet, version 2