Example #1
0
 public static Complex[,] fft2d(Complex[,] input)
 {
     Complex[,] output = (Complex[,])input.Clone();
     // Rows first:
     Complex[] x = new Complex[output.GetLength(1)];
     for (int h = 0; h < output.GetLength(0); h++)
     {
         for (int i = 0; i < output.GetLength(1); i++)
         {
             x[i] = output[h, i];
         }
         x = fft(x);
         for (int i = 0; i < output.GetLength(1); i++)
         {
             output[h, i] = x[i];
         }
     }
     //Columns last
     Complex[] y = new Complex[output.GetLength(0)];
     for (int h = 0; h < output.GetLength(1); h++)
     {
         for (int i = 0; i < output.GetLength(0); i++)
         {
             y[i] = output[i, h];
         }
         y = fft(y);
         for (int i = 0; i < output.GetLength(0); i++)
         {
             output[i, h] = y[i];
         }
     }
     return output;
 }
Example #2
0
        public Complex[] ComputeSpectrum(Complex[] srcData)
        {
            var data = srcData.Clone() as Complex[];
            ComputeSpectrumInPlace(data);

            return data;
        }
Example #3
0
        private static (Complex Zero, bool converge, Complex[] qp) Vrshft(Complex z, Complex[] p, Complex[] h)
        {
            double relstp = 0;
            var    b      = 0;
            var    s      = z.Clone();

            _ = new Complex[p.Length];
            Complex pv;

            Complex[] qp;
            (pv, qp) = p.Deflate(s);
            var mp = pv.Modulus();

            if (mp <= 20 * ErrorEvaluation(qp, s.Modulus(), mp))
            {
                return(s, true, qp);
            }
            double omp = mp;

            LastPart();
            for (int i = 2; i <= 10; i++)
            {
                (pv, qp) = p.Deflate(s);
                mp       = pv.Modulus();
                if (mp <= 20 * ErrorEvaluation(qp, s.Modulus(), mp))
                {
                    return(s, true, qp);
                }
                var pumasa = b == 1 || mp < omp || relstp >= 0.05;
                if (pumasa && mp * 0.1 > omp)
                {
                    return(z, false, qp);
                }
                if (!pumasa)
                {
                    b        = 1;
                    s       *= SMultiplier(relstp);
                    (pv, qp) = p.Deflate(s);
                    for (var j = 1; j <= 5; j++)
                    {
                        h = CalcTH(h, s, qp, pv);
                    }
                }
                omp = pumasa ? mp : DblMax;
                LastPart();
            }
            return(z, false, qp);

            void LastPart()
            {
                h          = CalcTH(h, s, qp, pv);
                var(t1, _) = Calct(s, pv, h);
                if (t1 != new Complex(0, 0))
                {
                    relstp = t1.Modulus() / s.Modulus();
                    s     += t1;
                }
            }
        }
Example #4
0
 public Term(Complex coefficient, Indeterminate[] variables)
 {
     CoEfficient = coefficient.Clone();
     Variables   = CloneHelper <Indeterminate> .CloneCollection(variables).ToArray();
 }
Example #5
0
        /// <summary>
        ///   Performs the Fast Hilbert Transform over a complex[] array.
        /// </summary>
        /// 
        public static void FHT(Complex[] data, FourierTransform.Direction direction)
        {
            int N = data.Length;

            // Forward operation
            if (direction == FourierTransform.Direction.Forward)
            {
                // Makes a copy of the data so we don't lose the
                //  original information to build our final signal
                Complex[] shift = (Complex[])data.Clone();

                // Perform FFT
                FourierTransform.FFT(shift, FourierTransform.Direction.Backward);

                //double positive frequencies
                for (int i = 1; i < (N / 2); i++)
                {
                    shift[i] *= 2.0;
                }
                // zero out negative frequencies
                //  (leaving out the dc component)
                for (int i = (N / 2) + 1; i < N; i++)
                {
                    shift[i] = Complex.Zero;
                }

                // Reverse the FFT
                FourierTransform.FFT(shift, FourierTransform.Direction.Forward);

                // Put the Hilbert transform in the Imaginary part
                //  of the input signal, creating a Analytic Signal
                for (int i = 0; i < N; i++)
                    data[i] = new Complex(data[i].Real, shift[i].Imaginary);
            }

            else // Backward operation
            {
                // Just discard the imaginary part
                for (int i = 0; i < data.Length; i++)
                    data[i] = new Complex(data[i].Real, 0.0);
            }
        }
