Exemplo n.º 1
0
        FFT(double[] x, double[] y, uint n, FourierDirection direction, ref object temporaryStorage)
        {
            ChirpNativeFFTStorage s = temporaryStorage as ChirpNativeFFTStorage;

            chirpnativefft(x, y, x, y, (int)n, direction, ref s);
            temporaryStorage = s;
        }
Exemplo n.º 2
0
        FourierTransformation2D(IMatrix <double> matrixRe, IMatrix <double> matrixIm, FourierDirection direction)
        {
            int numberOfRows    = matrixRe.RowCount;
            int numberOfColumns = matrixRe.ColumnCount;

            // Do the FFT in the first direction

            // First direction: transform all columns of the matrix
            ChirpNativeFFTStorage tempStorage = null;
            var resultArrayRe = new double[numberOfRows];
            var resultArrayIm = new double[numberOfRows];
            var inputArrayRe  = new double[numberOfRows];
            var inputArrayIm  = new double[numberOfRows];

            for (int c = 0; c < numberOfColumns; ++c) // for each column
            {
                for (int r = 0; r < numberOfRows; ++r)
                {
                    inputArrayRe[r] = matrixRe[r, c];
                    inputArrayIm[r] = matrixIm[r, c];
                }

                chirpnativefft(resultArrayRe, resultArrayIm, inputArrayRe, inputArrayIm, numberOfRows, direction, ref tempStorage);

                for (int r = 0; r < numberOfRows; ++r)
                {
                    matrixRe[r, c] = resultArrayRe[r];
                    matrixIm[r, c] = resultArrayIm[r];
                }
            }

            // Second direction: transform all rows of the matrix
            if (numberOfColumns != numberOfRows)
            {
                resultArrayRe = new double[numberOfColumns];
                resultArrayIm = new double[numberOfColumns];
                inputArrayRe  = new double[numberOfColumns];
                inputArrayIm  = new double[numberOfColumns];
            }

            for (int r = 0; r < numberOfRows; ++r) // for each row
            {
                for (int c = 0; c < numberOfColumns; ++c)
                {
                    inputArrayRe[c] = matrixRe[r, c];
                    inputArrayIm[c] = matrixIm[r, c];
                }

                chirpnativefft(resultArrayRe, resultArrayIm, inputArrayRe, inputArrayIm, numberOfColumns, direction, ref tempStorage);

                for (int c = 0; c < numberOfColumns; ++c)
                {
                    matrixRe[r, c] = resultArrayRe[c];
                    matrixIm[r, c] = resultArrayIm[c];
                }
            }
        }
Exemplo n.º 3
0
        private static void chirpnativefft(
            double[] resultreal,
            double[] resultimag,
            double[] inputreal,
            double[] inputimag,
            int arrsize,
            FourierDirection direction,
            ref ChirpNativeFFTStorage s)
        {
            if (arrsize <= 2)
            {
                throw new ArgumentException("This algorithm works for array sizes > 2 only.");
            }

            int msize = GetNecessaryTransformationSize(arrsize);

            if (s == null || arrsize != s._arrSize || direction != s._direction)
            {
                s = new ChirpNativeFFTStorage(msize, arrsize, direction);
            }
            else // if the temp storage is not fresh, we have to clear the arrays first
            {
                Array.Clear(s._xjfj_real, 0, msize);
                Array.Clear(s._xjfj_imag, 0, msize);
            }

            // make the arrays local variables
            double[] xjfj_real     = s._xjfj_real;
            double[] xjfj_imag     = s._xjfj_imag;
            double[] fserp_real    = s._fserp_real;
            double[] fserp_imag    = s._fserp_imag;
            double[] resarray_real = s._resarray_real;
            double[] resarray_imag = s._resarray_imag;

            var chirpfactor_real = s._chirpfactors_real;
            var chirpfactor_imag = s._chirpfactors_imag;

            // multiply the input array with the chirpfactors
            for (int i = 0; i < arrsize; ++i)
            {
                xjfj_real[i] = inputreal[i] * chirpfactor_real[i] - inputimag[i] * chirpfactor_imag[i];
                xjfj_imag[i] = inputreal[i] * chirpfactor_imag[i] + inputimag[i] * chirpfactor_real[i];
            }

            // convolute xjfj with precomputed fourier-transformation of fserp
            fhtconvolutionWithFouriertransformed2ndArgument(resarray_real, resarray_imag, xjfj_real, xjfj_imag, fserp_real, fserp_imag, msize);

            // multiply the result  with the chirpfactors
            for (int i = 0; i < arrsize; ++i)
            {
                resultreal[i] = resarray_real[i] * chirpfactor_real[i] - resarray_imag[i] * chirpfactor_imag[i];
                resultimag[i] = resarray_real[i] * chirpfactor_imag[i] + resarray_imag[i] * chirpfactor_real[i];
            }
        }
