/// <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)) { var 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; }
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; var 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)); } } }
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 static void zzTestZero(int u, int v) { int n = u * v; double[] re = new double[n]; double[] im = new double[n]; var 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"); } }
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; var 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 zzTestReOne_OnePosBothDim(int u, int v) { Console.WriteLine("TestReOn_OnePosBothDim({0},{1})", u, v); int n = u * v; double[] re = new double[n]; double[] im = new double[n]; re[1 * v + 1] = 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 * (((double)i) / u + ((double)j) / 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.Sin(2 * Math.PI * (((double)i) / u + ((double)j) / 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 void MyFFT(double[] real, double[] imag, FourierDirection direction) { var fft = new Pfa235FFT(real.Length); fft.FFT(real, imag, direction); }