public static void FFT(WorksheetController dg) { int len = dg.SelectedDataColumns.Count; if (len == 0) { return; // nothing selected } if (!(dg.DataTable[dg.SelectedDataColumns[0]] is Altaxo.Data.DoubleColumn)) { return; } // preliminary // we simply create a new column, copy the values Altaxo.Data.DoubleColumn col = (Altaxo.Data.DoubleColumn)dg.DataTable[dg.SelectedDataColumns[0]]; double[] arr = col.Array; FastHartleyTransform.RealFFT(arr, arr.Length); col.Array = arr; }
fft_complex_convolution(double[] fr, double[] fi, double[] gr, double[] gi, uint ldn, double v /*=0.0*/) // // (complex, cyclic) convolution: (gr,gi)[] := (fr,fi)[] (*) (gr,gi)[] // (use zero padded data for usual conv.) // ldn := base-2 logarithm of the array length // // supply a value for v for a normalization factor != 1/n // { // const int is = 1; int n = (1 << (int)ldn); FastHartleyTransform.FFT(fr, fi, n); //FFT(fr, fi, ldn, is); FastHartleyTransform.FFT(gr, gi, n); //FFT(gr, gi, ldn, is); if (v == 0.0) { v = 1.0 / n; } for (uint k = 0; k < n; ++k) { double tr = fr[k]; double ti = fi[k]; cmult(gr[k], gi[k], ref tr, ref ti); gr[k] = tr * v; gi[k] = ti * v; cmult(fr[k], fi[k], ref gr[k], ref gi[k]); } FastHartleyTransform.IFFT(gr, gi, n); // FFT(gr, gi, ldn, -is); }
/// <summary> /// Performs a cyclic correlation of splitted complex data of arbitrary length. /// </summary> /// <param name="datare">Real part of the data array (first input array).</param> /// <param name="dataim">Imaginary part of the data array (first input array).</param> /// <param name="responsere">Real part of the response array (second input array).</param> /// <param name="responseim">Imaginary part of the response array (second input array).</param> /// <param name="resultre">The real part of the resulting array.</param> /// <param name="resultim">The imaginary part of the resulting array.</param> /// <param name="n">The convolution size. The input and result arrays may be larger, but of course not smaller than this number.</param> public static void CyclicCorrelation( double[] datare, double[] dataim, double[] responsere, double[] responseim, double[] resultre, double[] resultim, int n) { int msize = GetNecessaryCorrelationSize(n); // System.Diagnostics.Trace.WriteLine(string.Format("Enter chirp convolution with n={0}, m={1}",n,msize)); double[] srcre = new double[msize]; double[] srcim = new double[msize]; double[] rspre = new double[msize]; double[] rspim = new double[msize]; Array.Copy(datare, srcre, n); Array.Copy(dataim, srcim, n); // Copy the response not only to the beginning, but also immediatly after the data Array.Copy(responsere, rspre, n); Array.Copy(responsere, 0, rspre, n, n - 1); Array.Copy(responseim, rspim, n); Array.Copy(responseim, 0, rspim, n, n - 1); FastHartleyTransform.CyclicCorrelationDestructive(srcre, srcim, rspre, rspim, srcre, srcim, msize); Array.Copy(srcre, resultre, n); Array.Copy(srcim, resultim, n); }
/// <summary> /// Performs a convolution of two comlex arrays with are in splitted form (i.e. real and imaginary part are separate arrays). Attention: the values of the /// input arrays will be destroyed! /// </summary> /// <param name="resultreal">The real part of the result. (may be identical with arr1 or arr2).</param> /// <param name="resultimag">The imaginary part of the result (may be identical with arr1 or arr2).</param> /// <param name="arr1real">The real part of the first input array. Destroyed at the end of function!</param> /// <param name="arr1imag">The imaginary part of the first input array. Destroyed at the end of function!</param> /// <param name="arr2real">The real part for the pre-fouriertransformed second sequence to convolute.</param> /// <param name="arr2imag">The imaginary part for the pre-fouriertransformed second sequence to convolute.</param> /// <param name="arrsize">The length of the convolution. Has to be equal or smaller than the array size. Has to be a power of 2!</param> private static void fhtconvolutionWithFouriertransformed2ndArgument(double[] resultreal, double[] resultimag, double[] arr1real, double[] arr1imag, double[] arr2real, double[] arr2imag, int arrsize) { FastHartleyTransform.FFT(arr1real, arr1imag, arrsize); MultiplySplittedComplexArrays(resultreal, resultimag, arr1real, arr1imag, arr2real, arr2imag, arrsize); FastHartleyTransform.IFFT(resultreal, resultimag, arrsize); NormalizeArrays(resultreal, resultimag, 1.0 / arrsize, arrsize); }
void MyCorrelationRoutine(double[] src1real, double[] src2real, double[] resultreal, int n) { double[] inp1re = new double[n]; double[] inp2re = new double[n]; Array.Copy(src1real, inp1re, n); Array.Copy(src2real, inp2re, n); FastHartleyTransform.CyclicCorrelationDestructive(inp1re, inp2re, resultreal, n); }
void MyConvolution(double[] re1, double[] re2, double[] re, int n) { double[] inp1 = new double[n]; double[] inp2 = new double[n]; Array.Copy(re1, inp1, n); Array.Copy(re2, inp2, n); FastHartleyTransform.CyclicDestructiveConvolution(inp1, inp2, re, n); }
private void Precompute_Fouriertransformed_ChirpFactorsConjugate() { // use the chirp factors that were already computed // these factors differ only in the sign of the Exp() function, thus the imaginary part changes sign // furthermore, the array must be filled from the left and from the right (for later convolution) _fserp_real[0] = 1; _fserp_imag[0] = 0; for (int i = 1; i < _arrSize; i++) { _fserp_real[_msize - i] = _fserp_real[i] = _chirpfactors_real[i]; _fserp_imag[_msize - i] = _fserp_imag[i] = -_chirpfactors_imag[i]; // inverse sign } FastHartleyTransform.FFT(_fserp_real, _fserp_imag, _msize); }
static void fhtconvolution(Complex[] resarray, Complex[] arr1, Complex[] arr2, int arrsize) { double[] fht1real = new double[arrsize]; double[] fht1imag = new double[arrsize]; double[] fht2real = new double[arrsize]; double[] fht2imag = new double[arrsize]; CopyFromComplexToSplittedArrays(fht1real, fht1imag, arr1, arrsize); CopyFromComplexToSplittedArrays(fht2real, fht2imag, arr2, arrsize); // do a convolution by fourier transform both parts, multiply and inverse fft FastHartleyTransform.FFT(fht1real, fht1imag, arrsize); FastHartleyTransform.FFT(fht2real, fht2imag, arrsize); MultiplySplittedComplexArrays(fht1real, fht1imag, fht1real, fht1imag, fht2real, fht2imag, arrsize); FastHartleyTransform.IFFT(fht1real, fht1imag, arrsize); NormalizeArrays(fht1real, fht1imag, 1.0 / arrsize, arrsize); CopyFromSplittedArraysToComplex(resarray, fht1real, fht1imag, arrsize); }
/// <summary> /// Performs a inplace fourier transformation. The original values are overwritten by the fourier transformed values. /// </summary> /// <param name="arr">The data to transform. On output, the fourier transformed data.</param> /// <param name="direction">Specify forward or reverse transformation here.</param> public void Transform(double[] arr, FourierDirection direction) { if (arr.Length != _numberOfData) { throw new ArgumentException(string.Format("Length of array arr ({0}) is different from the length specified at construction ({1})", arr.Length, _numberOfData), "arr"); } switch (_method) { case Method.Trivial: { if (_numberOfData == 2) { double a0 = arr[0], a1 = arr[1]; arr[0] = a0 + a1; arr[1] = a0 - a1; } } break; case Method.Hartley: { FastHartleyTransform.RealFFT(arr, direction); } break; case Method.Pfa235: { NullifyTempArrN1(); _pfa235.RealFFT(arr, _tempArr1N, direction); } break; case Method.Chirp: { if (direction == FourierDirection.Forward) { NullifyTempArrN1(); } else { if (null == this._tempArr1N) { _tempArr1N = new double[_numberOfData]; } _tempArr1N[0] = 0; for (int k = 1; k <= _numberOfData / 2; k++) { double sumreal = arr[k]; double sumimag = arr[_numberOfData - k]; _tempArr1N[k] = sumimag; _tempArr1N[_numberOfData - k] = -sumimag; arr[_numberOfData - k] = sumreal; } } ChirpFFT.FFT(arr, _tempArr1N, direction, ref _fftTempStorage); if (direction == FourierDirection.Forward) { for (int k = 0; k <= _numberOfData / 2; k++) { double sumreal = arr[k]; double sumimag = _tempArr1N[k]; if (k != 0 && (k + k) != _numberOfData) { arr[_numberOfData - k] = sumimag; } arr[k] = sumreal; } } } break; } }
void MyConvolution(double[] re1, double[] im1, double[] re2, double[] im2, double[] re, double[] im, int n) { FastHartleyTransform.CyclicConvolution(re1, im1, re2, im2, re, im, null, null, n); }
void MyConvolution(double[] re1, double[] re2, double[] re, int n) { FastHartleyTransform.CyclicRealConvolution(re1, re2, re, n, null); }