Exemplo n.º 4
0
        FFT(double[] x, double[] y, FourierDirection direction, ref object temporaryStorage)
        {
            if (x.Length != y.Length)
            {
                throw new ArgumentException("Length of real and imaginary array do not match!");
            }


            ChirpNativeFFTStorage s = temporaryStorage as ChirpNativeFFTStorage;

            chirpnativefft(x, y, x, y, x.Length, direction, ref s);
            temporaryStorage = s;
        }
Exemplo n.º 5
0
        private static void chirpnativefft(
            double[] resultreal,
            double[] resultimag,
            double[] inputreal,
            double[] inputimag,
            int arrsize,
            FourierDirection direction,
            ref ChirpNativeFFTStorage s)
        {
            int phasesign = direction == FourierDirection.Forward ? 1 : -1;
            int arrsize2  = arrsize + arrsize;

            if (arrsize <= 2)
            {
                throw new ArgumentException("This algorithm works for array sizes > 2 only.");
            }

            int msize = GetNecessaryTransformationSize(arrsize);

            if (s == null || s.Length != msize)
            {
                s = new ChirpNativeFFTStorage(msize);
            }

            double[] xjfj_real     = s.xjfj_real;
            double[] xjfj_imag     = s.xjfj_imag;
            double[] fserp_real    = s.fserp_real;
            double[] fserp_imag    = s.fserp_imag;
            double[] resarray_real = s.resarray_real;
            double[] resarray_imag = s.resarray_imag;

            // bilde xj*fj
            double prefactor = phasesign * Math.PI / arrsize;
            int    np        = 0;

            for (int i = 0; i < arrsize; i++)
            {
                double phi = prefactor * np; // np should be equal to (i*i)%arrsize2
                double vre = Math.Cos(phi);
                double vim = Math.Sin(phi);
                xjfj_real[i] = inputreal[i] * vre - inputimag[i] * vim;
                xjfj_imag[i] = inputreal[i] * vim + inputimag[i] * vre;

                np += i + i + 1; // np == (k*k)%n2
                if (np >= arrsize2)
                {
                    np -= arrsize2;
                }
            }

            // fill positive and negative part of fserp
            fserp_real[0] = 1; fserp_imag[0] = 0;
            prefactor     = -phasesign * Math.PI / arrsize;
            np            = 1; // since we start the loop with 1
            for (int i = 1; i < arrsize; i++)
            {
                double phi = prefactor * np; // np should be equal to (i*i)%arrsize2
                fserp_real[i] = fserp_real[msize - i] = Math.Cos(phi);
                fserp_imag[i] = fserp_imag[msize - i] = Math.Sin(phi);

                np += i + i + 1; // np == (k*k)%n2
                if (np >= arrsize2)
                {
                    np -= arrsize2;
                }
            }

            // convolute xjfj with fserp
            //NativeCyclicConvolution(resarray,xjfj,fserp,msize);
            fhtconvolution(resarray_real, resarray_imag, xjfj_real, xjfj_imag, fserp_real, fserp_imag, msize);

            // multipliziere mit fserpschlange
            prefactor = phasesign * Math.PI / arrsize;
            np        = 0;
            for (int i = 0; i < arrsize; i++)
            {
                double phi = prefactor * np; // np should be equal to (i*i)%arrsize2
                double vre = Math.Cos(phi);
                double vim = Math.Sin(phi);
                resultreal[i] = resarray_real[i] * vre - resarray_imag[i] * vim;
                resultimag[i] = resarray_real[i] * vim + resarray_imag[i] * vre;

                np += i + i + 1; // np == (i*i)%n2
                if (np >= arrsize2)
                {
                    np -= arrsize2;
                }
            }
        }
