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 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); }
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); }