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;
        }
Beispiel #3
0
        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));
                }
            }
        }
Beispiel #4
0
        private static int GetRandomN(int max)
        {
            int[] pqr = new int[3];

            int n = 0;

            do
            {
                n = rnd.Next(max);
            } while (n < 2 || n > max || !Pfa235FFT.Factorize(n, pqr));

            return(n);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        private void MyRoutine2(double[] real1, FourierDirection dir)
        {
            int n   = real1.Length;
            var rnd = new System.Random();

            double[] real2 = new double[n];
            for (int i = 0; i < n; i++)
            {
                real2[i] = rnd.NextDouble() / n;
            }

            var fft = new Pfa235FFT(n);

            fft.RealFFT(real2, real1, dir);
        }
Beispiel #7
0
        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");
            }
        }
Beispiel #8
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));
                }
            }
        }
Beispiel #9
0
        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));
                }
            }
        }
Beispiel #10
0
        private void MyFFT(double[] real, double[] imag, FourierDirection direction)
        {
            var fft = new Pfa235FFT(real.Length);

            fft.FFT(real, imag, direction);
        }