public RealFourierTransform(int length) { _numberOfData = length; if (length < 1) { throw new ArgumentException("length smaller than 1 is not appropriate here."); } else if (length < 3) { _method = Method.Trivial; } else if (Calc.BinaryMath.IsPowerOfTwo(length)) { // use Hartley transform _method = Method.Hartley; } else if (Pfa235FFT.CanFactorized(length)) { // use Pfa235 transform _method = Method.Pfa235; _pfa235 = new Pfa235FFT(_numberOfData); } else { // use chirp transform _method = Method.Chirp; } }
/// <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; }
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); }