Exemplo n.º 6
0
		private static void chirpnativefft(
			double[] resultreal,
			double[] resultimag,
			double[] inputreal,
			double[] inputimag,
			int arrsize,
			FourierDirection direction,
			ref ChirpNativeFFTStorage s)
		{
			if (arrsize <= 2)
				throw new ArgumentException("This algorithm works for array sizes > 2 only.");

			int msize = GetNecessaryTransformationSize(arrsize);

			if (s == null || arrsize != s._arrSize || direction != s._direction)
			{
				s = new ChirpNativeFFTStorage(msize, arrsize, direction);
			}
			else // if the temp storage is not fresh, we have to clear the arrays first
			{
				Array.Clear(s._xjfj_real, 0, msize);
				Array.Clear(s._xjfj_imag, 0, msize);
			}

			// make the arrays local variables
			double[] xjfj_real = s._xjfj_real;
			double[] xjfj_imag = s._xjfj_imag;
			double[] fserp_real = s._fserp_real;
			double[] fserp_imag = s._fserp_imag;
			double[] resarray_real = s._resarray_real;
			double[] resarray_imag = s._resarray_imag;

			var chirpfactor_real = s._chirpfactors_real;
			var chirpfactor_imag = s._chirpfactors_imag;

			// multiply the input array with the chirpfactors
			for (int i = 0; i < arrsize; ++i)
			{
				xjfj_real[i] = inputreal[i] * chirpfactor_real[i] - inputimag[i] * chirpfactor_imag[i];
				xjfj_imag[i] = inputreal[i] * chirpfactor_imag[i] + inputimag[i] * chirpfactor_real[i];
			}

			// convolute xjfj with precomputed fourier-transformation of fserp
			fhtconvolutionWithFouriertransformed2ndArgument(resarray_real, resarray_imag, xjfj_real, xjfj_imag, fserp_real, fserp_imag, msize);

			// multiply the result  with the chirpfactors
			for (int i = 0; i < arrsize; ++i)
			{
				resultreal[i] = resarray_real[i] * chirpfactor_real[i] - resarray_imag[i] * chirpfactor_imag[i];
				resultimag[i] = resarray_real[i] * chirpfactor_imag[i] + resarray_imag[i] * chirpfactor_real[i];
			}
		}
Exemplo n.º 7
0
    private static void chirpnativefft(
      double[] resultreal, 
      double[] resultimag,
      double[] inputreal,
      double[] inputimag,
      int arrsize,
      FourierDirection direction,
      ref ChirpNativeFFTStorage s)
    {
      int phasesign = direction==FourierDirection.Forward ? 1 : -1;
      int arrsize2 = arrsize+arrsize;
     
      if(arrsize<=2)
        throw new ArgumentException("This algorithm works for array sizes > 2 only.");

      int msize = GetNecessaryTransformationSize(arrsize);
     
      if(s==null || s.Length!=msize)
      {
        s = new ChirpNativeFFTStorage(msize);
      }

      double[] xjfj_real  = s.xjfj_real;
      double[] xjfj_imag  = s.xjfj_imag;
      double[] fserp_real = s.fserp_real;
      double[] fserp_imag = s.fserp_imag;
      double[] resarray_real = s.resarray_real;
      double[] resarray_imag = s.resarray_imag;

      // bilde xj*fj
      double prefactor = phasesign * Math.PI / arrsize;
      int np = 0;
      for(int i=0;i<arrsize;i++)
      {
        double phi = prefactor*np; // np should be equal to (i*i)%arrsize2
        double vre = Math.Cos(phi);
        double vim = Math.Sin(phi);
        xjfj_real[i] = inputreal[i] * vre - inputimag[i] * vim;
        xjfj_imag[i] = inputreal[i] * vim + inputimag[i] * vre;

        np += i+i+1;  // np == (k*k)%n2
        if ( np >= arrsize2 ) 
          np -= arrsize2;

      }

      // fill positive and negative part of fserp
      fserp_real[0]=1; fserp_imag[0]=0;
      prefactor = -phasesign * Math.PI / arrsize;
      np = 1; // since we start the loop with 1
      for(int i=1;i<arrsize;i++)
      {
        double phi = prefactor * np; // np should be equal to (i*i)%arrsize2
        fserp_real[i] = fserp_real[msize-i] = Math.Cos(phi);
        fserp_imag[i] = fserp_imag[msize-i] = Math.Sin(phi);
        
        np += i+i+1;  // np == (k*k)%n2
        if ( np >= arrsize2 ) 
          np -= arrsize2;
      }

      // convolute xjfj with fserp
      //NativeCyclicConvolution(resarray,xjfj,fserp,msize);
      fhtconvolution(resarray_real,resarray_imag,xjfj_real,xjfj_imag,fserp_real,fserp_imag,msize);

      // multipliziere mit fserpschlange
      prefactor = phasesign * Math.PI / arrsize;
      np = 0;
      for(int i=0;i<arrsize;i++)
      {
        double phi = prefactor * np; // np should be equal to (i*i)%arrsize2
        double vre = Math.Cos(phi);
        double vim = Math.Sin(phi);
        resultreal[i] = resarray_real[i]*vre - resarray_imag[i]*vim;
        resultimag[i] = resarray_real[i]*vim + resarray_imag[i]*vre;
            
        np += i+i+1;  // np == (i*i)%n2
        if ( np >= arrsize2 ) 
          np -= arrsize2;
      }
    }