Exemplo n.º 1
0
 /// <summary>
 /// 一次元FFT
 /// </summary>
 /// <param name="src"></param>
 /// <param name="direction"></param>
 /// <returns></returns>
 public static Complex[] FFT(Complex[] src, FourierDirectionEnum direction)
 {
     p.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
     Complex[] dest = fft(src, direction);
     //ComplexArray.Scale(dest, 1 / Math.Sqrt(src.Length));
     for (int i = 0; i < dest.Length; i++)
     {
         dest[i] *= 1 / Math.Sqrt(src.Length);
     }
     return(dest);
 }
Exemplo n.º 2
0
        private static Complex[] fft(Complex[] src, FourierDirectionEnum direction)
        {
            sign = direction == FourierDirectionEnum.Forward ? -1 : 1;

            return(fft(src));
        }
Exemplo n.º 3
0
        /// <summary>
        /// 2次元FFT
        /// </summary>
        /// <param name="src"></param>
        /// <param name="direction"></param>
        /// <returns></returns>
        public static Complex[][] FFT(Complex[][] src, double[][] filter, FourierDirectionEnum direction)
        {
            if (src == null || src.Length == 0 || src[0] == null || src[0].Length == 0)
            {
                return(null);
            }
            int centerX = src[0].Length / 2, centerY = src.Length / 2;

            //まずFilterを作用させる && 4分割して組みなおす
            Complex[][] src2 = new Complex[src.Length][];
            for (int i = 0; i < src.Length; i++)
            {
                src2[i] = new Complex[src[i].Length];
            }

            for (int i = 0; i < src.Length; i++)
            {
                for (int j = 0; j < src[i].Length; j++)
                {
                    if (direction == FourierDirectionEnum.Inverse)
                    {
                        src2[i < centerY ? i + centerY : i - centerY][j < centerX ? j + centerX : j - centerX] = filter == null ? src[i][j] : (1 - filter[i][j]) * src[i][j];
                    }
                    else
                    {
                        src2[i][j] = filter == null ? src[i][j] : (1 - filter[i][j]) * src[i][j];
                    }
                }
            }
            src  = null;
            sign = direction == FourierDirectionEnum.Forward ? -1 : 1;

            FFTdelegate[]  d  = new FFTdelegate[ThreadTotal];
            IAsyncResult[] ar = new IAsyncResult[ThreadTotal];
            for (int i = 0; i < ThreadTotal; i++)
            {
                d[i] = new FFTdelegate(FFT);
            }

            //まず各行ごとにFFT
            Complex[][] dest1 = new Complex[src2.Length][];
            for (int i = 0; i < dest1.Length; i++)
            {
                for (int j = 0; j < ThreadTotal && i + j < dest1.Length; j++)
                {
                    ar[j] = d[j].BeginInvoke(src2[i + j], direction, ref dest1[i + j], null, null);//スレッド起動
                }
                for (int j = 0; j < ThreadTotal && i + j < dest1.Length; j++)
                {
                    d[j].EndInvoke(ref dest1[i + j], ar[j]);//スレッド終了待ち
                    if (ProgressEvent != null)
                    {
                        ProgressEvent();
                    }
                }
                i += ThreadTotal - 1;
            }

            //次に各列ごとにFFT
            Complex[][] dest2 = new Complex[src2[0].Length][];
            for (int i = 0; i < dest2.Length; i++)
            {
                dest2[i] = new Complex[src2.Length];
                for (int j = 0; j < src2.Length; j++)
                {
                    dest2[i][j] = dest1[j][i];
                }
            }

            for (int i = 0; i < dest2.Length; i++)
            {
                for (int j = 0; j < ThreadTotal && i + j < dest2.Length; j++)
                {
                    ar[j] = d[j].BeginInvoke(dest2[i + j], direction, ref dest2[i + j], null, null);//スレッド起動
                }
                for (int j = 0; j < ThreadTotal && i + j < dest2.Length; j++)
                {
                    d[j].EndInvoke(ref dest2[i + j], ar[j]);//スレッド終了待ち
                    if (ProgressEvent != null)
                    {
                        ProgressEvent();
                    }
                }
                i += ThreadTotal - 1;
            }

            //dest2の行と列を入れ替えてdest1に格納し返す
            for (int i = 0; i < src2.Length; i++)
            {
                for (int j = 0; j < src2[0].Length; j++)
                {
                    dest1[i][j] = dest2[j][i];
                }
            }
            dest2 = null;

            if (direction == FourierDirectionEnum.Inverse)
            {
                return(dest1);
            }
            else //最後に入れ替える必要がある時は
            {
                Complex[][] dest3 = new Complex[src2.Length][];
                for (int i = 0; i < dest3.Length; i++)
                {
                    dest3[i] = new Complex[src2[i].Length];
                }
                for (int i = 0; i < src2.Length; i++)
                {
                    for (int j = 0; j < src2[i].Length; j++)
                    {
                        dest3[i < centerY ? i + centerY : i - centerY][j < centerX ? j + centerX : j - centerX] = dest1[i][j];
                    }
                }
                dest1 = null;
                return(dest3);
            }
        }
Exemplo n.º 4
0
 private static void FFT(Complex[] src, FourierDirectionEnum direction, ref Complex[] dest)
 {
     dest = FFT(src, direction);
 }
Exemplo n.º 5
0
 public static Complex[][] FFT(Complex[][] src, FourierDirectionEnum direction)
 {
     return(FFT(src, null, direction));
 }