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