/// <summary> /// Executes the fourier transformation itself (without data pretreatment). /// </summary> /// <exception cref="System.InvalidOperationException">The Fourier transformation was already executed.</exception> protected virtual void ExecuteFourierTransformation() { if (_arraysContainTransformation) throw new InvalidOperationException("The Fourier transformation was already executed."); var numColumns = NumberOfColumns; var numRows = NumberOfRows; var rePart = ((IMatrixInArray1DRowMajorRepresentation<double>)_realMatrix).GetArray1DRowMajor(); _imagMatrix = new DoubleMatrixInArray1DRowMajorRepresentation(numRows, numColumns); var imPart = ((IMatrixInArray1DRowMajorRepresentation<double>)_imagMatrix).GetArray1DRowMajor(); // fourier transform either with Pfa (faster) or with the Chirp-z-transform if (Pfa235FFT.CanFactorized(numRows) && Pfa235FFT.CanFactorized(numColumns)) { Pfa235FFT fft = new Pfa235FFT(numRows, numColumns); fft.FFT(rePart, imPart, FourierDirection.Forward); } else { var matrixRe = new DoubleMatrixInArray1DRowMajorRepresentation(rePart, numRows, numColumns); ChirpFFT.FourierTransformation2D(matrixRe, _imagMatrix, FourierDirection.Forward); } _arraysContainTransformation = true; }
protected static string TwoDimFFT(Altaxo.AltaxoDocument mainDocument, GUI.WorksheetController dg, out double[] rePart, out double[] imPart) { int rows = dg.Doc.DataColumns.RowCount; int cols = dg.Doc.DataColumns.ColumnCount; // reserve two arrays (one for real part, which is filled with the table contents) // and the imaginary part - which is left zero here) rePart = new double[rows*cols]; imPart = new double[rows*cols]; // fill the real part with the table contents for(int i=0;i<cols;i++) { Altaxo.Data.INumericColumn col = dg.Doc[i] as Altaxo.Data.INumericColumn; if(null==col) { return string.Format("Can't apply fourier transform, since column number {0}, name:{1} is not numeric",i,dg.Doc[i].FullName); } for(int j=0;j<rows;j++) { rePart[i*rows+j] = col[j]; } } // test it can be done if(!Pfa235FFT.CanFactorized(cols)) return string.Format("Can't apply fourier transform, since the number of cols ({0}) are not appropriate for this kind of fourier transform.",cols); if(!Pfa235FFT.CanFactorized(rows)) return string.Format("Can't apply fourier transform, since the number of rows ({0}) are not appropriate for this kind of fourier transform.",rows); // fourier transform Pfa235FFT fft = new Pfa235FFT(cols,rows); fft.FFT(rePart,imPart,FourierDirection.Forward); // replace the real part by the amplitude for(int i=0;i<rePart.Length;i++) { rePart[i] = Math.Sqrt(rePart[i]*rePart[i]+imPart[i]*imPart[i]); } return null; }
private void MyFFT(double[] real, double[] imag, FourierDirection direction) { Pfa235FFT fft = new Pfa235FFT(real.Length); fft.FFT(real, imag, direction); }
private static void zzTestImOne_ArbPosBothDim(int u, int v) { int upos = rnd.Next(u); int vpos = rnd.Next(v); int n = u * v; double[] re = new double[n]; double[] im = new double[n]; im[upos * v + vpos] = 1; Pfa235FFT fft = new Pfa235FFT(u, v); fft.FFT(re, im, FourierDirection.Inverse); for (int i = 0; i < u; i++) { for (int j = 0; j < v; j++) { Assert.AreEqual(Math.Sin(2 * Math.PI * (((double)i) * upos / u + ((double)j) * vpos / v)), re[i * v + j], n * 1E-15, string.Format("FFT({0},{1}) of re 1 at pos 1 re[{2},{3}]", u, v, i, j)); Assert.AreEqual(Math.Cos(2 * Math.PI * (((double)i) * upos / u + ((double)j) * vpos / v)), im[i * v + j], n * 1E-15, string.Format("FFT({0},{1}) of re 1 at pos 1 im[{2},{3}]", u, v, i, j)); } } }
private static void zzTestReOne_OnePos2ndDim(int u, int v) { int n = u * v; double[] re = new double[n]; double[] im = new double[n]; re[1 * v] = 1; Pfa235FFT fft = new Pfa235FFT(u, v); fft.FFT(re, im, FourierDirection.Inverse); for (int i = 0; i < u; i++) { for (int j = 0; j < v; j++) { Assert.AreEqual(Math.Cos((2 * Math.PI * i) / u), re[i * v + j], n * 1E-15, string.Format("FFT({0},{1}) of re 1 at pos 1 re[{2},{3}]", u, v, i, j)); Assert.AreEqual(-Math.Sin((2 * Math.PI * i) / u), im[i * v + j], n * 1E-15, string.Format("FFT({0},{1}) of re 1 at pos 1 im[{2},{3}]", u, v, i, j)); } } }
private static void zzTestZero(int u, int v) { int n = u * v; double[] re = new double[n]; double[] im = new double[n]; Pfa235FFT fft = new Pfa235FFT(u, v); fft.FFT(re, im, FourierDirection.Inverse); for (int i = 0; i < n; i++) { Assert.AreEqual(0, re[i], 0, "FFT of zero should give re=0"); Assert.AreEqual(0, im[i], 0, "FFT of zero should give im=0"); } }