Example #6
0
        /// <summary>
        /// Removes unnecessary zero terms.
        /// </summary>
        public void Clean()
        {
            int i;

            for (i = Degree; i >= 0 && Coefficients[i] == 0; i--) ;

            Complex[] coeffs = new Complex[i + 1];

            for (int k = 0; k <= i; k++)
                coeffs[k] = Coefficients[k];

            Coefficients = (Complex[])coeffs.Clone();
        }
        /// <summary>
        /// 一维频率抽取基2快速傅里叶变换
        /// 频率抽取:输入为自然顺序,输出为码位倒置顺序
        /// 基2:待变换的序列长度必须为2的整数次幂
        /// </summary>
        /// <param name="sourceData">待变换的序列(复数数组)</param>
        /// <param name="countN">序列长度,可以指定[0,sourceData.Length-1]区间内的任意数值</param>
        /// <returns>返回变换后的序列(复数数组)</returns>
        private Complex[] fft_frequency(Complex[] sourceData, int countN)
        {
            if (countN == 0)
                return null;
            if (sourceData == null)
                return null;

            //2的r次幂为N,求出r.r能代表fft算法的迭代次数
            double dr = Math.Log(countN, 2);
            //int r = Convert.ToInt32(dr);
            int r = (int)Math.Ceiling(dr);   //向上取整
            Complex[] resultData = new Complex[sourceData.Length];

            if (dr - r != 0)
            {
                countN = (int)Math.Pow(2, r);
            }

            //分别存储蝶形运算过程中左右两列的结果
            Complex[] interVar1 = new Complex[countN];
            Complex[] interVar2 = new Complex[countN];

            //interVar1 = (Complex[])sourceData.Clone();
            int index = 0;
            for (; index < sourceData.Length; index++)
            {
                interVar1[index] = sourceData[index];
            }
            if (sourceData.Length < countN)
            {

                while (index < countN)
                {

                    interVar1[index] = new Complex();
                    index++;
                }
            }

            //w代表旋转因子
            Complex[] w = new Complex[countN / 2];
            //为旋转因子赋值。(在蝶形运算中使用的旋转因子是已经确定的,提前求出以便调用)
            //旋转因子公式 \  /\  /k __
            //              \/  \/N  --  exp(-j*2πk/N)
            //这里还用到了欧拉公式
            for (int i = 0; i < countN / 2; i++)
            {
                double angle = -i * Math.PI * 2 / countN;
                w[i] = new Complex(Math.Cos(angle), Math.Sin(angle));
            }

            //蝶形运算
            for (int i = 0; i < r; i++)
            {
                //i代表当前的迭代次数,r代表总共的迭代次数.
                //i记录着迭代的重要信息.通过i可以算出当前迭代共有几个分组,每个分组的长度

                //interval记录当前有几个组
                // <<是左移操作符,左移一位相当于*2
                //多使用位运算符可以人为提高算法速率^_^
                int interval = 1 << i;

                //halfN记录当前循环每个组的长度N
                int halfN = 1 << (r - i);

                //循环,依次对每个组进行蝶形运算
                for (int j = 0; j < interval; j++)
                {
                    //j代表第j个组

                    //gap=j*每组长度,代表着当前第j组的首元素的下标索引
                    int gap = j * halfN;

                    //进行蝶形运算
                    for (int k = 0; k < halfN / 2; k++)
                    {

                        interVar2[k + gap] = interVar1[k + gap] + interVar1[k + gap + halfN / 2];
                        interVar2[k + (halfN / 2) + gap] = (interVar1[k + gap] - interVar1[k + gap + (halfN / 2)]) * w[k * interval];
                    }
                }

                //将结果拷贝到输入端,为下次迭代做好准备
                interVar1 = (Complex[])interVar2.Clone();
            }

            //将输出码位倒置
            for (uint j = 0; j < countN; j++)
            {
                //j代表自然顺序的数组元素的下标索引

                //用rev记录j码位倒置后的结果
                uint rev = 0;
                //num作为中间变量
                uint num = j;

                //码位倒置(通过将j的最右端一位最先放入rev右端,然后左移,然后将j的次右端一位放入rev右端,然后左移...)
                //由于2的r次幂=N,所以任何j可由r位二进制数组表示,循环r次即可
                for (int i = 0; i < r; i++)
                {
                    rev <<= 1;
                    rev |= num & 1;
                    num >>= 1;
                }
                interVar2[rev] = interVar1[j];
            }
            for (int i = 0; i < resultData.Length; i++)
                resultData[i] = interVar2[i];
            return resultData;
        }
Example #8
0
    void FFT(double[] sourceData, double[] spectrumData)
    {
        int N = spectrumData.Length;
        int r = Convert.ToInt32(Math.Log(N, 2));

        Complex[] interVar1 = new Complex[N];
        Complex[] interVar2 = new Complex[N];

        for (int i = 0; i < N; i++)
        {
            interVar1[i] = new Complex(sourceData[i], 0);
        }
        //interVar1 = (Complex[])sourceData.Clone();

        Complex[] w = new Complex[N / 2];

        for (int i = 0; i < N / 2; i++)
        {
            double angle = -i * Math.PI * 2 / N;
            w[i] = new Complex(Math.Cos(angle), Math.Sin(angle));
        }

        for (int i = 0; i < r; i++)
        {
            int interval = 1 << i;

            int halfN = 1 << (r - i);

            for (int j = 0; j < interval; j++)
            {
                int gap = j * halfN;

                for (int k = 0; k < halfN / 2; k++)
                {
                    interVar2[k + gap]             = interVar1[k + gap] + interVar1[k + gap + halfN / 2];
                    interVar2[k + halfN / 2 + gap] = (interVar1[k + gap] - interVar1[k + gap + halfN / 2]) * w[k * interval];
                }
            }

            interVar1 = (Complex[])interVar2.Clone();
        }

        for (uint j = 0; j < N; j++)
        {
            uint rev = 0;
            uint num = j;

            for (int i = 0; i < r; i++)
            {
                rev <<= 1;
                rev  |= num & 1;
                num >>= 1;
            }
            interVar2[rev] = interVar1[j];
        }

        for (int i = 0; i < N; i++)
        {
            spectrumData[i] = Complex.Abs(interVar2[i]);
        }
    }