Пример #1
0
void Correlation::output()
{
    // calculate the FFTs of the two functions
	if( gsl_fft_real_radix2_transform( d_x, 1, d_n ) == 0 &&
        gsl_fft_real_radix2_transform( d_y, 1, d_n ) == 0)
	{
		for(int i=0; i<d_n/2; i++ ){// multiply the FFT by its complex conjugate
			if( i==0 || i==(d_n/2)-1 )
				d_x[i] *= d_x[i];
			else{
				int ni = d_n-i;
				double dReal = d_x[i] * d_y[i] + d_x[ni] * d_y[ni];
				double dImag = d_x[i] * d_y[ni] - d_x[ni] * d_y[i];
				d_x[i] = dReal;
				d_x[ni] = dImag;
			}
		}
	} else {
		QMessageBox::warning((ApplicationWindow *)parent(), tr("QtiPlot") + " - " + tr("Error"),
                             tr("Error in GSL forward FFT operation!"));
		return;
	}

	gsl_fft_halfcomplex_radix2_inverse(d_x, 1, d_n );	//inverse FFT

	addResultCurve();
    d_result_table = d_table;
}
Пример #2
0
/* calculates the inverse Fourier transform of signal data (half-complex),
 * and stores it into fft_results */
int inverse_fft (size_t N, double *data, double *fft_results) {
  size_t i;
  int retcode;
  double *fft_data = (double *) calloc (N, sizeof (double));

  /* initialize the data for fft */
  for (i=0; i<N; i++) fft_data [i] = data [i];

  /* use the corresponding routine if N is power of 2 */
  if (is_power_of_n (N,2)) {
    /* perform the fft */
    retcode = gsl_fft_halfcomplex_radix2_inverse (fft_results, 1, N);
    gsl_fft_halfcomplex_radix2_unpack (fft_data, fft_results, 1, N);
  }
  else {
    /* alloc memory for real and half-complex wavetables, and workspace */
    gsl_fft_halfcomplex_wavetable *hc_wavetable = gsl_fft_halfcomplex_wavetable_alloc (N);
    gsl_fft_real_workspace *ws = gsl_fft_real_workspace_alloc (N);

    /* perform the fft */
    retcode = gsl_fft_halfcomplex_inverse (fft_data, 1, N, hc_wavetable, ws);
    gsl_fft_halfcomplex_unpack (fft_data, fft_results, 1, N);

    /* free memory */
    gsl_fft_halfcomplex_wavetable_free (hc_wavetable);
    gsl_fft_real_workspace_free (ws);

  }
  free (fft_data);
  return retcode;
}
Пример #3
0
void TimeSeriesMotion::ifft(const QVector<std::complex<double> >& in, QVector<double>& out ) const
{
/*
#ifdef USE_IFFTW
    // Copy the input QVector into a double array
    fftw_complex* inArray = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in.size());

    for( int i = 0; i < in.size(); i++ ) {
        inArray[i][0] = in.at(i).real();
        inArray[i][1] = in.at(i).imag();
    }    

    // Allocate the space for the output
    int n = 2 * (in.size() - 1);
    double* outArray = (double*)fftw_malloc(sizeof(double) * n);

    // Create the plan and execute the FFT
    fftw_plan p = fftw_plan_dft_c2r_1d(n, inArray, outArray, FFTW_ESTIMATE);
    fftw_execute(p);

    // Copy the data to the output QVector and normalize by QVector length
    out.resize(n);
    for (int i = 0; i < out.size(); i++) {
        out[i] = outArray[i] / out.size();
    }

    // Free the memory
    fftw_destroy_plan(p);
    fftw_free(inArray);
    fftw_free(outArray);
*/
    const int n = 2 * (in.size() - 1);
    double *d = new double[n];

    d[0] = in.first().real();
    for (int i = 1; i < in.size(); ++i) {
        d[i] = in.at(i).real();
        d[n - i] = in.at(i).imag();
    }
    d[n / 2] = in.last().real();

#if USE_FFTW
    fftw_plan p = fftw_plan_r2r_1d(n, d, d, FFTW_HC2R, FFTW_ESTIMATE);
    fftw_execute(p);

    for (int i = 0; i < n; ++i) {
        // Scale by n
        d[i] /= n;
    }
#else
    gsl_fft_halfcomplex_radix2_inverse(d, 1, n);
#endif

    // Copy results to output
    out.resize(n);
    memcpy(out.data(), d, n * sizeof(double));

    delete [] d;
}
Пример #4
0
void Convolution::convlv(double *sig, int n, double *dres, int m, int sign)
{
	double *res = new double[n];
	memset(res,0,n*sizeof(double));
	int i, m2 = m/2;
	for (i=0;i<m2;i++)
	{//store the response in wrap around order, see Numerical Recipes doc
		res[i] = dres[m2+i];
		res[n-m2+i] = dres[i];
	}

	if(m2%2==1)
		res[m2]=dres[m-1];

	// calculate ffts
	gsl_fft_real_radix2_transform(res,1,n);
	gsl_fft_real_radix2_transform(sig,1,n);

	double re, im, size;
	for (i=0;i<n/2;i++)
	{// multiply/divide both ffts
		if(i==0 || i==n/2-1)
		{
			if(sign == 1)
				sig[i] = res[i]*sig[i];
			else
				sig[i] = sig[i]/res[i];
		}
		else
		{
			int ni = n-i;
			if(sign == 1)
			{
				re = res[i]*sig[i]-res[ni]*sig[ni];
				im = res[i]*sig[ni]+res[ni]*sig[i];
			}
			else
			{
				size = res[i]*res[i]+res[ni]*res[ni];
				re = res[i]*sig[i]+res[ni]*sig[ni];
				im = res[i]*sig[ni]-res[ni]*sig[i];
				re /= size;
				im /= size;
			}

			sig[i] = re;
			sig[ni] = im;
		}
	}
	delete[] res;
	gsl_fft_halfcomplex_radix2_inverse(sig,1,n);// inverse fft
}
bool CrossCorrelate::algorithm() {

  KstVectorPtr array_one    = inputVector(ARRAY_ONE);
  KstVectorPtr array_two    = inputVector(ARRAY_TWO);
  KstVectorPtr step_value   = outputVector(STEP_VALUE);
  KstVectorPtr correlated   = outputVector(CORRELATED);

  if (array_one->length() <= 0               ||
      array_two->length() <= 0               ||
      array_one->length() != array_two->length()) {
      return false;
  }

  double* pdArrayOne;
  double* pdArrayTwo;
  double* pdResult[2];
  double  dReal;
  double  dImag;

  int iLength;
  int iLengthNew;

  bool iReturn = false;

  //
  // zero-pad the array...
  //
  iLength  = array_one->length();
  iLength *= 2;

  step_value->resize(array_one->length(), false);
  correlated->resize(array_two->length(), false);

  //
  // round iLength up to the nearest power of two...
  //
  iLengthNew = 64;
  while( iLengthNew < iLength && iLengthNew > 0) {
    iLengthNew *= 2;
  }
  iLength = iLengthNew;

  if (iLength <= 0)
    return false;

  pdArrayOne = new double[iLength];
  pdArrayTwo = new double[iLength];
  if (pdArrayOne != NULL && pdArrayTwo != NULL) {
    //
    // zero-pad the two arrays...
    //
    memset( pdArrayOne, 0, iLength * sizeof( double ) );
    memcpy( pdArrayOne, array_one->value(), array_one->length() * sizeof( double ) );

    memset( pdArrayTwo, 0, iLength * sizeof( double ) );
    memcpy( pdArrayTwo, array_two->value(), array_two->length() * sizeof( double ) );

    //
    // calculate the FFTs of the two functions...
    //
    if (gsl_fft_real_radix2_transform( pdArrayOne, 1, iLength ) == 0) {
      if (gsl_fft_real_radix2_transform( pdArrayTwo, 1, iLength ) == 0) {
        //
        // multiply one FFT by the complex conjugate of the other...
        //
        for (int i=0; i<iLength/2; i++) {
          if (i==0 || i==(iLength/2)-1) {
            pdArrayOne[i] = pdArrayOne[i] * pdArrayTwo[i];
          } else {
            dReal = pdArrayOne[i] * pdArrayTwo[i] + pdArrayOne[iLength-i] * pdArrayTwo[iLength-i];
            dImag = pdArrayOne[i] * pdArrayTwo[iLength-i] - pdArrayOne[iLength-i] * pdArrayTwo[i];

            pdArrayOne[i] = dReal;
            pdArrayOne[iLength-i] = dImag;
          }
        }

        //
        // do the inverse FFT...
        //
        if (gsl_fft_halfcomplex_radix2_inverse( pdArrayOne, 1, iLength ) == 0) {
          if (step_value->length() != array_one->length()) {
            pdResult[0] = (double*)realloc( step_value->value(), array_one->length() * sizeof( double ) );
          } else {
            pdResult[0] = step_value->value();
          }

          if (correlated->length() != array_two->length()) {
            pdResult[1] = (double*)realloc( correlated->value(), array_two->length() * sizeof( double ) );
          } else {
            pdResult[1] = correlated->value();
          }

          if (pdResult[0] != NULL && pdResult[1] != NULL) {
            for (int i = 0; i < array_one->length(); ++i) {
              step_value->value()[i] = pdResult[0][i];
            }
            for (int i = 0; i < array_two->length(); ++i) {
              correlated->value()[i] = pdResult[1][i];
            }

            for (int i = 0; i < array_one->length(); i++) {
                step_value->value()[i] = (double)( i - ( array_one->length() / 2 ) );
            }

            memcpy( &(correlated->value()[array_one->length() / 2]),
                    &(pdArrayOne[0]),
                    ( ( array_one->length() + 1 ) / 2 ) * sizeof( double ) );

            memcpy( &(correlated->value()[0]),
                    &(pdArrayOne[iLength - (array_one->length() / 2)]),
                    ( array_one->length() / 2 ) * sizeof( double ) );

            iReturn = true;
          }
        }
      }
    }
  }
  delete[] pdArrayOne;
  delete[] pdArrayTwo;

  return iReturn;
}
Пример #6
0
bool AutoCorrelate::algorithm() {

  KstVectorPtr array            = inputVector(ARRAY);
  KstVectorPtr step_value       = outputVector(STEP_VALUE);
  KstVectorPtr auto_correlated  = outputVector(AUTO_CORRELATED);

  if (array->length() <= 0) {
    return false;
  }

  double* pdArrayOne;
  double* pdResult;
  double* pdCorrelate;
  double  dReal;
  double  dImag;
  double  sigmaSquared = 0.0;

  int iLength;
  int iLengthNew;

  bool iReturn = false;

  //
  // zero-pad the array...
  //
  iLength  = array->length();
  iLength *= 2;

  step_value->resize(array->length(), false);
  auto_correlated->resize(array->length(), false);

  //
  // round iLength up to the nearest power of two...
  //
  iLengthNew = 64;
  while( iLengthNew < iLength && iLengthNew > 0) {
    iLengthNew *= 2;
  }
  iLength = iLengthNew;

  if (iLength <= 0) {
    return false;
  }

  pdArrayOne = new double[iLength];
  if (pdArrayOne != NULL) {
    //
    // zero-pad the two arrays...
    //
    memset( pdArrayOne, 0, iLength * sizeof( double ) );
    memcpy( pdArrayOne, array->value(), array->length() * sizeof( double ) );

    //
    // calculate the FFTs of the two functions...
    //
    if (gsl_fft_real_radix2_transform( pdArrayOne, 1, iLength ) == 0) {
      //
      // multiply the FFT by its complex conjugate...
      //
      for (int i=0; i<iLength/2; i++) {
        if (i==0 || i==(iLength/2)-1) {
          pdArrayOne[i] *= pdArrayOne[i];
        } else {
          dReal = pdArrayOne[i] * pdArrayOne[i] + pdArrayOne[iLength-i] * pdArrayOne[iLength-i];
          dImag = pdArrayOne[i] * pdArrayOne[iLength-i] - pdArrayOne[iLength-i] * pdArrayOne[i];

          pdArrayOne[i] = dReal;
          pdArrayOne[iLength-i] = dImag;
        }
      }

      //
      // do the inverse FFT...
      //
      if (gsl_fft_halfcomplex_radix2_inverse( pdArrayOne, 1, iLength ) == 0) {
        if (step_value->length() != array->length()) {
          pdResult = (double*)realloc( step_value->value(), array->length() * sizeof( double ) );
        } else {
          pdResult = step_value->value();
        }

        if (auto_correlated->length() != array->length()) {
          pdCorrelate = (double*)realloc( auto_correlated->value(), array->length() * sizeof( double ) );
        } else {
          pdCorrelate = auto_correlated->value();
        }

        if (pdResult != NULL && pdCorrelate != NULL) {
          sigmaSquared = pdArrayOne[0];

          memcpy( &(auto_correlated->value()[array->length() / 2]),
                  &(pdArrayOne[0]),
                  ( ( array->length() + 1 ) / 2 ) * sizeof( double ) );

          memcpy( &(auto_correlated->value()[0]),
                  &(pdArrayOne[iLength - (array->length() / 2)]),
                  ( array->length() / 2 ) * sizeof( double ) );

          for (int i = 0; i < array->length(); i++) {
            auto_correlated->value()[i] /= sigmaSquared;
            step_value->value()[i] = (double)( i - ( array->length() / 2 ) );
          }

          iReturn = true;
        }
      }
    }
  }
  delete[] pdArrayOne;

  return iReturn;
}
Пример #7
0
int crosscorrelate(const double *const inArrays[], const int inArrayLens[],
		const double inScalars[],
		double *outArrays[], int outArrayLens[],
		double outScalars[])
{
  double* pdArrayOne;
  double* pdArrayTwo;
  double* pdResult[2];
  double  dReal;
  double  dImag;
  int i = 0;
  int iLength;
  int iLengthNew;
  int iReturn = -1;

  if( inArrayLens[0] > 0               && 
      inArrayLens[1] > 0               &&
      inArrayLens[0] == inArrayLens[1] )
  {
    //
    // zero-pad the array...
    //
    iLength  = inArrayLens[0];
    iLength *= 2;
    
    //
    // round iLength up to the nearest power of two...
    //
    iLengthNew = 64;
    while( iLengthNew < iLength && iLengthNew > 0 )
    {
      iLengthNew *= 2;
    }
    iLength = iLengthNew;

    if( iLength > 0 )
    {
      pdArrayOne = new double[iLength];
      pdArrayTwo = new double[iLength];
      if( pdArrayOne != NULL && pdArrayTwo != NULL )
      {
        //
        // zero-pad the two arrays...
        //
        memset( pdArrayOne, 0, iLength * sizeof( double ) );
        memcpy( pdArrayOne, inArrays[0], inArrayLens[0] * sizeof( double ) );

        memset( pdArrayTwo, 0, iLength * sizeof( double ) );
        memcpy( pdArrayTwo, inArrays[1], inArrayLens[1] * sizeof( double ) );

        //
        // calculate the FFTs of the two functions...
        //
        if( gsl_fft_real_radix2_transform( pdArrayOne, 1, iLength ) == 0 )
        {
          if( gsl_fft_real_radix2_transform( pdArrayTwo, 1, iLength ) == 0 )
          {
            //
            // multiply one FFT by the complex conjugate of the other...
            //
            for( i=0; i<iLength/2; i++ )
            {
              if( i==0 || i==(iLength/2)-1 )
              {
                pdArrayOne[i] = pdArrayOne[i] * pdArrayTwo[i];
              }
              else
              {              
                dReal = pdArrayOne[i] * pdArrayTwo[i] + pdArrayOne[iLength-i] * pdArrayTwo[iLength-i];
                dImag = pdArrayOne[i] * pdArrayTwo[iLength-i] - pdArrayOne[iLength-i] * pdArrayTwo[i];

                pdArrayOne[i] = dReal;
                pdArrayOne[iLength-i] = dImag;
              }
            }

            //
            // do the inverse FFT...
            //
            if( gsl_fft_halfcomplex_radix2_inverse( pdArrayOne, 1, iLength ) == 0 )
            {              
              if( outArrayLens[0] != inArrayLens[0] )
              {
                pdResult[0] = (double*)realloc( outArrays[0], inArrayLens[0] * sizeof( double ) );
              }
              else
              {
                pdResult[0] = outArrays[0];
              }

              if( outArrayLens[1] != inArrayLens[1] )
              {
                pdResult[1] = (double*)realloc( outArrays[1], inArrayLens[1] * sizeof( double ) );
              }
              else
              {
                pdResult[1] = outArrays[1];
              }

              if( pdResult[0] != NULL && pdResult[1] != NULL )
              {
                outArrays[0] = pdResult[0];
                outArrayLens[0] = inArrayLens[0];

                outArrays[1] = pdResult[1];
                outArrayLens[1] = inArrayLens[1];
                
                for( i=0; i<inArrayLens[0]; i++ )
                {
                    outArrays[0][i] = (double)( i - ( inArrayLens[0] / 2 ) );
                }

                memcpy( &(outArrays[1][inArrayLens[0] / 2]),
                        &(pdArrayOne[0]),
                        ( ( inArrayLens[0] + 1 ) / 2 ) * sizeof( double ) );

                memcpy( &(outArrays[1][0]),
                        &(pdArrayOne[iLength - (inArrayLens[0] / 2)]),
                        ( inArrayLens[0] / 2 ) * sizeof( double ) );

                iReturn = 0;
              }
            }
          }
        }
        
        delete[] pdArrayOne;
        delete[] pdArrayTwo;
      }
    }
  }
  
  return iReturn;
}
Пример #8
0
	inline int inverse( DATA& data, size_t const stride = 1 ){
	  return gsl_fft_halfcomplex_radix2_inverse( data.data(), stride, data.size() / stride ); }
Пример #9
0
	/**
	 * C++ version of gsl_fft_halfcomplex_radix2_inverse().
	 * @param data An array of halfcomplex values as an array of double values.
	 * @param n The size of the array.
	 * @return Error code on failure.
	 */
	inline int inverse( double data[], size_t const n ){
	  return gsl_fft_halfcomplex_radix2_inverse( data, 1, n ); }