Exemple #1
0
int main ( int argc, char **argv ) {
    int methodnr;

    FLOAT_TYPE alphamin,alphamax,alphastep;
    FLOAT_TYPE alpha;
    FLOAT_TYPE wtime;

    FILE* fout;
    
    system_t *system;
    method_t method;
    parameters_t parameters, parameters_ewald;
    data_t *data, *data_ewald;
    forces_t *forces, *forces_ewald;
    char *pos_file = NULL, *force_file = NULL, *out_file = NULL, *ref_out = NULL, *sys_out = NULL, *rdf_file = NULL, *vtf_file = NULL, *cdf_file = NULL;
    error_t error;
    FLOAT_TYPE length, prec;
    int npart;
    FLOAT_TYPE charge;
    int form_factor;
    FLOAT_TYPE rdf_min, rdf_max;
    int rdf_bins;

    FLOAT_TYPE error_k=0.0, ewald_error_k_est, estimate=0.0, error_k_est;
    int i,j, calc_k_error, calc_est;

    #ifdef _OPENMP
    int nthreads;
    #endif

    cmd_parameters_t params = { NULL, 0, NULL, 0 };

    add_param( "rcut", ARG_TYPE_FLOAT, ARG_REQUIRED, &(parameters.rcut), &params );
    add_param( "alphamin", ARG_TYPE_FLOAT, ARG_OPTIONAL, &alphamin, &params );
    add_param( "alphamax", ARG_TYPE_FLOAT, ARG_OPTIONAL, &alphamax, &params );
    add_param( "alphastep", ARG_TYPE_FLOAT, ARG_OPTIONAL, &alphastep, &params );
    add_param( "alpha", ARG_TYPE_FLOAT, ARG_OPTIONAL, &alpha, &params );
    add_param( "positions", ARG_TYPE_STRING, ARG_OPTIONAL, &pos_file, &params );
    add_param( "error_k", ARG_TYPE_NONE, ARG_OPTIONAL, NULL, &params );
    add_param( "forces", ARG_TYPE_STRING, ARG_OPTIONAL, &force_file, &params );
    add_param( "mesh", ARG_TYPE_INT, ARG_REQUIRED, &(parameters.mesh), &params );
    add_param( "cao", ARG_TYPE_INT, ARG_REQUIRED, &(parameters.cao), &params );
    add_param( "method", ARG_TYPE_INT, ARG_REQUIRED, &methodnr, &params );
    add_param( "mc", ARG_TYPE_INT, ARG_OPTIONAL, &P3M_BRILLOUIN, &params );
    add_param( "mc_est", ARG_TYPE_INT, ARG_OPTIONAL, &P3M_BRILLOUIN_TUNING, &params );
    add_param( "no_estimate", ARG_TYPE_NONE, ARG_OPTIONAL, NULL, &params );
    add_param( "outfile", ARG_TYPE_STRING, ARG_OPTIONAL, &out_file, &params );
    add_param( "particles", ARG_TYPE_INT, ARG_OPTIONAL, &npart, &params );
    add_param( "box", ARG_TYPE_FLOAT, ARG_OPTIONAL, &length, &params );
    add_param( "tune", ARG_TYPE_NONE, ARG_OPTIONAL, NULL, &params );
    add_param( "prec", ARG_TYPE_FLOAT, ARG_OPTIONAL, &prec, &params );
    add_param( "reference_out", ARG_TYPE_STRING, ARG_OPTIONAL, &ref_out, &params );
    add_param( "system_out", ARG_TYPE_STRING, ARG_OPTIONAL, &sys_out, &params );
    add_param( "verlet_lists", ARG_TYPE_NONE, ARG_OPTIONAL, NULL, &params );
    add_param( "charge", ARG_TYPE_FLOAT, ARG_OPTIONAL, &charge, &params );
    add_param( "system_type", ARG_TYPE_INT, ARG_OPTIONAL, &form_factor, &params );
    add_param( "rdf", ARG_TYPE_STRING, ARG_OPTIONAL, &rdf_file, &params );
    add_param( "rdf_bins", ARG_TYPE_INT, ARG_OPTIONAL, &rdf_bins, &params );
    add_param( "rdf_rmin", ARG_TYPE_FLOAT, ARG_OPTIONAL, &rdf_min, &params );
    add_param( "rdf_rmax", ARG_TYPE_FLOAT, ARG_OPTIONAL, &rdf_max, &params );
    add_param( "cdf", ARG_TYPE_STRING, ARG_OPTIONAL, &cdf_file, &params );
    add_param( "no_calculation", ARG_TYPE_NONE, ARG_OPTIONAL, NULL, &params );
    add_param( "vtf_file", ARG_TYPE_STRING, ARG_OPTIONAL, &vtf_file, &params );
    add_param( "rdf_species", ARG_TYPE_NONE, ARG_OPTIONAL, NULL, &params );
    add_param( "no_reference_force", ARG_TYPE_NONE, ARG_OPTIONAL, NULL, &params);
    #ifdef _OPENMP
    add_param( "threads", ARG_TYPE_INT, ARG_OPTIONAL, &nthreads, &params );
    #endif

    parse_parameters( argc - 1, argv + 1, params );

    calc_k_error = param_isset( "error_k", params );
    calc_est = param_isset( "estimate", params );

    parameters.cao3 = parameters.cao*parameters.cao*parameters.cao;
    parameters.ip = parameters.cao - 1;
    parameters.alpha = 0.0;
    parameters_ewald = parameters;

#ifdef _OPENMP
    if(param_isset("threads", params)) {
      omp_set_num_threads(nthreads);
    }
    printf("OpenMP: Using up to %d threads.\n", omp_get_max_threads( ));
#endif

    if(!(param_isset("alphamin", params) && param_isset("alphamax", params) && param_isset("alphastep", params)) && !param_isset("alpha", params)) {
      puts("Need to provide either alpha-range (alphamin, alphamax, alphastep) or alpha.");
      exit(1);
    }

    if( !(param_isset("positions", params) == 1) &&
	!((param_isset("box", params) == 1) && (param_isset("particles", params))) ) {
      puts("Need to provide either 'positions' or 'box' and 'particles'.");
      exit(1);
    }

    if( param_isset("positions", params) == 1) {
    // Inits the system and reads particle data and parameters from file.
      puts("Reading file");
      system = Read_system ( &parameters, pos_file );
      puts("Done.");
    } else {
      puts("Generating system.");
      if( !(param_isset("charge", params) == 1)) {
	charge=1.0;
      }
      if(param_isset("system_type", params)) {
	printf("Using system type %d\n", form_factor);
	system = generate_system( form_factor, npart, length, charge);
      } else {
	system = generate_system( FORM_FACTOR_RANDOM, npart, length, charge);
      }
      puts("Done.");
    }

    if( param_isset("vtf_file", params) == 1) 
      write_vtf( vtf_file, system );

    if( param_isset("rdf", params) == 1) {
      puts("Calculating RDF");
      if( param_isset("rdf_bins", params) == 0)
	rdf_bins = 100;
      if( param_isset("rdf_rmin", params) == 0)
	rdf_min = 0.0;
      if( param_isset("rdf_rmax", params) == 0)
	rdf_max = system->length/2;
      printf("Using %d bins, %lf <= r <= %lf\n", rdf_bins, rdf_min, rdf_max);
      int bins = rdf_bins;
      FLOAT_TYPE *rdf = radial_distribution(rdf_min, rdf_max, rdf_bins, system);
      FLOAT_TYPE *c;
      /* FLOAT_TYPE *rdf_sym = Init_array( 2*bins-1, 2*sizeof(FLOAT_TYPE)); */
      /* c = low_pass_forward( bins, rdf, 0.3); */
      /* c = low_pass_backward(bins, c, 0.3); */
      /* rdf = c; */
      /* for(int i = 0; i < 2*bins; i++) { */
      /* 	rdf_sym[i] = c[i]; */
      /* } */
      /* for(int i = bins; i < 2*bins-1; i++) { */
      /* 	rdf_sym[2*i] =  c[2*bins - 2] + (i-bins)*(c[2] - c[0]); */
      /* 	rdf_sym[2*i+1] = c[4*bins - 2*i - 1]; */
      /* } */


      FILE *rdf_out = fopen(rdf_file, "w");
      /* FILE *c_out = fopen("c_fft.dat", "w"); */

      /* rshif_array(2*(2*bins-1), c, 2*bins); */

      for(int i = 0; i<bins; i++)
	fprintf(rdf_out, "%e %e\n", FLOAT_CAST rdf[2*i], FLOAT_CAST rdf[2*i+1]);

      /* for(int i = 0; i<2*bins-1; i++) */
      /* 	/\* fprintf(c_out, "%e %e\n", FLOAT_CAST rdf_sym[2*i], FLOAT_CAST rdf_sym[2*i+1] );  *\/ */
      /* 	fprintf(c_out, "%d %e %e\n", i, FLOAT_CAST c[2*i], FLOAT_CAST c[2*i+1] ); */

      /* fclose(c_out); */
      fclose(rdf_out);
      fftw_free(rdf);
      /* fftw_free(c); */
      puts("Done.");
    }

    if( param_isset("rdf_species", params) == 1) {
      radial_distribution_species(0.0, 3.0, 200, system);
    }

    forces = Init_forces(system->nparticles);
    forces_ewald = Init_forces(system->nparticles);

    if(param_isset("reference_out", params)) 
      {
	printf("Minimal distance: %.*f\n", DIGITS, FLOAT_CAST Min_distance( system ));
	puts("Calculating reference forces.");
	printf("Reference precision %e\n.", FLOAT_CAST Calculate_reference_forces( system, &parameters ));
	puts("Done.");
	printf("Writing reference forces to '%s'\n", ref_out);
	Write_exact_forces(system, ref_out);
	puts("Done.");
      }

    if(param_isset("system_out", params)) 
      {
	printf("Writing system to '%s'\n", sys_out);
	Write_system(system, sys_out);
	puts("Done.");
      }

    if(param_isset("no_calculation", params) == 1)
      return 0;

    if(param_isset("forces", params) == 1) {
      printf("Reading reference forces from '%s'.\n", force_file);
      Read_exact_forces( system, force_file );
      puts("Done.");
    } else {
      if(param_isset("no_reference_force", params) !=1) {
	puts("Calculating reference forces.");
	printf("Reference precision %e\n.", FLOAT_CAST Calculate_reference_forces( system, &parameters ));
	puts("Done.");
      } else {
	puts("Skipping reference force calculation.");
      }
    }

    if ( methodnr == method_ewald.method_id )
        method = method_ewald;
#ifdef P3M_IK_H
    else if ( methodnr == method_p3m_ik.method_id )
        method = method_p3m_ik;
#endif
#ifdef P3M_IK_I_H
    else if ( methodnr == method_p3m_ik_i.method_id )
        method = method_p3m_ik_i;
#endif
#ifdef P3M_AD_H
    else if ( methodnr == method_p3m_ad.method_id )
        method = method_p3m_ad;
#endif
#ifdef P3M_AD_I_H
    else if ( methodnr == method_p3m_ad_i.method_id ) {
        method = method_p3m_ad_i;
    }
#endif
    else {
        fprintf ( stderr, "Method %d not know.", methodnr );
        exit ( 126 );
    }

    if ( ( method.Init == NULL ) || ( method.Influence_function == NULL ) || ( method.Kspace_force == NULL ) ) {
        fprintf ( stderr,"Internal error: Method '%s' (%d) is not properly defined. Aborting.\n", method.method_name, method.method_id );
        exit ( -1 );
    }

    fprintf ( stderr, "Using %s.\n", method.method_name );

    if(param_isset("outfile", params) == 1) {
      fout = fopen ( out_file, "w" );      
    } else {
      fout = fopen ( "out.dat","w" );
    }

    printf ( "Init" );
    fflush(stdout);
    data = method.Init ( system, &parameters );
    printf ( ".\n" );

    printf ( "Init Ewald" );
    data_ewald = method_ewald.Init ( system, &parameters_ewald );
    printf ( ".\n" );

    /* printf ( "Init neighborlist" ); */
    /* Init_neighborlist ( system, &parameters, data ); */
    /* printf ( ".\n" ); */

    FLOAT_TYPE gen_err_dip, gen_err;

    printf ( "# %8s\t%8s\t%8s\t%8s\t%8s\n", "alpha", "DeltaF", "Estimate", "R-Error-Est", "K-Error-Est Generic-K-Space-err" );
    for ( parameters.alpha=alphamin; parameters.alpha<=alphamax; parameters.alpha+=alphastep ) {
      parameters_ewald.alpha = parameters.alpha;

      method.Influence_function ( system, &parameters, data );  /* Hockney/Eastwood */

      wtime = MPI_Wtime();

      Calculate_forces ( &method, system, &parameters, data, forces ); /* Hockney/Eastwood */

      wtime = MPI_Wtime() - wtime;

      error_k =0.0;
      if(calc_k_error == 1) {
	puts("kerror");
	for(i=0;i<3;i++) {
	  memset ( forces_ewald->f_k->fields[i], 0, system->nparticles*sizeof ( FLOAT_TYPE ) );
	}
	method_ewald.Influence_function ( system, &parameters_ewald, data_ewald );
	method_ewald.Kspace_force( system, &parameters_ewald, data_ewald, forces_ewald );

	error_k =0.0;
	for (i=0; i<system->nparticles; i++) {
	  for (j=0;j<3;j++) {            
	    /* printf("f_k_p3m [%lf, %lf, %lf] f_k_ewald [%lf, %lf %lf]\n", */
	    /* 	    forces->f_k->fields[0][i],forces->f_k->fields[1][i],forces->f_k->fields[2][i], */
	    /* 	    forces_ewald->f_k->fields[0][i],forces_ewald->f_k->fields[1][i],forces_ewald->f_k->fields[2][i]); */
	    error_k   += SQR( forces->f_k->fields[j][i] - forces_ewald->f_k->fields[j][i] );
	  }
	}
	error_k = SQRT(error_k) / SQRT(system->nparticles);
      }

      ewald_error_k_est = compute_error_estimate_k( system, &parameters_ewald, parameters_ewald.alpha);
      error = Calculate_errors ( system, forces );

      if ( method.Error != NULL ) {
	if( calc_est == 0 )
	  estimate = method.Error ( system, &parameters );
	error_k_est = method.Error_k ( system, &parameters);
 	FLOAT_TYPE Q_uncorr, Q_corr, Q_nonfluc;
	/* Q_uncorr = Generic_error_estimate( A_ad, B_ad, C_ewald, system, &parameters, data); */
	/* Q_corr = Generic_error_estimate( A_ad_water, B_ad_water, C_ewald_water, system, &parameters, data); */

	FLOAT_TYPE corrected_est, corrected_total, rs_error;
	corrected_est = system->q2 / (system->length * SQR(system->length)) * SQRT( ( Q_uncorr - Q_corr ) / system->nparticles );
	gen_err = system->q2 / (system->length * SQR(system->length)) * SQRT( ( Q_uncorr ) / system->nparticles );
	gen_err_dip = ((Q_corr > 0) - (Q_corr < 0)) * system->q2 / (system->length * SQR(system->length)) * SQRT( ( FLOAT_ABS(Q_corr) ) / system->nparticles );
	rs_error =Realspace_error( system, &parameters );
	corrected_total = SQRT( SQR(rs_error) + SQR(corrected_est));

	/* printf("Q_uncorr %e, Q_corr %e, Q_nonfluc %e\n", Q_uncorr, Q_corr, Q_nonfluc); */

	printf ( "%8lf\t%8e\t%8e\t %8e %8e\t %8e sec\t %8e\t %e\t %e\n", FLOAT_CAST parameters.alpha, FLOAT_CAST (error.f / SQRT(system->nparticles)) , FLOAT_CAST estimate,
		 FLOAT_CAST rs_error , FLOAT_CAST error_k_est, FLOAT_CAST wtime, FLOAT_CAST gen_err, FLOAT_CAST gen_err_dip, FLOAT_CAST corrected_total );

	/* printf ( "%8lf\t%8e\t%8e\t %8e %8e\t %8e sec\n", FLOAT_CAST parameters.alpha, FLOAT_CAST (error.f / SQRT(system->nparticles)) , FLOAT_CAST estimate, */
	/* 	 FLOAT_CAST rs_error , FLOAT_CAST error_k_est, FLOAT_CAST wtime ); */

	fprintf ( fout,"% lf\t% e\t% e\t% e\t% e\t% e\t% e\t% e\n", 
		  FLOAT_CAST parameters.alpha, FLOAT_CAST (error.f / SQRT(system->nparticles)) , 
		  FLOAT_CAST estimate, FLOAT_CAST Realspace_error( system, &parameters ), 
		  FLOAT_CAST error_k_est, FLOAT_CAST error_k, FLOAT_CAST ewald_error_k_est, FLOAT_CAST corrected_total);
        } else {
            printf ( "%8lf\t%8e\t na\t%8e\t%8e\n", FLOAT_CAST parameters.alpha, FLOAT_CAST error.f / system->nparticles , FLOAT_CAST error.f_r, FLOAT_CAST error.f_k );
            fprintf ( fout,"% lf\t% e\t na\n", FLOAT_CAST parameters.alpha, FLOAT_CAST error.f / system->nparticles );
        }
#ifdef FORCE_DEBUG
        fprintf ( stderr, "%lf rms %e %e %e\n", parameters.alpha, error.f_v[0], error.f_v[1], error.f_v[2] );
#endif
        fflush ( stdout );
        fflush ( fout );
    }
    fclose ( fout );

    return 0;
}
///
/// Make SFTs from given REAL8TimeSeries at given timestamps, potentially applying a time-domain window on each timestretch first
///
SFTVector *
XLALMakeSFTsFromREAL8TimeSeries ( const REAL8TimeSeries *timeseries,	//!< input time-series
                                  const LIGOTimeGPSVector *timestamps, 	//!< timestamps to produce SFTs for (can be NULL), if given must all lies within timeseries' time-span
                                  const char *windowType,		//!< optional time-domain window function to apply before FFTing
                                  REAL8 windowBeta			//!< window parameter, if any
                                  )
{
  XLAL_CHECK_NULL ( timeseries != NULL, XLAL_EINVAL, "Invalid NULL input 'timeseries'\n");
  XLAL_CHECK_NULL ( timestamps != NULL, XLAL_EINVAL, "Invalid NULL input 'timestamps'\n");

  REAL8 dt = timeseries->deltaT;	// timeseries timestep */
  REAL8 Tsft = timestamps->deltaT;
  REAL8 df = 1.0 / Tsft;		// SFT frequency spacing

  // make sure that number of timesamples/SFT is an integer (up to possible rounding error 'eps')
  REAL8 timestepsSFT0 = Tsft / dt;
  UINT4 timestepsSFT  = lround ( timestepsSFT0 );
  XLAL_CHECK_NULL ( fabs ( timestepsSFT0 - timestepsSFT ) / timestepsSFT0 < eps, XLAL_ETOL,
                    "Inconsistent sampling-step (dt=%g) and Tsft=%g: must be integer multiple Tsft/dt = %g >= %g\n",
                    dt, Tsft, timestepsSFT0, eps );

  // prepare window function if requested
  REAL8Window *window = NULL;
  if ( windowType != NULL ) {
    XLAL_CHECK_NULL ( (window = XLALCreateNamedREAL8Window ( windowType, windowBeta, timestepsSFT )) != NULL, XLAL_EFUNC );
  }

  // ---------- Prepare FFT ----------
  REAL8Vector *timeStretchCopy;	// input array of length N
  XLAL_CHECK_NULL ( (timeStretchCopy = XLALCreateREAL8Vector ( timestepsSFT )) != NULL, XLAL_EFUNC, "XLALCreateREAL4Vector(%d) failed.\n", timestepsSFT );
  UINT4 numSFTBins = timestepsSFT / 2 + 1;	// number of positive frequency-bins + 'DC' to be stored in SFT
  fftw_complex *fftOut;	// output array of length N/2 + 1
  XLAL_CHECK_NULL ( (fftOut = fftw_malloc ( numSFTBins * sizeof(fftOut[0]) )) != NULL, XLAL_ENOMEM, "fftw_malloc(%d*sizeof(complex)) failed\n", numSFTBins );
  fftw_plan fftplan;	// FFTW plan
  LAL_FFTW_WISDOM_LOCK;
  XLAL_CHECK_NULL ( (fftplan = fftw_plan_dft_r2c_1d ( timestepsSFT, timeStretchCopy->data, fftOut, FFTW_ESTIMATE)) != NULL, XLAL_EFUNC );	// FIXME: or try FFTW_MEASURE
  LAL_FFTW_WISDOM_UNLOCK;

  LIGOTimeGPS tStart = timeseries->epoch;

  // get last possible start-time for an SFT
  REAL8 duration =  round ( timeseries->data->length * dt ); // rounded to seconds
  LIGOTimeGPS tLast = tStart;
  XLALGPSAdd( &tLast, duration - Tsft );

  // check that all timestamps lie within [tStart, tLast]
  for ( UINT4 i = 0; i < timestamps->length; i ++ )
    {
      char buf1[256], buf2[256];
      XLAL_CHECK_NULL ( XLALGPSDiff ( &tStart, &(timestamps->data[i]) ) <= 0, XLAL_EDOM, "Timestamp i=%d: %s before start-time %s\n",
                        i, XLALGPSToStr ( buf1, &(timestamps->data[i]) ), XLALGPSToStr ( buf2, &tStart ) );
      XLAL_CHECK_NULL ( XLALGPSDiff ( &tLast,   &(timestamps->data[i]) ) >=0, XLAL_EDOM, "Timestamp i=%d: %s after last start-time %s\n",
                        i, XLALGPSToStr ( buf1, &(timestamps->data[i]) ), XLALGPSToStr ( buf2, &tLast ) );
    }

  UINT4 numSFTs = timestamps->length;

  // prepare output SFT-vector
  SFTVector *sftvect;
  XLAL_CHECK_NULL ( (sftvect = XLALCreateSFTVector ( numSFTs, numSFTBins )) != NULL, XLAL_EFUNC,
                    "XLALCreateSFTVector(numSFTs=%d, numBins=%d) failed.\n", numSFTs, numSFTBins );

  // main loop: apply FFT to the requested time-stretches and store in output SFTs
  for ( UINT4 iSFT = 0; iSFT < numSFTs; iSFT++ )
    {
      SFTtype *thisSFT = &(sftvect->data[iSFT]);	// point to current SFT-slot to store output in

      // find the start-bin for this SFT in the time-series
      REAL8 offset = XLALGPSDiff ( &(timestamps->data[iSFT]), &tStart );
      INT4 offsetBins = lround ( offset / dt );

      // copy timeseries-data for that SFT into local buffer
      memcpy ( timeStretchCopy->data, timeseries->data->data + offsetBins, timeStretchCopy->length * sizeof(timeStretchCopy->data[0]) );

      // window the current time series stretch if required
      REAL8 sigma_window = 1;
      if ( window != NULL )
        {
	  sigma_window = sqrt ( window->sumofsquares / window->data->length );
	  for( UINT4 iBin = 0; iBin < timeStretchCopy->length; iBin++ ) {
            timeStretchCopy->data[iBin] *= window->data->data[iBin];
          }
        } // if window

      // FFT this time-stretch
      fftw_execute ( fftplan );

      // fill the header of the i'th output SFT */
      strcpy ( thisSFT->name, timeseries->name );
      thisSFT->epoch = timestamps->data[iSFT];
      thisSFT->f0 = timeseries->f0;			// SFT starts at heterodyning frequency
      thisSFT->deltaF = df;

      // normalize DFT-data to conform to v2 specification ==> multiply DFT by (dt/sigma{window})
      // the SFT normalization in case of windowing follows the conventions detailed in the SFTv2 specification,
      // namely LIGO-T040164, and in particular Eqs.(3),(4) and (6) in T010095-00.pdf
      // https://dcc.ligo.org/cgi-bin/private/DocDB/ShowDocument?.submit=Number&docid=T010095
      // https://dcc.ligo.org/DocDB/0026/T010095/000/T010095-00.pdf
      REAL8 norm = dt / sigma_window;
      for ( UINT4 k = 0; k < numSFTBins ; k ++ ) {
        thisSFT->data->data[k] = (COMPLEX8) ( norm * fftOut[k] );
      }

      // correct heterodyning-phase, IF NECESSARY: ie if (fHet * tStart) is not an integer, such that phase-corr = multiple of 2pi
      if ( ( (INT4)timeseries->f0 != timeseries->f0  ) || (timeseries->epoch.gpsNanoSeconds != 0) || (thisSFT->epoch.gpsNanoSeconds != 0) ) {
        XLAL_CHECK_NULL ( XLALcorrect_phase ( thisSFT, timeseries->epoch) == XLAL_SUCCESS, XLAL_EFUNC );
      }

    } // for iSFT < numSFTs

  // free memory
  fftw_free ( fftOut );
  LAL_FFTW_WISDOM_LOCK;
  fftw_destroy_plan ( fftplan );
  LAL_FFTW_WISDOM_UNLOCK;
  XLALDestroyREAL8Vector ( timeStretchCopy );
  XLALDestroyREAL8Window ( window );

  return sftvect;

} // XLALMakeSFTsFromREAL8TimeSeries()
Exemple #3
0
//==============================================================================
//cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
//==============================================================================
RealStateSlab::~RealStateSlab() {
  //==============================================================================

  if(planeArr != NULL) {fftw_free(planeArr);planeArr = NULL; planeArrR=NULL;}

}
void test02 ( void )

/******************************************************************************/
/*
  Purpose:

    TEST02: apply FFT to real 1D data.

  Modified:

    23 October 2005

  Author:

    John Burkardt
*/
{
  int i;
  double *in;
  double *in2;
  int n = 100;
  int nc;
  fftw_complex *out;
  fftw_plan plan_backward;
  fftw_plan plan_forward;
  unsigned int seed = 123456789;

  printf ( "\n" );
  printf ( "TEST02\n" );
  printf ( "  Demonstrate FFTW3 on a single vector of real data.\n" );
  printf ( "\n" );
  printf ( "  Transform data to FFT coefficients.\n" );
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
  printf ( "  Compare recovered data to original data.\n" );
/*
  Set up an array to hold the data, and assign the data.
*/
  in = fftw_malloc ( sizeof ( double ) * n );

  srand ( seed );

  for ( i = 0; i < n; i++ )
  {
    in[i] = frand ( );
  }

  printf ( "\n" );
  printf ( "  Input Data:\n" );
  printf ( "\n" );

  for ( i = 0; i < n; i++ )
  {
    printf ( "  %4d  %12f\n", i, in[i] );
  }
/*
  Set up an array to hold the transformed data,
  get a "plan", and execute the plan to transform the IN data to
  the OUT FFT coefficients.
*/
  nc = ( n / 2 ) + 1;

  out = fftw_malloc ( sizeof ( fftw_complex ) * nc );

  plan_forward = fftw_plan_dft_r2c_1d ( n, in, out, FFTW_ESTIMATE );

  fftw_execute ( plan_forward );

  printf ( "\n" );
  printf ( "  Output FFT Coefficients:\n" );
  printf ( "\n" );

  for ( i = 0; i < nc; i++ )
  {
    printf ( "  %4d  %12f  %12f\n", i, out[i][0], out[i][1] );
  }
/*
  Set up an arrray to hold the backtransformed data IN2,
  get a "plan", and execute the plan to backtransform the OUT
  FFT coefficients to IN2.
*/
  in2 = fftw_malloc ( sizeof ( double ) * n );

  plan_backward = fftw_plan_dft_c2r_1d ( n, out, in2, FFTW_ESTIMATE );

  fftw_execute ( plan_backward );

  printf ( "\n" );
  printf ( "  Recovered input data divided by N:\n" );
  printf ( "\n" );

  for ( i = 0; i < n; i++ )
  {
    printf ( "  %4d  %12f\n", i, in2[i] / ( double ) ( n ) );
  }
/*
  Release the memory associated with the plans.
*/
  fftw_destroy_plan ( plan_forward );
  fftw_destroy_plan ( plan_backward );

  fftw_free ( in );
  fftw_free ( in2 );
  fftw_free ( out );

  return;
}
void test04 ( void )

/******************************************************************************/
/*
  Purpose:

    TEST04: apply FFT to real 2D data.

  Discussion:

    In this example, we generate NX=8 by NY=10 random real values 
    stored as an NX by NY array of type DOUBLE named "IN".

    We have FFTW3 compute the Fourier transform of this data named "OUT".

    We have FFTW3 compute the inverse Fourier transform of "OUT" to get
    "IN2", which should be the original input data, scaled by NX * NY.

    The Fourier coefficients are stored in an NX by NYH array where
    NYH = (NY/2) + 1.  We only compute about half the data because
    of real data implies symmetric FFT coefficients.

      a[i*nyh+j][0] is the real      part of A(I,J).
      a[i*nyh+j][1] is the imaginary part of A(I,J)..

  Modified:

    05 November 2007

  Author:

    John Burkardt
*/
{
  int i;
  double *in;
  double *in2;
  int j;
  int nx = 8;
  int ny = 10;
  int nyh;
  fftw_complex *out;
  fftw_plan plan_backward;
  fftw_plan plan_forward;
  unsigned int seed = 123456789;

  printf ( "\n" );
  printf ( "TEST04\n" );
  printf ( "  Demonstrate FFTW3 on a %d by %d array of real data.\n",
    nx, ny );
  printf ( "\n" );
  printf ( "  Transform data to FFT coefficients.\n" );
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
  printf ( "  Compare recovered data to original data.\n" );
/*
  Create the input array, an NX by NY array of doubles.
*/
  in = malloc ( sizeof ( double ) * nx * ny );

  srand ( seed );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      in[i*ny+j] = frand ( );
    }
  }

  printf ( "\n" );
  printf ( "  Input Data:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      printf ( "  %4d  %4d  %12f\n", i, j, in[i*ny+j] );
    }
  }
/*
  Create the output array OUT, which is of type FFTW_COMPLEX,
  and of a size NX * NYH that is roughly half the dimension of the input data
  (ignoring the fact that the input data is real, and the FFT
  coefficients are complex).
*/
  nyh = ( ny / 2 ) + 1;

  out = fftw_malloc ( sizeof ( fftw_complex ) * nx * nyh );

  plan_forward = fftw_plan_dft_r2c_2d ( nx, ny, in, out, FFTW_ESTIMATE );

  fftw_execute ( plan_forward );

  printf ( "\n" );
  printf ( "  Output FFT Coefficients:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < nyh; j++ )
    {
      printf ( "  %4d  %4d  %12f  %12f\n", 
      i, j, out[i*nyh+j][0], out[i*nyh+j][1] );
    }
  }
/*
  Recreate the input array.
*/
  in2 = malloc ( sizeof ( double ) * nx * ny );

  plan_backward = fftw_plan_dft_c2r_2d ( nx, ny, out, in2, FFTW_ESTIMATE );

  fftw_execute ( plan_backward );

  printf ( "\n" );
  printf ( "  Recovered input data divided by NX * NY:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      printf ( "  %4d  %4d  %12f\n",  
        i, j, in2[i*ny+j] / ( double ) ( nx * ny ) );
    }
  }
/*
  Free up the allocated memory.
*/
  fftw_destroy_plan ( plan_forward );
  fftw_destroy_plan ( plan_backward );

  free ( in );
  free ( in2 );
  fftw_free ( out );

  return;
}
void test_planner(int rank)
{
     /* 
      * create and destroy many plans, at random.  Check the
      * garbage-collecting allocator of twiddle factors 
      */
     int i, dim;
     int r, s;
     fftw_plan p[PLANNER_TEST_SIZE];
     fftwnd_plan pnd[PLANNER_TEST_SIZE];
     int *narr, maxdim;

     chk_mem_leak = 0;
     verbose--;

     please_wait();
     if (rank < 1)
	  rank = 1;

     narr = (int *) fftw_malloc(rank * sizeof(int));

     maxdim = (int) pow(8192.0, 1.0/rank);

     for (i = 0; i < PLANNER_TEST_SIZE; ++i) {
	  p[i] = (fftw_plan) 0;
	  pnd[i] = (fftwnd_plan) 0;
     }

     for (i = 0; i < PLANNER_TEST_SIZE * PLANNER_TEST_SIZE; ++i) {
	  r = rand();
	  if (r < 0)
	       r = -r;
	  r = r % PLANNER_TEST_SIZE;

	  for (dim = 0; dim < rank; ++dim) {
	       do {
		    s = rand();
		    if (s < 0)
			 s = -s;
		    s = s % maxdim + 1;
	       } while (s == 0);
	       narr[dim] = s;
	  }

	  if (rank == 1) {
	       if (p[r])
		    rfftw_destroy_plan(p[r]);

	       p[r] = rfftw_create_plan(narr[0], random_dir(), measure_flag |
					wisdom_flag);
	       if (paranoid && narr[0] < 200)
		    test_correctness(narr[0]);
	  }
	  if (pnd[r])
	       rfftwnd_destroy_plan(pnd[r]);

	  pnd[r] = rfftwnd_create_plan(rank, narr,
				       random_dir(), measure_flag |
				       wisdom_flag);

	  if (i % (PLANNER_TEST_SIZE * PLANNER_TEST_SIZE / 20) == 0) {
	       WHEN_VERBOSE(0, printf("test planner: so far so good\n"));
	       WHEN_VERBOSE(0, printf("test planner: iteration %d out of %d\n",
			      i, PLANNER_TEST_SIZE * PLANNER_TEST_SIZE));
	  }
     }

     for (i = 0; i < PLANNER_TEST_SIZE; ++i) {
	  if (p[i])
	       rfftw_destroy_plan(p[i]);
	  if (pnd[i])
	       rfftwnd_destroy_plan(pnd[i]);
     }

     fftw_free(narr);
     verbose++;
     chk_mem_leak = 1;
}
void test_speed_nd_aux(struct size sz,
		       fftw_direction dir, int flags, int specific)
{
     fftw_real *in;
     fftwnd_plan plan;
     double t;
     fftw_time begin, end;
     int i, N;

     /* only bench in-place multi-dim transforms */
     flags |= FFTW_IN_PLACE;	

     N = 1;
     for (i = 0; i < sz.rank - 1; ++i)
	  N *= sz.narray[i];

     N *= (sz.narray[i] + 2);

     in = (fftw_real *) fftw_malloc(N * howmany_fields * sizeof(fftw_real));

     if (specific) {
	  begin = fftw_get_time();
	  plan = rfftwnd_create_plan_specific(sz.rank, sz.narray, dir,
					      speed_flag | flags
					      | wisdom_flag | no_vector_flag,
					      in, howmany_fields, 0, 1);
     } else {
	  begin = fftw_get_time();
	  plan = rfftwnd_create_plan(sz.rank, sz.narray,
				     dir, speed_flag | flags
				     | wisdom_flag | no_vector_flag);
     }
     end = fftw_get_time();
     CHECK(plan != NULL, "can't create plan");

     t = fftw_time_to_sec(fftw_time_diff(end, begin));
     WHEN_VERBOSE(2, printf("time for planner: %f s\n", t));

     WHEN_VERBOSE(2, printf("\n"));
     WHEN_VERBOSE(2, (rfftwnd_print_plan(plan)));
     WHEN_VERBOSE(2, printf("\n"));

     if (dir == FFTW_REAL_TO_COMPLEX) {
	  FFTW_TIME_FFT(rfftwnd_real_to_complex(plan, howmany_fields,
						in, howmany_fields, 1,
						0, 0, 0),
			in, N * howmany_fields, t);
     } else {
	  FFTW_TIME_FFT(rfftwnd_complex_to_real(plan, howmany_fields,
						(fftw_complex *) in,
						howmany_fields, 1,
						0, 0, 0),
			in, N * howmany_fields, t);
     }

     rfftwnd_destroy_plan(plan);

     WHEN_VERBOSE(1, printf("time for one fft: %s", smart_sprint_time(t)));
     WHEN_VERBOSE(1, printf(" (%s/point)\n", smart_sprint_time(t / N)));
     WHEN_VERBOSE(1, printf("\"mflops\" = 5/2 (N log2 N) / (t in microseconds)"
			" = %f\n", 0.5 * howmany_fields * mflops(t, N)));

     fftw_free(in);

     WHEN_VERBOSE(1, printf("\n"));
}
Exemple #8
0
static void destroy_fftw(struct holder *holder)
{
	fftw_destroy_plan(holder->plan);
	fftw_free(holder->output);
	fftw_free(holder->samples);
}
//=======================================================================
void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_)
{
	if (initialised) // if we have already initialised FFT plan
	{
		// destroy fft plan
		fftw_destroy_plan(p);
		fftw_free(complexIn);
		fftw_free(complexOut);

	}
	
	hopSize = hopSize_; // set hopsize
	frameSize = frameSize_; // set framesize
	
	onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type
    windowType = windowType_; // set window type
		
	// initialise buffers
    frame.resize(frameSize);
    window.resize(frameSize);
    magSpec.resize(frameSize);
    prevMagSpec.resize(frameSize);
    phase.resize(frameSize);
    prevPhase.resize(frameSize);
    prevPhase2.resize(frameSize);
	
	
	// set the window to the specified type
	switch (windowType){
		case RectangularWindow:
			calculateRectangularWindow();		// Rectangular window
			break;	
		case HanningWindow:
			calculateHanningWindow();			// Hanning Window
			break;
		case HammingWindow:
			calclulateHammingWindow();			// Hamming Window
			break;
		case BlackmanWindow:
			calculateBlackmanWindow();			// Blackman Window
			break;
		case TukeyWindow:
			calculateTukeyWindow();             // Tukey Window
			break;
		default:
			calculateHanningWindow();			// DEFAULT: Hanning Window
	}
	
	// initialise previous magnitude spectrum to zero
	for (int i = 0;i < frameSize;i++)
	{
		prevMagSpec[i] = 0.0;
		prevPhase[i] = 0.0;
		prevPhase2[i] = 0.0;
		frame[i] = 0.0;
	}
	
	prevEnergySum = 0.0;	// initialise previous energy sum value to zero
	
	/*  Init fft */
	complexIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize);		// complex array to hold fft data
	complexOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize);	// complex array to hold fft data
	p = fftw_plan_dft_1d(frameSize, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE);	// FFT plan initialisation
	
	initialised = true;
}
Exemple #10
0
void test_P3DFFT(int *n, std::ofstream& results, int decomp, int * dims){

  int nx,ny,nz,procid,nprocs,ndim;
  int istart[3],isize[3],iend[3];
  int fstart[3],fsize[3],fend[3];
  int p3dfft_mem_conf,nrep;
  long int Nlocal,Nglob;
  double factor;
  double l_timers[12]={0},g_timers[12]={0};
  double total_time=0*MPI_Wtime(), setup_time=0;
  // rtime_local is timings on each process and _global is the max reduced to root
  // 0 is the forward FFT time, 1 is the Hadamard multiplication, 2 is the IFFT time, 3 is the sum of 0-2, and 4 is the setup time
  // The communication time is measured by l_timers locally on each process and then reduced to g_timers to the root.
  // the sum of first four elements give the comm time
  unsigned char op_f[4]="fft", op_b[4]="tff";
  int memsize[3];

  MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
  MPI_Comm_rank(MPI_COMM_WORLD,&procid);



  nx=n[0]; ny=n[1]; nz=n[2]; ndim=1; nrep=NREP;

  if(decomp==1){
    dims[0] = 1; dims[1] = nprocs;
  }
  if(procid == 0)
    printf("Using processor grid %d x %d\n",dims[0],dims[1]);

  /* Initialize P3DFFT */
  MPI_Barrier(MPI_COMM_WORLD);
  setup_time -= MPI_Wtime(); //Compute Setup Time.
  Cp3dfft_setup(dims,nx,ny,nz,MPI_Comm_c2f(MPI_COMM_WORLD),nx,ny,nz,1,memsize);
  setup_time +=  MPI_Wtime(); //Compute Setup Time.
  PCOUT<<"done with setup"<<std::endl;

  Cp3dfft_get_dims(istart,iend,isize,1);
  Cp3dfft_get_dims(fstart,fend,fsize,2);
  /* Allocate and initialize */

  double *A; // Input matrix A
  A=(double*)fftw_malloc(sizeof(double)*(memsize[0]*memsize[1]*memsize[2]*2));
  //B=(double*)fftw_malloc(sizeof(double)*(memsize[0]*memsize[1]*memsize[2]*2));

  /* Warmup */
  Cp3dfft_ftran_r2c(A,A,op_f);
  Cp3dfft_ftran_r2c(A,A,op_f);
  MPI_Barrier(MPI_COMM_WORLD);
  Cset_timers();

  for (int rep=0; rep<nrep; rep++){
    initialize_p3dfft(A,n);

    MPI_Barrier(MPI_COMM_WORLD);

    /* Forward transform */
    total_time -=  MPI_Wtime();
    Cp3dfft_ftran_r2c(A,A,op_f);
    total_time +=  MPI_Wtime();

    MPI_Barrier(MPI_COMM_WORLD);
  }

  Cget_timers(l_timers);
  Cp3dfft_btran_c2r(A,A,op_b);

  /* Compute Error */
  //PCOUT<<"Done With FFTs computing error"<<std::endl;
  compute_error_p3dfft(A,n);

  /* Gather timing statistics */
  double g_total_time, g_comm_time, g_setup_time;

  MPI_Reduce(&total_time,&g_total_time,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD);
  MPI_Reduce(&setup_time,&g_setup_time,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD);
  MPI_Reduce(&l_timers,&g_timers,12,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD);


  g_total_time=g_total_time/nrep;
  g_comm_time=(g_timers[0]+g_timers[1]+g_timers[2]+g_timers[3])/((double) nrep);
  //g_total_time=g_total_time/((double)nrep);
  ptrdiff_t size=n[0];size*=n[1]; size*=n[2];
  double gflops=2.5*size*( log2(n[2]) + log2(n[0])+ log2(n[1]) )/(g_total_time)/1e9;

  if(procid == 0){
    std::cout.precision(4);
    std::cout<<"P3DFFT Size="<<n[0]<<" "<<n[1]<<" "<<n[2]<<std::endl;;
    std::cout<<"0= "<<g_timers[0]<<" 1= "<<g_timers[1]<<" 2= "<<g_timers[2]<<" 3= "<<g_timers[3]<<" 4= "<<g_timers[4]<<std::endl;
    std::cout<<"5= "<<g_timers[5]<<" 6= "<<g_timers[6]<<" 7= "<<g_timers[7]<<" 8= "<<g_timers[8]<<" 9= "<<g_timers[9]<<std::endl;
    std::cout<<"10= "<<g_timers[10]<<" 11= "<<g_timers[11]<<std::endl;
    std::cout<<"\033[1;31m";
    std::cout<<"\t"<<"np"<<"\t"<<"Grid"<<"\t"<<"Total"<<'\t'<<"Comm Time"<<"\t"<<"Setup Time"<<"\t"<<"\t"<<"Reps"<<'\t'<<"GFlops"<<std::endl;
    std::cout<<"\t"<<nprocs<<"\t"<<dims[1]<<"*"<<dims[0]<<"\t"<<g_total_time<<'\t'<<g_comm_time<<"\t"<<g_setup_time<<"\t"<<nrep<<'\t'<<gflops<<std::endl;
    std::cout<<"\033[0m\n"<<std::endl;

    results<<"\t"<<nprocs<<"\t"<<dims[1]<<"*"<<dims[0]<<"\t"<<g_total_time<<'\t'<<g_comm_time<<"\t"<<g_setup_time<<"\t"<<nrep<<'\t'<<gflops<<std::endl;
  }
  /* Free work space */
  fftw_free(A);
  Cp3dfft_clean();

}
Exemple #11
0
void CalcFourierTransforms(struct fouriercomponents *fc) {
  
#if WRITE_DEBUG_DATS 
  FILE *debug_FT;
  char *d_DIR = (char*)malloc(sizeof(char)*100);
#endif
      
  unsigned int a,b,i;
  unsigned int sample_rate = fc->signal_size;
  double *in, imag_power, real_power;
  fftw_complex *out;
  fftw_plan plan;
   
  in = (double*) fftw_malloc(sizeof(double) * fc->signal_size);
  out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fc->signal_size);  
  plan = fftw_plan_dft_r2c_1d(fc->signal_size, in, out, FFTW_ESTIMATE);
  
  for (a=0;a<fc->signal_count;a++) {

    fc->real[a]      = (double *) malloc(sizeof(double)*fc->signal_size);
    fc->imag[a]      = (double *) malloc(sizeof(double)*fc->signal_size);
    fc->freq[a]      = (double *) malloc(sizeof(double)*fc->signal_size);
    fc->magnitude[a] = (double *) malloc(sizeof(double)*fc->signal_size);
    fc->phase[a]     = (double *) malloc(sizeof(double)*fc->signal_size);

#if WRITE_DEBUG_DATS 
    {          
      if (fc->scan_mode==0)
        strcpy(d_DIR,DEBUG_IMAGE_DIR "FTS/h/");
      else if (fc->scan_mode==1)
        strcpy(d_DIR,DEBUG_IMAGE_DIR "FTS/v/");
      else if (fc->scan_mode==2)
        strcpy(d_DIR,DEBUG_IMAGE_DIR "cradle/");
      char buf[100];
      sprintf(buf,"%04d",a);
      strcat(d_DIR,buf);
      strcat(d_DIR,".dat");
      debug_FT = fopen(d_DIR,"w");
    }
#endif

    for (b=0;b<fc->signal_size;b++)
      in[b] = fc->signals[a][b];
    
    fftw_execute(plan); 
       
    for (i=1;i<fc->signal_size/2+1;i++) {
      
      fc->real[a][i] = out[i][0];//cos
      fc->imag[a][i] = out[i][1];//sin
      fc->freq[a][i] = i * sample_rate / fc->signal_size;
      
      real_power = pow(fc->real[a][i],2);
      imag_power = pow(fc->imag[a][i],2);
      fc->magnitude[a][i] = sqrt(real_power + imag_power);
      fc->phase[a][i] = atan(fc->imag[a][i] / fc->real[a][i]);

#if WRITE_DEBUG_DATS
      {              
        fprintf(debug_FT,"%0.2lf %0.2lf\n",fc->freq[a][i],fc->magnitude[a][i]);
        //printf("%d |real:%lf imag:%lf    FREQ:%lf    MAGNITUDE:%lf PHASE:%lf\n",
        //       i,fc->real[i],fc->imag[i],fc->freq[i],fc->magnitude[i],fc->phase[i]);
      }
#endif 
    }
    
#if WRITE_DEBUG_DATS
    fclose(debug_FT);
#endif
  }
  
  fftw_destroy_plan(plan);
  fftw_free(in); 
  fftw_free(out);
}
void smurf_fts2_spectrum(int* status)
{
    if( *status != SAI__OK ) { return; }

    const char*  dataLabel    = "Spectrum";     /* Data label */
    Grp* gIn                  = NULL;           /* Input group */
    Grp* gOut                 = NULL;           /* Output group */
    Grp* gSfp                 = NULL;           /* SFP group */
    smfData* inData           = NULL;           /* Pointer to input data */
    smfData* outData          = NULL;           /* Pointer to output data */
    smfData* sfpData          = NULL;           /* Pointer to SFP data */
  /*smfData* sfp              = NULL;*/         /* Pointer to SFP index data */
    int doSFP                 = 0;              /* Only apply SFP if given */
    int zeropad               = 1;              /* Determines whether to zeropad */
    double resolution         = 0.0;            /* Spectral Resolution */
    double resolutionin       = 0.0;            /* Spectral Resolution input */
    double resolutionzp       = 0.0;            /* Spectral Resolution zero padded */
    double resolution_override= 0.0;            /* Spectral Resolution override */
    int i                     = 0;              /* Counter */
    int j                     = 0;              /* Counter */
    int k                     = 0;              /* Counter */
    int l                     = 0;              /* Counter */
    double fNyquist           = 0.0;            /* Nyquist frequency */
    double fNyquistin         = 0.0;            /* Nyquist frequency input */
    double fNyquistzp         = 0.0;            /* Nyquist frequency zero padded */
    double dSigma             = 0.0;            /* Spectral Sampling Interval */
    double dSigmain           = 0.0;            /* Spectral Sampling Interval zero padded */
    double dSigmazp           = 0.0;            /* Spectral Sampling Interval zero padded */
    double* IFG               = NULL;           /* Interferogram */
    double* SFP               = NULL;           /* Spectral Filter Profile for all pixels */
    double* SFPij             = NULL;           /* Spectral Filter Profile for a single pixel */
    double wavelen            = 0.0;            /* The central wave length of the subarray filter (m) */
    double wnSfpFirst         = 10.600;         /* Starting 850 band SFP wave number */
    double wnSfpLast          = 12.800;         /* Ending 850 band SFP wave number */
    double wnSfp850First      = 11.220;         /* Starting 850 band SFP wave number */
    double wnSfp850Last       = 12.395;         /* Ending 850 band SFP wave number */
  /*double wnSfp850First      = 10.600;*/       /* Starting 850 band SFP wave number */
  /*double wnSfp850Last       = 12.800;*/       /* Ending 850 band SFP wave number */
    double wnSfp450First      = 21.630;         /* Starting 450 band SFP wave number */
    double wnSfp450Last       = 23.105;         /* Ending 450 band SFP wave number */
    double wnSfpFirst_override= 0.0;            /* Starting SFP wave number override */
    double wnSfpLast_override = 0.0;            /* Ending SFP wave number override */
    double wnSfpResolution    = 0.025;          /* The resolution of the SFP wave numbers (1/cm) */
    double wnSfpF             = 0.0;            /* Starting SFP wave number */
    double wnSfpL             = 0.0;            /* Ending SFP wave number */
    double* WN                = NULL;           /* Wave Numbers from SFP */
    double* DS                = NULL;           /* Double Sided Interferogram */
    fftw_complex* DSIN        = NULL;           /* Double-Sided interferogram, FFT input */
    fftw_complex* SPEC        = NULL;           /* Spectrum */
    fftw_plan plan            = NULL;           /* fftw plan */
    gsl_interp_accel* ACC     = NULL;           /* SFP interpolator */
    gsl_spline* SPLINE        = NULL;           /* SFP interpolation spline */

    size_t nFiles             = 0;              /* Size of the input group */
    size_t nOutFiles          = 0;              /* Size of the output group */
    size_t nSFPFiles          = 0;              /* Size of the SFP group */
    size_t nSfp               = 89;             /* Number of SFP calibration file values */
    size_t fIndex             = 0;              /* File index */
    size_t nWidth             = 32;             /* Data cube width */
    size_t nHeight            = 40;             /* Data cube height */
    size_t nFrames            = 0;              /* Data cube depth */
    size_t nPixels            = nWidth*nHeight; /* Number of bolometers in the subarray */

    double dIntensity         = 0;
    int N                     = 0;
    int Nin                   = 0;                /* N input */
    int Nzp                   = 0;                /* N zero padded */
    int N2                    = 0;
    int N2in                  = 0;                /* N/2 input */
    int N2zp                  = 0;                /* N/2 zero padded */
    int bolIndex              = 0;
    int cubeIndex             = 0;
    int badPixel              = 0;
    int indexZPD              = 0;
    int indexZPDin            = 0;
    int indexZPDzp            = 0;
    int pad                   = 0;               /* zero padding (difference between input and zero padded interferogram length) */
    int pad2                  = 0;               /* zero padding / 2 */
    double dx                 = 0.0;             /* Delta x */
    double dxin               = 0.0;             /* Delta x input */
    double dxzp               = 0.0;             /* Delta x zero padded */
    double OPDMax             = 0.0;             /* OPD max in cm */
    double OPDMaxin           = 0.0;             /* OPD max in cm input */
    double OPDMaxzp           = 0.0;             /* OPD max in cm zero padded */
    double s                  = 0.0;             /* spectrum value */
    double f                  = 0.0;             /* filter value */

#define DEBUG 0

    /* Get Input & Output groups */
    kpg1Rgndf("IN", 0, 1, "", &gIn, &nFiles, status);
    kpg1Wgndf("OUT", gOut, nFiles, nFiles, "Equal number of input and output files expected!", &gOut, &nOutFiles, status);
    kpg1Gtgrp("SFP", &gSfp, &nSFPFiles, status);
    if(*status != SAI__OK) {
        /* TODO: Check for any other possible error conditions */
        /* Assume SFP calibration file not given, and proceed without it */
        doSFP = 0;
        *status = SAI__OK;
    } else {
	    if(nSFPFiles > 0) doSFP = 1;
    }

    /* Read in ADAM parameters */
    parGet0i("ZEROPAD", &zeropad, status);

    /* Resolution */
    parGet0d("RESOLUTION", &resolution_override, status);

    if(doSFP) {
        /* SFP WN Range overrides */
        parGet0d("WNSFPFIRST", &wnSfpFirst_override, status);
			if(*status != SAI__OK) {
				*status = SAI__OK;  /* Allow null */
				wnSfpFirst_override = 0.0;
			}
        parGet0d("WNSFPLAST", &wnSfpLast_override, status);
			if(*status != SAI__OK) {
				*status = SAI__OK;  /* Allow null */
				wnSfpLast_override = 0.0;
			}
    }

    /* BEGIN NDF */
    ndfBegin();


    /* Loop through each input file */
    for(fIndex = 1; fIndex <= nFiles; fIndex++) {
        /* Open Observation file */
        smf_open_file(NULL, gIn, fIndex, "READ", SMF__NOFIX_METADATA, &inData, status);
        if(*status != SAI__OK) {
            *status = SAI__ERROR;
            errRep(FUNC_NAME, "Unable to open the source file!", status);
            goto CLEANUP;
        }

        /* Data cube dimensions */
        nWidth  = inData->dims[0];
        nHeight = inData->dims[1];
        nFrames = inData->dims[2];
        nPixels = nWidth * nHeight;

        /*printf("%s: nWidth=%d, nHeight=%d, nPixels=%d, nFrames=%d\n", TASK_NAME, nWidth, nHeight, nPixels, nFrames);*/

        /* Check if the file is initialized for FTS2 processing */
        if(!(inData->fts)) {
            *status = SAI__ERROR;
            errRep( FUNC_NAME, "The file is NOT initialized for FTS2 data reduction!", status);
            goto CLEANUP;
        }

        /* Read in the Nyquist frequency from FITS component */
        smf_fits_getD(inData->hdr, "FNYQUIST", &fNyquist, status);
        if(*status != SAI__OK) {
            *status = SAI__ERROR;
            errRep(FUNC_NAME, "Unable to find the Nyquist frequency in FITS component!", status);
            goto CLEANUP;
        }

        /* Read in the wave length (m) from the FITS header to determine the band */
        smf_fits_getD(inData->hdr, "WAVELEN", &wavelen, status);
        if(*status != SAI__OK) {
            *status = SAI__ERROR;
            errRep(FUNC_NAME, "Unable to find the wavelen in the FITS header!", status);
            goto CLEANUP;
        }

        /* Set WN SFP range according to band */
        if(wavelen == 0.00085) {
            wnSfpFirst = wnSfp850First;
            wnSfpLast = wnSfp850Last;
        } else if(wavelen == 0.00045) {
            wnSfpFirst = wnSfp450First;
            wnSfpLast = wnSfp450Last;
        }

      /*printf("%s: wnSfpFirst_override=%f, wnSfpLast_override=%f\n", TASK_NAME, wnSfpFirst_override, wnSfpLast_override);*/
      /*printf("%s: wnSfpFirst=%f, wnSfpLast=%f\n", TASK_NAME, wnSfpFirst, wnSfpLast);*/
        if(wnSfpFirst_override) {
            wnSfpF = wnSfpFirst_override;
        } else {
            wnSfpF = wnSfpFirst;
        }
        if(wnSfpLast_override) {
            wnSfpL = wnSfpLast_override;
        } else {
            wnSfpL = wnSfpLast;
        }
      /*printf("%s: wnSfpF=%f, wnSfpL=%f\n", TASK_NAME, wnSfpF, wnSfpL);*/

        fNyquistin = fNyquistzp = 0.0;
        dx = dxin = dxzp = 0.0;
        N2 = N2in = N2zp = 0;
        indexZPD = indexZPDin = indexZPDzp = 0;
        N = Nin = Nzp = 0;
        dSigma = dSigmain = dSigmazp = 0.0;

        fNyquistin = fNyquist;
        dxin = (1/(2*fNyquistin));
        N2in = (nFrames / 2);
        indexZPDin = N2in - 1;
        Nin = 2 * N2in;
        OPDMaxin = N2in * dxin;
        if(resolution_override > 0.0) {
            resolution = resolution_override;
            resolutionin = resolution_override;
        } else {
            resolution = 1 / (2 * OPDMaxin);
            resolutionin = resolution;
        }
        dSigmain = fNyquistin / N2in;

        if(zeropad) {
            if(DEBUG) {
                /* Make the zero-padded array twice the size of the input */
                fNyquistzp = fNyquist;
                Nzp = N2in * 4;
                N2zp = Nzp / 2;
                dxzp = 1 / (2 * fNyquistzp);
                OPDMaxzp = N2zp * dxzp;
                dSigmazp = fNyquistzp / N2zp;
                resolutionzp = 1 / (2 * OPDMaxzp);
            } else {
                /* Round Nyquist frequency down to nearest integer, for calculation convenience
                fNyquistzp = floor(fNyquist);

                smf_fits_updateD(inData->hdr, "FNYQUIST", fNyquistzp, "Nyquist frequency (cm^-1)", status);*/

                /* Never change nyquist when zero padding */
                fNyquistzp = fNyquist;

                /* If resolution > 0.05, then round down to nearest 0.05 value, else set to 0.005 */
                /* Calculate resolution as 1 / (2*OPDMax) */
                /* Calculate OPDMax as N2 * dx */

                if(resolution_override) {
                    resolutionzp = resolution_override;
                } else {
                    if(resolution > 0.05) {
                        resolutionzp = floor(resolution/0.05) * 0.05;
                    } else {
                        resolutionzp = 0.005;
                    }
                }

                /* Calculate OPDMaxOut  as 1 / (2 * resolutionzp) */
                OPDMaxzp = 1 / (2 * resolutionzp);

                /* Calculate N2 */
                dxzp = (1/(2*fNyquistzp));
                N2zp = (OPDMaxzp / dxzp);
                indexZPDzp = N2zp - 1;
                Nzp = 2 * N2zp;
                dSigmazp = fNyquistzp / N2zp;
            }
        }

      /*printf("%s: Nin=%d, Nzp=%d, N2in=%d, N2zp=%d, indexZPDin=%d, indexZPDzp=%d, dSigmain=%f, dSigmazp=%f, fNyquistin=%f, fNyquistzp=%f, dxin=%f, dxzp=%f, OPDMaxin=%f, OPDMaxzp=%f, resolutionin=%f, resolutionzp=%f\n",
               TASK_NAME, Nin, Nzp, N2in, N2zp, indexZPDin, indexZPDzp, dSigmain, dSigmazp, fNyquistin, fNyquistzp, dxin, dxzp, OPDMaxin, OPDMaxzp, resolutionin, resolutionzp);*/

        if(zeropad) {
            N = Nzp;
            N2 = N2zp;
            indexZPD = indexZPDzp;
            dSigma = dSigmazp;
            fNyquist = fNyquistzp;
            dx = dxzp;
            OPDMax = OPDMaxzp;
            resolution = resolutionzp;
        } else {
            N = Nin;
            N2 = N2in;
            indexZPD = indexZPDin;
            dSigma = dSigmain;
            fNyquist = fNyquistin;
            dx = dxin;
            OPDMax = OPDMaxin;
            resolution = resolutionin;
        }

        /* Save wavenumber factor to FITS extension */
        smf_fits_updateD(inData->hdr, "WNFACT", dSigma, "Wavenumber factor cm^-1", status);

        /* TODO: Update mirror positions */
        smf_fits_updateI(inData->hdr, "MIRSTART", 0, "Frame index in which the mirror starts moving", status);
        smf_fits_updateI(inData->hdr, "MIRSTOP", N2, "Frame index in which the mirror stops moving", status);
      /*smf_fits_updateD(inData->hdr, "OPDMIN", OPD_EVEN[0], "Minimum OPD", status);
        smf_fits_updateD(inData->hdr, "OPDSTEP", dx, "OPD step size", status);*/


        /* Copy input data into output data */
        outData = smf_deepcopy_smfData(NULL, inData, 0, SMF__NOCREATE_DATA, 0, 0, status);
        outData->dtype   = SMF__DOUBLE;
        outData->ndims   = 3;
        outData->dims[0] = nWidth;
        outData->dims[1] = nHeight;
        outData->dims[2] = N2+1;
        outData->pntr[0] = (double*) astMalloc((nPixels * (N2+1)) * sizeof(double));
        if (dataLabel) { one_strlcpy(outData->hdr->dlabel, dataLabel, sizeof(outData->hdr->dlabel), status ); }

        /* Allocate memory for arrays */
        IFG  = astCalloc(N,  sizeof(*IFG));
        DS   = astCalloc(N, sizeof(*DS));
        DSIN = fftw_malloc(N * sizeof(*DSIN));
        SPEC = fftw_malloc(N * sizeof(*SPEC));

        /* Initialize arrays */
        for(k = 0; k < N; k++) { SPEC[k][0] = SPEC[k][1] = DSIN[k][0] = DSIN[k][1] = DS[k] = IFG[k] = 0.0; }

        /* Open the SFP calibration file, if given */
        if(doSFP) {
            smf_open_file(NULL, gSfp, 1, "READ", SMF__NOCREATE_QUALITY, &sfpData, status);
            if(*status != SAI__OK) {
                *status = SAI__ERROR;
                errRep(FUNC_NAME, "Unable to open the SFP calibration file!", status);
                goto CLEANUP;
            }

            /* Read in the number of data elements */
            nSfp = sfpData->dims[1] / nPixels;
            /* Allocate memory for arrays */
            SFP = astCalloc(nSfp*nPixels, sizeof(*SFP));
            SFPij = astCalloc(nSfp, sizeof(*SFP));
            WN  = astCalloc(nSfp, sizeof(*WN));

            /* DEBUG: Dispay SFP data */
          /*printf("smurf_fts2_spectrum ([%d,%d,%d] elements): WN, SFP\n", (int)sfpData->dims[0],(int)sfpData->dims[1],(int)sfpData->dims[2]);*/
            for(k=0;k<nSfp;k++){
                /* printf("WN:%.3f,SFP:%.10f\n", *((double*) (sfpData->pntr[0]) + i), *((double*) (sfpData->pntr[0]) + i+1)); */
                /* Adjust starting and ending wave number ranges for 450 or 850 bands */
                if(wavelen == 0.00085 || wavelen == 0.00045) {
                    WN[k] = wnSfpFirst + k * wnSfpResolution;
                } else {
                    *status = SAI__ERROR;
                    errRep(FUNC_NAME, "Unexpected WAVELEN value found in the FITS header!", status);
                    goto CLEANUP;
                }
              /*printf("SFP WN[%d]=%f\n",k,WN[k]);*/
                for(j=0;j<nHeight;j++) {
                    for(i=0;i<nWidth;i++) {
                        bolIndex = i + j * nWidth;
                        cubeIndex = bolIndex + k * nPixels;
                        SFP[cubeIndex] = *((double*) (sfpData->pntr[0]) + cubeIndex);
                      /*if(i==10 && j==20) printf("SFP i:%d,j:%d,k:%d,bolIndex:%d,cubeIndex:%d=%f\n",i,j,k,bolIndex,cubeIndex,SFP[cubeIndex]);*/
                    }
                }
            }

            /*printf("smurf_fts2_spectrum DEBUG: early exiting!\n");
              exit(0); */

            /* Create a 2D SFP index array and store it in the file, if given
            sfp = smf_create_smfData(SMF__NOCREATE_DA | SMF__NOCREATE_FTS, status);
            sfp->dtype   = SMF__INTEGER;
            sfp->ndims   = 2;
            sfp->dims[0] = nSfp;
            sfp->dims[1] = 2;
            sfp->pntr[0] = (int*) astCalloc(nSfp*2,  sizeof(double));
            // By default set ZPD indices to a bad value
            for(i = 0; i < nSfp; i++) {
                for(j = 0; j < 2; j++) {
                    bolIndex = i + j * 2;
                    *((int*) (sfp->pntr[0]) + bolIndex) = VAL__BADI;
                }
            } */

            /* Prepare GSL interpolator to convert SFP data to this spectrum's resolution */
            ACC    = gsl_interp_accel_alloc();
            SPLINE = gsl_spline_alloc(gsl_interp_cspline, nSfp);
        }

        for(i = 0; i < nWidth; i++) {
            for(j = 0; j < nHeight; j++) {
                bolIndex = i + j * nWidth;

                badPixel = 0;
                for(k = 0; k < Nin; k++) {
                    dIntensity = *((double*)(inData->pntr[0]) + (bolIndex + k * nPixels));
                    if(dIntensity == VAL__BADD) {
                        badPixel = 1;
                        break;
                    }
                }
                /* If this is a bad pixel, go to next */
                if(badPixel) {
                    for(k = 0; k <= N2in; k++) {
                        *((double*)(outData->pntr[0]) + (bolIndex + k * nPixels)) = VAL__BADD;
                    }
                    continue;
                }

                /* Double-Sided interferogram */
                if(zeropad) {
                    pad = Nzp - Nin;
                    pad2 = pad / 2;
                    /* Copy the right half of the input into the left half of this IFG, zero padded in the middle */
                    for(k=indexZPDin; k<Nin; k++) {
                        /*printf("%s: IFG: indexZPDin=%d, indexZPDzp=%d, Nin=%d, Nzp=%d, k=%d, l=%d\n", TASK_NAME, indexZPDin, indexZPDzp, Nin, Nzp, k, l);*/
                        IFG[k - indexZPDin] = *((double*)(inData->pntr[0]) + (bolIndex + k * nPixels));
                      /*if(i==16 && j==25) {
                            printf("%s: Pixel[%d,%d]: (L<-R) IFG[k(%d)-indexZPDin(%d)=%d] = inData->pntr[bolIndex(%d)+k(%d)*nPixels(%d)=%d] = %g\n",
                                   TASK_NAME, i, j, k, indexZPDin, (k - indexZPDin), bolIndex, k, nPixels, (bolIndex + k * nPixels), IFG[k - indexZPDin]);
                        }*/
                    }
                    /* Copy the left half of the input into the right half of this IFG, zero padded in the middle */
                    for(k=0,l=0; k<indexZPDin; k++) {
                        IFG[Nzp - indexZPDin + k] =  *((double*)(inData->pntr[0]) + (bolIndex + k * nPixels));
                      /*if(i==16 && j==25) {
                            printf("%s: Pixel[%d,%d]: (L->R) IFG[Nzp(%d)-indexZPDin(%d)+k(%d)=%d] = inData->pntr[bolIndex(%d)+k(%d)*nPixels(%d)=%d] = %g\n",
                                   TASK_NAME, i, j, Nzp, indexZPDin, k, (Nzp-indexZPDin+k), bolIndex, k, nPixels, (bolIndex+k*nPixels), IFG[Nzp-indexZPDin+k]);
                        }*/
                    }
                } else {
                    /* Copy the right half of the input into the left half of this IFG */
                    for(k=indexZPD; k<N; k++) {
                        IFG[k - indexZPD] = *((double*)(inData->pntr[0]) + (bolIndex + k * nPixels));
                      /*if(i==16 && j==25) {
                            printf("%s: Pixel[%d,%d]: (L<-R) IFG[k(%d)-indexZPD(%d)=%d] = inData->pntr[bolIndex(%d)+k(%d)*nPixels(%d)=%d] = %f\n",
                                     TASK_NAME, i, j, k, indexZPD, (k - indexZPD), bolIndex, k, nPixels, (bolIndex + k * nPixels), IFG[k - indexZPD]);
                        }*/
                    }
                    /* Copy the left half of the input into the right half of this IFG */
                    for(k=0; k<indexZPD; k++) {
                        IFG[N - indexZPD + k] =  *((double*)(inData->pntr[0]) + (bolIndex + k * nPixels));
                      /*if(i==16 && j==25) {
                              printf("%s: Pixel[%d,%d]: (L->R) IFG[N(%d)-indexZPD(%d)+k(%d)=%d] = inData->pntr[bolIndex(%d)+k(%d)*nPixels(%d)=%d] = %f\n",
                                     TASK_NAME, i, j, N, indexZPD, k, (N - indexZPD + k), bolIndex, k, nPixels, (bolIndex + k * nPixels), IFG[N - indexZPD + k]);
                        }*/
                    }
                }

                /* DEBUG: Write out input data
                for(k = 0; k < Nin; k++) {
                    *((double*)(outData->pntr[0]) + (bolIndex + nPixels * k)) =
                    *((double*)( inData->pntr[0]) + (bolIndex + nPixels * k));
                    if(i==16 && j==25) {
                        printf("%s: inData[%d,%d,%d]=%g\n",TASK_NAME, i, j, k, *((double*)( inData->pntr[0]) + (bolIndex + nPixels * k)));
                    }
                } */

                /* DEBUG: Write out the shifted IFG
                for(k = 0; k < N; k++) {
                    *((double*)(outData->pntr[0]) + (bolIndex + k* nPixels)) = IFG[k];
                    if(i==16 && j==25) {
                        printf("%s: IFG[%d,%d,%d]=%g\n",TASK_NAME, i, j, k, IFG[k]);
                    }
                } */

                /* Convert real-valued interferogram to complex-valued interferogram */
                for(k = 0; k < N; k++) { DSIN[k][0] = IFG[k]; DSIN[k][1] = 0.0; }

                /* DEBUG: Write out DSIN
                for(k = 0; k < N; k++) {
                    *((double*)(outData->pntr[0]) + (bolIndex + k * nPixels)) = DSIN[k][0];
                    if(i==16 && j==25) {
                        printf("%s: DSIN[%d,%d,%d]=%g\n",TASK_NAME, i, j, k, DSIN[k][0]);
                    }
                } */

                /* FFT Double-sided complex-valued interferogram */
                plan = fftw_plan_dft_1d(N, DSIN, SPEC, FFTW_FORWARD, FFTW_ESTIMATE);
                fftw_execute(plan);

                /* Normalize spectrum */
                for(k=0;k<N;k++) { SPEC[k][0] = SPEC[k][0] / (double)(N * resolution); }

                /* Apply SFP calibration, if given */
                if(doSFP){
                    /* Get the SFP for this pixel */
                    for(k=0;k<nSfp;k++) { SFPij[k] = SFP[i + j*nWidth + k*nPixels]; }
                    /* Interpolate the SFP values from its original WN scale to the current spectrum scale */
                    gsl_spline_init(SPLINE, WN, SFPij, nSfp);

                    /* Divide the spectrum in the band pass region by the interpolated SFP value at each position */
                    for(k = 0; k < N; k++) {
                      /*if(k*dSigma >= WN[0] && k*dSigma <= WN[nSfp-1]) {*/
                        if(k*dSigma >= wnSfpF && k*dSigma <= wnSfpL) {
                            f = gsl_spline_eval(SPLINE, k*dSigma, ACC);
                            /*index = bolIndex + nPixels * k;*/
                            s = SPEC[k][0];
                            SPEC[k][0] = s / f;
                          /*if(i==10 && j==20) { printf("SFP i=%d, j=%d, k=%d, dSigma=%f, k*dSigma=%f, s=%f, f=%f, s/f=%f, \n", i, j, k, dSigma, k*dSigma, s, f, s/f); }*/
                        }
                    }
                }

                /* Write out the positive real component of the spectrum */
                for(k = 0; k <= N2; k++) {
                    *((double*)(outData->pntr[0]) + (bolIndex + k * nPixels)) = SPEC[k][0];
                  /*if(i==16 && j==25) {
                        printf("%s: SPEC[%d,%d,%d]=%E\n",TASK_NAME, i, j, k, SPEC[k][0] / (double)(N * resolution));
                    }*/
                }

                /* Destroy each allocated plan */
                if(plan) { fftw_destroy_plan(plan); }
            }
        }

        /* Deallocate memory used by arrays */
        if(IFG)  { IFG = astFree(IFG); }
        if(DS)   { DS = astFree(DS); }
        if(SFP)  { SFP = astFree(SFP); }
        if(SFPij)  { SFPij = astFree(SFPij); }
        if(WN)   { WN = astFree(WN); }
        if(DSIN) { fftw_free(DSIN); DSIN = NULL; }
        if(SPEC) { fftw_free(SPEC); SPEC = NULL; }
        if(ACC)     { gsl_interp_accel_free(ACC);   ACC     = NULL; }
        if(SPLINE)  { gsl_spline_free(SPLINE);      SPLINE  = NULL; }

        /* Close the file */
        if(inData) {
            smf_close_file( NULL,&inData, status);
            if(*status != SAI__OK) {
                *status = SAI__ERROR;
                errRep(FUNC_NAME, "Unable to close the input file!", status);
                goto CLEANUP;
            }
        }

        /* Write output */
        /* outData->fts = smf_construct_smfFts(NULL, sfp, fpm, sigma, status);   // TODO: Add interpolated SFP to FITS header */
        smf_write_smfData(NULL, outData, NULL, NULL, gOut, fIndex, 0,
                          MSG__VERB, 0, NULL, NULL, status);
        if(*status != SAI__OK) {
            *status = SAI__ERROR;
            errRep(FUNC_NAME, "Unable to write the output file!", status);
            goto CLEANUP;
        }
        smf_close_file( NULL,&outData, status);
        if(*status != SAI__OK) {
            *status = SAI__ERROR;
            errRep(FUNC_NAME, "Unable to close the output file!", status);
            goto CLEANUP;
        }
    }

CLEANUP:
    if(IFG)  { IFG = astFree(IFG); }
    if(DS)   { DS = astFree(DS); }
    if(SFP)  { SFP = astFree(SFP); }
    if(SFPij)  { SFPij = astFree(SFPij); }
    if(WN)   { WN = astFree(WN); }
    if(DSIN) { fftw_free(DSIN); DSIN = NULL; }
    if(SPEC) { fftw_free(SPEC); SPEC = NULL; }
    if(ACC)     { gsl_interp_accel_free(ACC);   ACC     = NULL; }
    if(SPLINE)  { gsl_spline_free(SPLINE);      SPLINE  = NULL; }

    /* Close files if still open */
    if(inData) {
        smf_close_file( NULL,&inData, status);
        if(*status != SAI__OK) {
            *status = SAI__ERROR;
            errRep(FUNC_NAME, "CLEANUP: Unable to close the input file!", status);
        }
    }
    if(outData) {
        smf_close_file( NULL,&outData, status);
        if(*status != SAI__OK) {
            *status = SAI__ERROR;
            errRep(FUNC_NAME, "CLEANUP: Unable to close the output file!", status);
        }
    }
    if(sfpData) {
        smf_close_file( NULL,&sfpData, status);
        if(*status != SAI__OK) {
            *status = SAI__ERROR;
            errRep(FUNC_NAME, "CLEANUP: Unable to close the SFP file!", status);
        }
    }

    /* END NDF */
    ndfEnd(status);

    /* Delete Groups */
    if(gIn) grpDelet(&gIn, status);
    if(gOut) grpDelet(&gOut, status);
    if(gSfp) grpDelet(&gSfp, status);
}
Exemple #13
0
/*==============================*/
int main (void)  {
    fftw_complex *gamma1k;
    fftw_complex *gamma2k;
    double *gamma1r;
    double *gamma2r;
    fftw_plan plan1;
    fftw_plan plan2;
    fftw_plan plana;
    fftw_plan planb;
    int nn = 1024;    // this needs to be changed to nc
    int cn2= nn/2 + 1;
    int N  = nn*nn*nn;
    int Nc = nn*nn*cn2;

    gamma1k = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Nc);
    gamma2k = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Nc);
    gamma1r = (double *) fftw_malloc(N * sizeof(double));
    gamma2r = (double *) fftw_malloc(N * sizeof(double));
    plan1 = fftw_plan_dft_r2c_3d(nn, nn, nn, gamma1r, gamma1k, FFTW_ESTIMATE);
    plan2 = fftw_plan_dft_r2c_3d(nn, nn, nn, gamma2r, gamma2k, FFTW_ESTIMATE);
    plana = fftw_plan_dft_c2r_3d(nn, nn, nn, gamma1k, gamma1r, FFTW_ESTIMATE);
    planb = fftw_plan_dft_c2r_3d(nn, nn, nn, gamma2k, gamma2r, FFTW_ESTIMATE);
/*===Finishing FFTW initialization===*/

    int i, j, k, index_0;
    float ga1, ga2;

    FILE *GAM1 = fopen(path1, "rb");
    FILE *GAM2 = fopen(path2, "rb");
 
    printf("Reading..\n");
    for(k = 0; k < nn; k++)  {
        for(j = 0; j < nn; j++)  {
            for(i = 0; i < nn; i++)  {
                index_0 = index_f(k, j, i);
                fread(&ga1, 4, 1, GAM1);
                fread(&ga2, 4, 1, GAM2);
                gamma1r[index_0] = ga1;
                gamma2r[index_0] = ga2;
            }
        }
    }
    printf("Finish reading...\n");
/*===Finishing reading data===*/

    fftw_execute(plan1);
    fftw_execute(plan2);
    printf("Finish fft for the first time...\n");
/*===Finishing FFTW one===*/

    double r_part1, i_part1;
    double r_part2, i_part2;
    int    x, y, z;
    double k2, k_mag, kv2, kv_mag, k1hat, k2hat;
    double factor1, factor2, weight;

    for(k = 0; k < nn; k++)  {
        printf("complicate process~~~%d\n", k);
        for(j = 0; j < nn; j++)  {
            for(i = 0; i < cn2; i++)  {
                index_0 = index_k(k, j, i); //index to find that element
                r_part1 = gamma1k[index_0][0];
                i_part1 = gamma1k[index_0][1];
                r_part2 = gamma2k[index_0][0];
                i_part2 = gamma2k[index_0][1];
  
                x = i;     // index to calculating wavenumber
                if(j < cn2) y = j; else y = (nn - j)*(-1.);
                if(k < cn2) z = k; else z = (nn - k)*(-1.);
                k2     = x*x + y*y + z*z;
                k_mag  = sqrt(k2);
                kv2    = x*x + y*y;
                kv_mag = sqrt(kv2);
             // add something about kv2 = 0 case
             //
                if (kv2 == 0) {
                    gamma1k[index_0][0] = 0.;
                    gamma1k[index_0][1] = 0.;
                    gamma2k[index_0][0] = 0.;
                    gamma2k[index_0][1] = 0.;
                }
                else  {
                k1hat  = x/kv_mag;
                k2hat  = y/kv_mag;
                factor1 = (pow(k1hat, 2) - pow(k2hat, 2)) * 2. * k2/kv2;
                factor2 = (2.*k1hat*k2hat) * 2. *k2/kv2;
                weight  = pow((kv2/k2), 2);
                gamma1k[index_0][0] = (factor1*r_part1+factor2*r_part2);
                gamma1k[index_0][1] = (factor1*i_part1+factor2*i_part2); 
                gamma2k[index_0][0] = (-factor2*r_part1+factor1*r_part2);
                gamma2k[index_0][1] = (-factor2*i_part1+factor1*i_part2);
                }
           }
        }
    }
    fftw_execute(plana);
    fftw_execute(planb);
    printf("Finishig IFFT ......\n");
/*===Multiplying  window function===*/

    FILE *KAP  = fopen(pathout1, "wb");
    FILE *KAPU = fopen(pathout2, "wb");
   
    float out1, out2;
    printf("Begin to output...\n");
    for(k = 0; k < nn; k++)  {
        for(j = 0; j < nn; j++)  {
            for(i = 0; i < nn; i++)  {
                index_0 = index_f(k, j, i);
                out1 = gamma1r[index_0]/pow(nc, 3);
                out2 = gamma2r[index_0]/pow(nc, 3);
                fwrite(&out1, 4, 1, KAP);
                fwrite(&out2, 4, 1, KAPU);
            }
        }
    }
/*============================*/ 
    fftw_destroy_plan(plan1);
    fftw_destroy_plan(plan2);
    fftw_destroy_plan(plana);
    fftw_destroy_plan(planb);
    fftw_free(gamma1k);
    fftw_free(gamma2k);
    fftw_free(gamma1r);
    fftw_free(gamma2r);

    return 0;
}
bool tpImageFilter::ApplyFastFilterTemplate(const T& I, TRes& O, const tpFilter& F)
{
	int L = I.getWidth();
	int width = L;
	int M = I.getHeight();
	int height = M;
	const double factor = 1.0/sqrt((double)height*width);
	O.resize(height, width);

	std::cout << "[INFO] Create complex caches numbers : " << L << "x" << M << std::endl;
	fftw_complex* in = (fftw_complex*)fftw_malloc(sizeof (fftw_complex)*M*L);
	fftw_complex* out = (fftw_complex*)fftw_malloc(sizeof (fftw_complex)*M*L);
	fftw_complex* kernel = (fftw_complex*)fftw_malloc(sizeof (fftw_complex)*M*L);
	fftw_plan p;
	fftw_plan p_inv;

	int w2 = (int)floor(F.getWidth() / 2.0);
	int h2 = (int)floor(F.getHeight() / 2.0);
	int centerX = (int)ceil(M / 2.0);
	int centerY = (int)ceil(L / 2.0);
	std::cout << "[INFO] Filtering size : " << F.getHeight() << "x" << F.getWidth() << std::endl;
	std::cout << "[INFO] half Filtering size : " << h2 << "x" << w2 << std::endl;
	//  Fill fftw_complex for kernel
	for(int x = 0; x < M; x++)
		for(int y = 0; y < L; y++)
		{
			if(((centerX - h2) < x) & ((centerX + h2) >= x) & ((centerY - w2) < y) & ((centerY + w2) >= y))
			{
				int vX = x - (centerX - h2);
				int vY = y - (centerY - w2);
				in[x*L+y][0] = F[vX][vY];
				in[x*L+y][1] = F[vX][vY];
			}
			else
			{
				in[x*L+y][0] = 0;
				in[x*L+y][1] = 0;
			}
		}
	// Create the plan (need by fftw)
	p = fftw_plan_dft_2d(M, L, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
	// Apply the transform (kernel)
	fftw_execute(p);
	for(int i = 0; i < M; i++)
		for(int j = 0; j < L; j++)
		{
			kernel[i*L+j][0] = out[i*L+j][0];
			kernel[i*L+j][1] = out[i*L+j][1];
		}
	// Apply transform (image)
	for(int i = 0; i < M; i++)
		for(int j = 0; j < L; j++)
		{
			in[i*L+j][0] = I[i][j];
			in[i*L+j][1] = 0;
		}
	fftw_execute(p);
	// Apply filter
	for(int i = 0; i < M; i++)
		for(int j = 0; j < L; j++)
		{
			out[i*L+j][0] = out[i*L+j][0]*kernel[i*L+j][0];
			out[i*L+j][1] = out[i*L+j][1]*kernel[i*L+j][1];
		}

	// Reverse the transform ...
	p_inv = fftw_plan_dft_2d(M, L, out, in, FFTW_BACKWARD, FFTW_ESTIMATE);
	fftw_execute(p_inv);
	// Copy result
	for(int i = 0; i < centerX; i++)
		for(int j = 0; j < centerY; j++)
		{
			O[i][j] = in[(i+centerX)*width + j+centerY][0]*factor*factor;
			O[i][j+centerY] = in[(i+centerX)*width + j][0]*factor*factor;
			O[i+centerX][j+centerY] = in[(i)*width + j][0]*factor*factor;
			O[i+centerX][j] = in[(i)*width + j + centerY][0]*factor*factor;
		}
	// Free memory
	fftw_destroy_plan(p);
	fftw_destroy_plan(p_inv);
	fftw_free(in);
	fftw_free(out);
	fftw_free(kernel);
	return true;
}
void testnd_out_of_place(int rank, int *n, fftwnd_plan validated_plan)
{
     int istride, ostride;
     int N, dim, i, j, k;
     int nc, nhc, nr;
     fftw_real *in1, *out3;
     fftw_complex *in2, *out1, *out2;
     fftwnd_plan p, ip;
     int flags = measure_flag | wisdom_flag;

     if (coinflip())
	  flags |= FFTW_THREADSAFE;

     N = nc = nr = nhc = 1;
     for (dim = 0; dim < rank; ++dim)
	  N *= n[dim];
     if (rank > 0) {
	  nr = n[rank - 1];
	  nc = N / nr;
	  nhc = nr / 2 + 1;
     }
     in1 = (fftw_real *) fftw_malloc(N * MAX_STRIDE * sizeof(fftw_real));
     out3 = (fftw_real *) fftw_malloc(N * MAX_STRIDE * sizeof(fftw_real));
     out1 = (fftw_complex *) fftw_malloc(nhc * nc * MAX_STRIDE
					 * sizeof(fftw_complex));
     in2 = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     out2 = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));

     p = rfftwnd_create_plan(rank, n, FFTW_REAL_TO_COMPLEX, flags);
     ip = rfftwnd_create_plan(rank, n, FFTW_COMPLEX_TO_REAL, flags);
     CHECK(p != NULL && ip != NULL, "can't create plan");

     for (istride = 1; istride <= MAX_STRIDE; ++istride) {
	  /* generate random inputs */
	  for (i = 0; i < nc; ++i)
	       for (j = 0; j < nr; ++j) {
		    c_re(in2[i * nr + j]) = DRAND();
		    c_im(in2[i * nr + j]) = 0.0;
		    for (k = 0; k < istride; ++k)
			 in1[(i * nr + j) * istride + k]
			     = c_re(in2[i * nr + j]);
	       }
	  for (i = 0; i < N * istride; ++i)
	       out3[i] = 0.0;

	  fftwnd(validated_plan, 1, in2, 1, 1, out2, 1, 1);

	  for (ostride = 1; ostride <= MAX_STRIDE; ++ostride) {
	       int howmany = (istride < ostride) ? istride : ostride;

	       WHEN_VERBOSE(2, printf("\n    testing stride %d/%d...",
				      istride, ostride));

	       if (howmany != 1 || istride != 1 || ostride != 1 || coinflip())
		    rfftwnd_real_to_complex(p, howmany, in1, istride, 1,
					    out1, ostride, 1);
	       else
		    rfftwnd_one_real_to_complex(p, in1, out1);

	       for (i = 0; i < nc; ++i)
		    for (k = 0; k < howmany; ++k)
			 CHECK(compute_error_complex(out1 + i * nhc * ostride + k,
						     ostride,
						     out2 + i * nr, 1,
						     nhc) < TOLERANCE,
			       "out-of-place (r2c): wrong answer");

	       if (howmany != 1 || istride != 1 || ostride != 1 || coinflip())
		    rfftwnd_complex_to_real(ip, howmany, out1, ostride, 1,
					    out3, istride, 1);
	       else
		    rfftwnd_one_complex_to_real(ip, out1, out3);

	       for (i = 0; i < N * istride; ++i)
		    out3[i] *= 1.0 / N;

	       if (istride == howmany)
		    CHECK(compute_error(out3, 1, in1, 1, N * istride)
			< TOLERANCE, "out-of-place (c2r): wrong answer");
	       for (i = 0; i < nc; ++i)
		    for (k = 0; k < howmany; ++k)
			 CHECK(compute_error(out3 + i * nr * istride + k,
					     istride,
					 (fftw_real *) (in2 + i * nr), 2,
					     nr) < TOLERANCE,
			   "out-of-place (c2r): wrong answer (check 2)");
	  }
     }

     rfftwnd_destroy_plan(p);
     rfftwnd_destroy_plan(ip);

     fftw_free(out3);
     fftw_free(out2);
     fftw_free(in2);
     fftw_free(out1);
     fftw_free(in1);
}
Exemple #16
0
void fourier::destroyTransform(){
  fftw_destroy_plan(plan);
  npoints=0;
  fftw_free(in);
  fftw_free(out);
}
void testnd_in_place(int rank, int *n, fftwnd_plan validated_plan,
		     int alternate_api, int specific)
{
     int istride, ostride, howmany;
     int N, dim, i, j, k;
     int nc, nhc, nr;
     fftw_real *in1, *out3;
     fftw_complex *in2, *out1, *out2;
     fftwnd_plan p, ip;
     int flags = measure_flag | wisdom_flag | FFTW_IN_PLACE;

     if (coinflip())
	  flags |= FFTW_THREADSAFE;

     N = nc = nr = nhc = 1;
     for (dim = 0; dim < rank; ++dim)
	  N *= n[dim];
     if (rank > 0) {
	  nr = n[rank - 1];
	  nc = N / nr;
	  nhc = nr / 2 + 1;
     }
     in1 = (fftw_real *) fftw_malloc(2 * nhc * nc * MAX_STRIDE * sizeof(fftw_real));
     out3 = in1;
     out1 = (fftw_complex *) in1;
     in2 = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     out2 = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));

     if (alternate_api && specific && (rank == 2 || rank == 3)) {
	  if (rank == 2) {
	       p = rfftw2d_create_plan_specific(n[0], n[1],
					     FFTW_REAL_TO_COMPLEX, flags,
						in1, MAX_STRIDE, 0, 0);
	       ip = rfftw2d_create_plan_specific(n[0], n[1],
					     FFTW_COMPLEX_TO_REAL, flags,
						 in1, MAX_STRIDE, 0, 0);
	  } else {
	       p = rfftw3d_create_plan_specific(n[0], n[1], n[2],
					     FFTW_REAL_TO_COMPLEX, flags,
						in1, MAX_STRIDE, 0, 0);
	       ip = rfftw3d_create_plan_specific(n[0], n[1], n[2],
					     FFTW_COMPLEX_TO_REAL, flags,
						 in1, MAX_STRIDE, 0, 0);
	  }
     } else if (specific) {
	  p = rfftwnd_create_plan_specific(rank, n, FFTW_REAL_TO_COMPLEX,
					   flags,
				       in1, MAX_STRIDE, in1, MAX_STRIDE);
	  ip = rfftwnd_create_plan_specific(rank, n, FFTW_COMPLEX_TO_REAL,
					    flags,
				       in1, MAX_STRIDE, in1, MAX_STRIDE);
     } else if (alternate_api && (rank == 2 || rank == 3)) {
	  if (rank == 2) {
	       p = rfftw2d_create_plan(n[0], n[1], FFTW_REAL_TO_COMPLEX,
				       flags);
	       ip = rfftw2d_create_plan(n[0], n[1], FFTW_COMPLEX_TO_REAL,
					flags);
	  } else {
	       p = rfftw3d_create_plan(n[0], n[1], n[2], FFTW_REAL_TO_COMPLEX,
				       flags);
	       ip = rfftw3d_create_plan(n[0], n[1], n[2], FFTW_COMPLEX_TO_REAL,
					flags);
	  }
     } else {
	  p = rfftwnd_create_plan(rank, n, FFTW_REAL_TO_COMPLEX, flags);
	  ip = rfftwnd_create_plan(rank, n, FFTW_COMPLEX_TO_REAL, flags);
     }

     CHECK(p != NULL && ip != NULL, "can't create plan");

     for (i = 0; i < nc * nhc * 2 * MAX_STRIDE; ++i)
	  out3[i] = 0;

     for (istride = 1; istride <= MAX_STRIDE; ++istride) {
	  /* generate random inputs */
	  for (i = 0; i < nc; ++i)
	       for (j = 0; j < nr; ++j) {
		    c_re(in2[i * nr + j]) = DRAND();
		    c_im(in2[i * nr + j]) = 0.0;
		    for (k = 0; k < istride; ++k)
			 in1[(i * nhc * 2 + j) * istride + k]
			     = c_re(in2[i * nr + j]);
	       }

	  fftwnd(validated_plan, 1, in2, 1, 1, out2, 1, 1);

	  howmany = ostride = istride;

	  WHEN_VERBOSE(2, printf("\n    testing in-place stride %d...",
				 istride));

	  if (howmany != 1 || istride != 1 || ostride != 1 || coinflip())
	       rfftwnd_real_to_complex(p, howmany, in1, istride, 1,
				       out1, ostride, 1);
	  else
	       rfftwnd_one_real_to_complex(p, in1, NULL);

	  for (i = 0; i < nc; ++i)
	       for (k = 0; k < howmany; ++k)
		    CHECK(compute_error_complex(out1 + i * nhc * ostride + k,
						ostride,
						out2 + i * nr, 1,
						nhc) < TOLERANCE,
			  "in-place (r2c): wrong answer");

	  if (howmany != 1 || istride != 1 || ostride != 1 || coinflip())
	       rfftwnd_complex_to_real(ip, howmany, out1, ostride, 1,
				       out3, istride, 1);
	  else
	       rfftwnd_one_complex_to_real(ip, out1, NULL);

	  for (i = 0; i < nc * nhc * 2 * istride; ++i)
	       out3[i] *= 1.0 / N;

	  for (i = 0; i < nc; ++i)
	       for (k = 0; k < howmany; ++k)
		    CHECK(compute_error(out3 + i * nhc * 2 * istride + k,
					istride,
					(fftw_real *) (in2 + i * nr), 2,
					nr) < TOLERANCE,
			  "in-place (c2r): wrong answer (check 2)");
     }

     rfftwnd_destroy_plan(p);
     rfftwnd_destroy_plan(ip);

     fftw_free(out2);
     fftw_free(in2);
     fftw_free(in1);
}
Exemple #18
0
int
main(int argc,char** argv){
  BMP fin (argv[1]);
  BMP fout;fout.init(fin.w,fin.h);
  
  double  (*in  )[8];
  double  (*out )[8];
  double  (*out2)[8];
  fftw_plan p ;
  int i,j,idx;
 
  in  = (double (*)[8])fftw_malloc( sizeof(double) * 8*8);
  out = (double (*)[8])fftw_malloc( sizeof(double) * 8*8);
  out2= (double (*)[8])fftw_malloc( sizeof(double) * 8*8);

 
  for(int c=0;c<3;c++){
    for(int by=0;by<fin.h/8;by++)
      for(int bx=0;bx<fin.w/8;bx++){
	for(int dy=0;dy<8;dy++)
	  for(int dx=0;dx<8;dx++){
	    int x=bx*8+dx;
	    int y=by*8+dy;
	    in[   dy][   dx]=fin(x,y)[c];
	  }


	p = fftw_plan_r2r_2d( 8,8,
			      (double*)in, (double*)out,
			      FFTW_REDFT10,FFTW_REDFT10,
			      FFTW_ESTIMATE );
      
	fftw_execute(p);


	for(int dy=0;dy<8;dy++)
	  for(int dx=0;dx<8;dx++){
	    out[   dy][   dx]/=8*8*4;
	  }
      
	for(int dy=0;dy<8;dy++)
	  for(int dx=0;dx<8;dx++){
	    //	    out[   dy][   dx]=round(out[   dy][   dx]/(qt[dy][dx]*quality));
	    out[   dy][   dx]=round(out[   dy][   dx]/2);
	  }

	for(int dy=0;dy<8;dy++)
	  for(int dx=0;dx<8;dx++){
	    //	    out[   dy][   dx]*=qt[dy][dx]*quality;
	    out[   dy][   dx]*=2;
	  }

      
	// for(int dy=0;dy<8;dy++)
	//   for(int dx=0;dx<8;dx++){
	//     printf("%04d\n",(int)out[   dy][   dx]);
	//   }
      
	p = fftw_plan_r2r_2d( 8,8,
			      (double*)out, (double*)out2,
			      FFTW_REDFT01,FFTW_REDFT01,
			      FFTW_ESTIMATE );
	fftw_execute(p);

      


	for(int dy=0;dy<8;dy++)
	  for(int dx=0;dx<8;dx++){
	    int x=bx*8+dx;
	    int y=by*8+dy;
	    fout(x,y)[c]=lmt(out2[   dy][   dx]);
	  }



      }
  }

  fout.write(argv[2]);
 
  fftw_destroy_plan(p);
  fftw_free(in);
  fftw_free(out);
  fftw_free(out2);
 
  return true;
}
/*
 * This is a real (as opposed to complex) variation of the FFT tester
 * described in
 *
 * Funda Ergün. Testing multivariate linear functions: Overcoming the
 * generator bottleneck. In Proceedings of the Twenty-Seventh Annual
 * ACM Symposium on the Theory of Computing, pages 407-416, Las Vegas,
 * Nevada, 29 May--1 June 1995.
 */
void test_ergun(int n, fftw_direction dir, fftw_plan plan)
{
     fftw_real *inA, *inB, *inC, *outA, *outB, *outC;
     fftw_real *inA1, *inB1;
     fftw_real *tmp;
     int i;
     int rounds = 20;
     FFTW_TRIG_REAL twopin = FFTW_K2PI / (FFTW_TRIG_REAL) n;

     inA = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));
     inB = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));
     inA1 = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));
     inB1 = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));
     inC = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));
     outA = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));
     outB = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));
     outC = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));
     tmp = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));

     WHEN_VERBOSE(2,
		  printf("Validating plan, n = %d, dir = %s\n", n,
			 dir == FFTW_REAL_TO_COMPLEX ? 
			 "REAL_TO_COMPLEX" : "COMPLEX_TO_REAL"));

     /* test 1: check linearity */
     for (i = 0; i < rounds; ++i) {
	  fftw_real alpha, beta;
	  alpha = DRAND();
	  beta = DRAND();
	  rfill_random(inA, n);
	  rfill_random(inB, n);
	  rarray_scale(inA1, inA, alpha, n);
	  rarray_scale(inB1, inB, beta, n);
	  rarray_add(inC, inA1, inB1, n);
	  rfftw_out_of_place(plan, n, inA, outA);
	  rfftw_out_of_place(plan, n, inB, outB);
	  rarray_scale(outA, outA, alpha, n);
	  rarray_scale(outB, outB, beta, n);
	  rarray_add(tmp, outA, outB, n);
	  rfftw_out_of_place(plan, n, inC, outC);
	  rarray_compare(outC, tmp, n);
     }

     /* test 2: check that the unit impulse is transformed properly */
     for (i = 0; i < n; ++i) {
	  /* impulse */
	  inA[i] = 0.0;
	  
	  /* transform of the impulse */
	  if (2 * i <= n)
	       outA[i] = 1.0;
	  else
	       outA[i] = 0.0;
     }
     inA[0] = 1.0;

     if (dir == FFTW_REAL_TO_COMPLEX) {
	  for (i = 0; i < rounds; ++i) {
	       rfill_random(inB, n);
	       rarray_sub(inC, inA, inB, n);
	       rfftw_out_of_place(plan, n, inB, outB);
	       rfftw_out_of_place(plan, n, inC, outC);
	       rarray_add(tmp, outB, outC, n);
	       rarray_compare(tmp, outA, n);
	  }
     } else {
	  for (i = 0; i < rounds; ++i) {
	       rfill_random(outB, n);
	       rarray_sub(outC, outA, outB, n);
	       rfftw_out_of_place(plan, n, outB, inB);
	       rfftw_out_of_place(plan, n, outC, inC);
	       rarray_add(tmp, inB, inC, n);
	       rarray_scale(tmp, tmp, 1.0 / ((double) n), n);
	       rarray_compare(tmp, inA, n);
	  }
     }

     /* test 3: check the time-shift property */
     /* the paper performs more tests, but this code should be fine too */
     if (dir == FFTW_REAL_TO_COMPLEX) {
	  for (i = 0; i < rounds; ++i) {
	       int j;

	       rfill_random(inA, n);
	       rarray_rol(inB, inA, n, 1, 1);
	       rfftw_out_of_place(plan, n, inA, outA);
	       rfftw_out_of_place(plan, n, inB, outB);
	       tmp[0] = outB[0];
	       for (j = 1; 2 * j < n; ++j) {
		    FFTW_TRIG_REAL s = dir * FFTW_TRIG_SIN(j * twopin);
		    FFTW_TRIG_REAL c = FFTW_TRIG_COS(j * twopin);
		    tmp[j] = outB[j] * c - outB[n - j] * s;
		    tmp[n - j] = outB[j] * s + outB[n - j] * c;
	       }
	       if (2 * j == n)
		    tmp[j] = -outB[j];

	       rarray_compare(tmp, outA, n);
	  }
     } else {
	  for (i = 0; i < rounds; ++i) {
	       int j;

	       rfill_random(inA, n);
	       inB[0] = inA[0];
	       for (j = 1; 2 * j < n; ++j) {
		    FFTW_TRIG_REAL s = dir * FFTW_TRIG_SIN(j * twopin);
		    FFTW_TRIG_REAL c = FFTW_TRIG_COS(j * twopin);
		    inB[j] = inA[j] * c - inA[n - j] * s;
		    inB[n - j] = inA[j] * s + inA[n - j] * c;
	       }
	       if (2 * j == n)
		    inB[j] = -inA[j];

	       rfftw_out_of_place(plan, n, inA, outA);
	       rfftw_out_of_place(plan, n, inB, outB);	       
	       rarray_rol(tmp, outA, n, 1, 1);
	       rarray_compare(tmp, outB, n);
	  }
     }

     WHEN_VERBOSE(2, printf("Validation done\n"));

     fftw_free(tmp);
     fftw_free(outC);
     fftw_free(outB);
     fftw_free(outA);
     fftw_free(inC);
     fftw_free(inB1);
     fftw_free(inA1);
     fftw_free(inB);
     fftw_free(inA);
}
Exemple #20
0
void cart_dfree(double **userrho)
{
    fftw_free(*userrho);
    free(userrho);
}
Exemple #21
0
int main(int argc,char *argv[]){
  char *filename,*locale;
  struct sample *samples = MAP_FAILED;
  off_t length;
  struct stat statbuf;
  double complex *buffer = NULL;
  double complex *spectrum = NULL;
  double complex cpstep;
  double carrier_freq,cstep;
  int i,fd,start,nsamples,exitcode;
  double complex carrier;
  
  exitcode = 0;
  fd = -1;
  if((locale = getenv("LANG")) != NULL)
    setlocale(LC_ALL,locale);
  else
    setlocale(LC_ALL,"en_US.utf8"); // The world revolves around the USA...

  while((i = getopt(argc,argv,"c:qr:f")) != EOF){
    switch(i){
    case 'c':
      Shift = atof(optarg);
      break;
    case 'q':
      Quiet = 1;
      break;
    case 'r': // Sample rate
      Samprate = atof(optarg);
      break;
    case 'f':
      Flip_samples++;
      break;
    default:
      fprintf(stderr,"%s: unknown option %c\n",argv[0],i);
      exit(1);
    }
  }

  filename = argv[optind];
  if(lstat(filename,&statbuf) == -1){
    fprintf(stderr,"lstat(%s) failed: %s\n",filename,strerror(errno));
    exitcode = 1;
    goto done;
  }
  if(!S_ISREG(statbuf.st_mode)){
    fprintf(stderr,"%s is not an ordinary file\n",filename);
    exitcode = 1;
    goto done;
  }
  length = statbuf.st_size;
  if((fd = open(filename,O_RDONLY)) == -1){
    fprintf(stderr,"open(%s,readonly) failed; %s\n",filename,strerror(errno));
    exitcode = 1;
    goto done;
  }
  if((samples = mmap(NULL,length,PROT_READ,MAP_SHARED,fd,0)) == MAP_FAILED){
    fprintf(stderr,"mmap(%s,%lld) failed: %s\n",filename,
	    (long long)length,strerror(errno));
    exitcode = 1;
    goto done;
  }
  nsamples = length / sizeof(struct sample);
  if(Flip_samples && !Quiet)
    fprintf(stderr,"I & Q samples swapped (spectrum inverted)\n");

  if((buffer = fftw_alloc_complex(Fftsize)) == NULL){
    fprintf(stderr,"fftw_alloc_complex(%d) failed\n",Fftsize);
    exitcode = 2;
    goto done;
  }
  if((spectrum = fftw_alloc_complex(Fftsize)) == NULL){
    fprintf(stderr,"fftw_alloc_complex(%d) failed\n",Fftsize);
    exitcode = 2;
    goto done;
  }
  if(!Quiet)
    fprintf(stderr,"demodulating %s: %'lld bytes, %'lld samples, %'.2lf sec @ %'.1lf Hz\n",
	    argv[optind],(long long)length,(long long)nsamples,nsamples/Samprate,Samprate);
  // For each block of input samples
  for(start=0; start < nsamples; start += Fftsize){

    if(!Flip_samples){
      for(i=0; i<Fftsize; i++)
	buffer[i] = samples[start+i].i + Q*samples[start+i].q;
    } else {
      for(i=0; i<Fftsize; i++)
	buffer[i] = samples[start+i].q + Q*samples[start+i].i;
    }
  
    carrier_freq = Shift;

    // Spin down
    cstep = 2*M_PI * carrier_freq/Samprate;  // carrier phase step per sample, radians
    cpstep = cos(cstep) - Q * sin(cstep); // Complex carrier step per sample
    carrier = 1;                          // Unity-amplitude carrier starts at 0 radians
    for(i=0;i<Fftsize;i++){
      buffer[i] *= carrier;         // Spin down to baseband
      carrier *= cpstep;                  // Increment carrier phase
    }
    for(i=0; i<Fftsize; i++){
      double s;

      s = creal(buffer[i]);
      fwrite(&s,sizeof(s),1,stdout);
      s = cimag(buffer[i]);
      fwrite(&s,sizeof(s),1,stdout);
    }
  }

 done:; // Clean up and exit
  if(samples != MAP_FAILED && munmap(samples,length) == -1){
    fprintf(stderr,"munmap(%p,%lld) failed: %s\n",samples,(long long)length,strerror(errno));
  }
  if(fd != -1)
    close(fd);

  if(buffer != NULL)
    fftw_free(buffer);

  exit(exitcode);
}
Exemple #22
0
/*
  run_all_fft

  This routine converts a wavepacket propagation from |f(x,y,t)> to |f(x,y,E)> , from a previously calculated cubic spline representation, using the fftw library routines

  main input: bcoefre, bcoefim. real and complex part spline matrices of |f(x,y,t)>
  main output: WPERe, WPEIm. real and complex part vectors of |f(x,y,E)>

 */
int run_all_fft(double *bcoefre,double *bcoefim, double *X, double *Y,double *xknot, double *yknot, double *tknot, int kx,double ti,double tf,double steptspl,int *np,int nf,int NTG, double width,double *WPERe,double *WPEIm, char *windtype, char *dim){
  int i,j,l,ll,k,nE;
  double x,y,E,ke,norm,stepxspl;
  fftw_complex *workin,*workout, *workin_b,*workout_b;
  fftw_plan p,p_b;
  double Ei,stepE;
  FILE *filin=fopen("fft_check_in.dat","w");
  FILE *filout=fopen("fft_check_out.dat","w");

  stepE = 2*M_PI/(NTG*steptspl);
  Ei = -NTG*stepE/(2.0E+0);
  nE =  NTG; //NTG/2
  printf("\nEnergy step: %E \n\n",stepE);

  //--- allocating work vectors
  workin = fftw_malloc(sizeof(fftw_complex) * NTG);
  workout = fftw_malloc(sizeof(fftw_complex) * NTG);
  workin_b = fftw_malloc(sizeof(fftw_complex) * NTG);
  workout_b = fftw_malloc(sizeof(fftw_complex) * NTG);


  for(i=0;i<np[1];i++){
    for(j=0;j<np[0];j++){
      //generates data set from spline coeff.
      gendata_Psic(workin,bcoefre,bcoefim,xknot,yknot,tknot,kx,np,nf,X[i],Y[j],ti,tf,steptspl,NTG,width,windtype,dim);
      gendata_Psic_bar(workin_b,bcoefre,bcoefim,xknot,yknot,tknot,kx,np,nf,X[i],Y[j],ti,tf,steptspl,NTG,width,windtype,dim);
      //centers t=0 at the zero frequency position of the fft input vector(first) due to periodicity requirement of fft
      center_fft(workin,NTG);
      center_fft(workin_b,NTG);

      //--- do forward fft
      // FFTW_BACKWARD -> sign in the exponent = 1.
      p = fftw_plan_dft_1d(NTG,workin,workout,FFTW_BACKWARD,FFTW_ESTIMATE);
      p_b = fftw_plan_dft_1d(NTG,workin_b,workout_b,FFTW_BACKWARD,FFTW_ESTIMATE);

      fftw_execute(p);  
      fftw_execute(p_b);  

      //shifts the fft result back to the center of the array
      center_fft(workout,NTG);
      center_fft(workout_b,NTG);

      //debug ---
      if(j==26){
	//center_fft(workin,NTG);
	fprintf(filin,"# %E %E\n",X[i],Y[j]);
	for(k=0;k<NTG;k++)fprintf(filin,"%E %E %E %E %E\n",-tf + k*steptspl,workin[k][0],workin[k][1],workin_b[k][0],workin_b[k][1]);
	fprintf(filout,"# %E %E\n",X[i],Y[j]);
	//for(k=0;k<NTG;k++)fprintf(filout,"%E %E %E\n",Ei + k*stepE,steptspl*workout[k][0],steptspl*workout[k][1]);
	for(k=0;k<NTG;k++)fprintf(filout,"%E %E %E %E %E\n",Ei + k*stepE,steptspl*workout[k][0],steptspl*workout[k][1],steptspl*workout_b[k][0],steptspl*workout_b[k][1]);
      }
      //----------
      
      //copies fft results to permanent array
      for(l=0;l<NTG;l++){ 
	//result of discrete FT must be multiplied by the time step (see num. recipes)
	ll = j + i*np[0] + l*np[1]*np[0];
	//printf("%d %d %d -> %d \n",j,i,k,ll);
	//fprintf(fil," %E %E %E\n",Ei + l*stepE,steptspl*workout[l][0],steptspl*workout[l][1]);
	//WPERe[ll] = (1.0/sqrt(2*M_PI))*steptspl*workout[l][0];
	//WPEIm[ll] = (1.0/sqrt(2*M_PI))*steptspl*workout[l][1];
	WPERe[ll] = steptspl*workout[l][0] + steptspl*workout_b[l][0];
	WPEIm[ll] = steptspl*workout[l][1] + steptspl*workout_b[l][1];
      }
      //fprintf(fil,"\n");
    }
  }
  //----------


  fftw_destroy_plan(p);
  fftw_destroy_plan(p_b);
  fftw_free(workin); 
  fftw_free(workout);
  fftw_free(workin_b); 
  fftw_free(workout_b);
  return 0;
}
void test03 ( void )

/******************************************************************************/
/*
  Purpose:

    TEST03: apply FFT to complex 2D data.

  Discussion:

    In this example, we generate NX=8 by NY=10 random complex values 
    stored as an NX by NY array of type FFTW_COMPLEX named "IN".

    We have FFTW3 compute the Fourier transform of this data named "OUT".

    We have FFTW3 compute the inverse Fourier transform of "OUT" to get
    "IN2", which should be the original input data, scaled by NX * NY.

    For a 2D complex NX by NY array used by FFTW, we need to access elements
    as follows:

      a[i*ny+j][0] is the real      part of A(I,J).
      a[i*ny+j][1] is the imaginary part of A(I,J)..

  Modified:

    05 November 2007

  Author:

    John Burkardt
*/
{
  int i;
  fftw_complex *in;
  fftw_complex *in2;
  int j;
  int nx = 8;
  int ny = 10;
  fftw_complex *out;
  fftw_plan plan_backward;
  fftw_plan plan_forward;
  unsigned int seed = 123456789;

  printf ( "\n" );
  printf ( "TEST03\n" );
  printf ( "  Demonstrate FFTW3 on a %d by %d array of complex data.\n",
    nx, ny );
  printf ( "\n" );
  printf ( "  Transform data to FFT coefficients.\n" );
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
  printf ( "  Compare recovered data to original data.\n" );
/*
  Create the input array.
*/
  in = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );

  srand ( seed );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      in[i*ny+j][0] = frand ( );
      in[i*ny+j][1] = frand ( );
    }
  }

  printf ( "\n" );
  printf ( "  Input Data:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      printf ( "  %4d  %4d  %12f  %12f\n", i, j, in[i*ny+j][0], in[i*ny+j][1] );
    }
  }
/*
  Create the output array.
*/
  out = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );

  plan_forward = fftw_plan_dft_2d ( nx, ny, in, out, FFTW_FORWARD, 
    FFTW_ESTIMATE );

  fftw_execute ( plan_forward );

  printf ( "\n" );
  printf ( "  Output FFT Coefficients:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      printf ( "  %4d  %4d  %12f  %12f\n", i, j, out[i*ny+j][0], out[i*ny+j][1] );
    }
  }
/*
  Recreate the input array.
*/
  in2 = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );

  plan_backward = fftw_plan_dft_2d ( nx, ny, out, in2, FFTW_BACKWARD, 
    FFTW_ESTIMATE );

  fftw_execute ( plan_backward );

  printf ( "\n" );
  printf ( "  Recovered input data divided by NX * NY:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      printf ( "  %4d  %4d  %12f  %12f\n",  i, j,
      in2[i*ny+j][0] / ( double ) ( nx * ny ),
      in2[i*ny+j][1] / ( double ) ( nx * ny ) );
    }
  }
/*
  Free up the allocated memory.
*/
  fftw_destroy_plan ( plan_forward );
  fftw_destroy_plan ( plan_backward );

  fftw_free ( in );
  fftw_free ( in2 );
  fftw_free ( out );

  return;
}
Exemple #24
0
int main(int argc, char **argv) {
  
  int c, i, mu, nu;
  int count        = 0;
  int filename_set = 0;
  int dims[4]      = {0,0,0,0};
  int l_LX_at, l_LXstart_at;
  int x0, x1, x2, x3, ix, iix;
  int sid;
  double *disc  = (double*)NULL;
  double *work = (double*)NULL;
  double q[4], fnorm;
  int verbose = 0;
  int do_gt   = 0;
  char filename[100], contype[200];
  double ratime, retime;
  double plaq;
  double spinor1[24], spinor2[24], U_[18];
  complex w, w1, *cp1, *cp2, *cp3;
  FILE *ofs;

  fftw_complex *in=(fftw_complex*)NULL;

#ifdef MPI
  fftwnd_mpi_plan plan_p, plan_m;
  int *status;
#else
  fftwnd_plan plan_p, plan_m;
#endif

#ifdef MPI
  MPI_Init(&argc, &argv);
#endif

  while ((c = getopt(argc, argv, "h?vgf:")) != -1) {
    switch (c) {
    case 'v':
      verbose = 1;
      break;
    case 'g':
      do_gt = 1;
      break;
    case 'f':
      strcpy(filename, optarg);
      filename_set=1;
      break;
    case 'h':
    case '?':
    default:
      usage();
      break;
    }
  }

  /* set the default values */
  if(filename_set==0) strcpy(filename, "cvc.input");
  fprintf(stdout, "# Reading input from file %s\n", filename);
  read_input_parser(filename);

  /* some checks on the input data */
  if((T_global == 0) || (LX==0) || (LY==0) || (LZ==0)) {
    if(g_proc_id==0) fprintf(stdout, "T and L's must be set\n");
    usage();
  }
  if(g_kappa == 0.) {
    if(g_proc_id==0) fprintf(stdout, "kappa should be > 0.n");
    usage();
  }

  /* initialize MPI parameters */
  mpi_init(argc, argv);
#ifdef MPI
  if((status = (int*)calloc(g_nproc, sizeof(int))) == (int*)NULL) {
    MPI_Abort(MPI_COMM_WORLD, 1);
    MPI_Finalize();
    exit(7);
  }
#endif

  /* initialize fftw */
  dims[0]=T_global; dims[1]=LX; dims[2]=LY; dims[3]=LZ;
#ifdef MPI
  plan_p = fftwnd_mpi_create_plan(g_cart_grid, 4, dims, FFTW_BACKWARD, FFTW_MEASURE);
  plan_m = fftwnd_mpi_create_plan(g_cart_grid, 4, dims, FFTW_FORWARD, FFTW_MEASURE);
  fftwnd_mpi_local_sizes(plan_p, &T, &Tstart, &l_LX_at, &l_LXstart_at, &FFTW_LOC_VOLUME);
#else
  plan_p = fftwnd_create_plan(4, dims, FFTW_BACKWARD, FFTW_MEASURE | FFTW_IN_PLACE);
  plan_m = fftwnd_create_plan(4, dims, FFTW_FORWARD,  FFTW_MEASURE | FFTW_IN_PLACE);
  T            = T_global;
  Tstart       = 0;
  l_LX_at      = LX;
  l_LXstart_at = 0;
  FFTW_LOC_VOLUME = T*LX*LY*LZ;
#endif
  fprintf(stdout, "# [%2d] fftw parameters:\n"\
                  "# [%2d] T            = %3d\n"\
		  "# [%2d] Tstart       = %3d\n"\
		  "# [%2d] l_LX_at      = %3d\n"\
		  "# [%2d] l_LXstart_at = %3d\n"\
		  "# [%2d] FFTW_LOC_VOLUME = %3d\n", 
		  g_cart_id, g_cart_id, T, g_cart_id, Tstart, g_cart_id, l_LX_at,
		  g_cart_id, l_LXstart_at, g_cart_id, FFTW_LOC_VOLUME);

#ifdef MPI
  if(T==0) {
    fprintf(stderr, "[%2d] local T is zero; exit\n", g_cart_id);
    MPI_Abort(MPI_COMM_WORLD, 1);
    MPI_Finalize();
    exit(2);
  }
#endif

  if(init_geometry() != 0) {
    fprintf(stderr, "ERROR from init_geometry\n");
#ifdef MPI
    MPI_Abort(MPI_COMM_WORLD, 1);
    MPI_Finalize();
#endif
    exit(1);
  }

  geometry();

  /* read the gauge field */
  alloc_gauge_field(&g_gauge_field, VOLUMEPLUSRAND);
  sprintf(filename, "%s.%.4d", gaugefilename_prefix, Nconf);
  if(g_cart_id==0) fprintf(stdout, "reading gauge field from file %s\n", filename);
  read_lime_gauge_field_doubleprec(filename);
#ifdef MPI
  xchange_gauge();
#endif

  /* measure the plaquette */
  plaquette(&plaq);
  if(g_cart_id==0) fprintf(stdout, "measured plaquette value: %25.16e\n", plaq);

  /* allocate memory for the spinor fields */
  no_fields = 3;
  g_spinor_field = (double**)calloc(no_fields, sizeof(double*));
  for(i=0; i<no_fields; i++) alloc_spinor_field(&g_spinor_field[i], VOLUMEPLUSRAND);

  /* allocate memory for the contractions */
  disc  = (double*)calloc( 8*VOLUME, sizeof(double));
  if( disc == (double*)NULL ) { 
    fprintf(stderr, "could not allocate memory for disc\n");
#  ifdef MPI
    MPI_Abort(MPI_COMM_WORLD, 1);
    MPI_Finalize();
#  endif
    exit(3);
  }
  for(ix=0; ix<8*VOLUME; ix++) disc[ix] = 0.;

  work  = (double*)calloc(48*VOLUME, sizeof(double));
  if( work == (double*)NULL ) { 
    fprintf(stderr, "could not allocate memory for work\n");
#  ifdef MPI
    MPI_Abort(MPI_COMM_WORLD, 1);
    MPI_Finalize();
#  endif
    exit(3);
  }

  /* prepare Fourier transformation arrays */
  in  = (fftw_complex*)malloc(FFTW_LOC_VOLUME*sizeof(fftw_complex));
  if(in==(fftw_complex*)NULL) {    
#ifdef MPI
    MPI_Abort(MPI_COMM_WORLD, 1);
    MPI_Finalize();
#endif
    exit(4);
  }

  /***********************************************
   * start loop on source id.s 
   ***********************************************/
  for(sid=g_sourceid; sid<=g_sourceid2; sid++) {

    /* read the new propagator */
#ifdef MPI
    ratime = MPI_Wtime();
#else
    ratime = (double)clock() / CLOCKS_PER_SEC;
#endif
    if(format==0) {
      sprintf(filename, "%s.%.4d.%.2d.inverted", filename_prefix, Nconf, sid);
      if(read_lime_spinor(g_spinor_field[2], filename, 0) != 0) break;
    }
    else if(format==1) {
      sprintf(filename, "%s.%.4d.%.5d.inverted", filename_prefix, Nconf, sid);
      if(read_cmi(g_spinor_field[2], filename) != 0) break;
    }
    xchange_field(g_spinor_field[2]);
#ifdef MPI
    retime = MPI_Wtime();
#else
    retime = (double)clock() / CLOCKS_PER_SEC;
#endif
    fprintf(stdout, "time to read prop.: %e seconds\n", retime-ratime);

    count++;

    /************************************************
     * calculate the source: apply Q_phi_tbc 
     ************************************************/
#ifdef MPI
    ratime = MPI_Wtime();
#else
    ratime = (double)clock() / CLOCKS_PER_SEC;
#endif
    Q_phi_tbc(g_spinor_field[0], g_spinor_field[2]);
    xchange_field(g_spinor_field[0]); 
#ifdef MPI
    retime = MPI_Wtime();
#else
    retime = (double)clock() / CLOCKS_PER_SEC;
#endif
    if(g_cart_id==0) fprintf(stdout, "time to calculate source: %e seconds\n", retime-ratime);

    /************************************************
     * HPE: apply BH3 
     ************************************************/
    BH3(g_spinor_field[1], g_spinor_field[2]);

    /* add new contractions to (existing) disc */
#  ifdef MPI
    ratime = MPI_Wtime();
#  else
    ratime = (double)clock() / CLOCKS_PER_SEC;
#  endif
    for(mu=0; mu<4; mu++) { /* loop on Lorentz index of the current */
      iix = _GWI(mu,0,VOLUME);
      for(ix=0; ix<VOLUME; ix++) {    /* loop on lattice sites */
        _cm_eq_cm_ti_co(U_, &g_gauge_field[_GGI(ix, mu)], &co_phase_up[mu]);

        /* first contribution */
        _fv_eq_cm_ti_fv(spinor1, U_, &g_spinor_field[1][_GSI(g_iup[ix][mu])]);
	_fv_eq_gamma_ti_fv(spinor2, mu, spinor1);
	_fv_mi_eq_fv(spinor2, spinor1);
	_co_eq_fv_dag_ti_fv(&w, &g_spinor_field[0][_GSI(ix)], spinor2);
	disc[iix  ] -= 0.5 * w.re;
	disc[iix+1] -= 0.5 * w.im;

        /* second contribution */
	_fv_eq_cm_dag_ti_fv(spinor1, U_, &g_spinor_field[1][_GSI(ix)]);
	_fv_eq_gamma_ti_fv(spinor2, mu, spinor1);
	_fv_pl_eq_fv(spinor2, spinor1);
	_co_eq_fv_dag_ti_fv(&w, &g_spinor_field[0][_GSI(g_iup[ix][mu])], spinor2);
	disc[iix  ] -= 0.5 * w.re;
	disc[iix+1] -= 0.5 * w.im;

	iix += 2;
      }  /* of ix */
    }    /* of mu */

#ifdef MPI
    retime = MPI_Wtime();
#else
    retime = (double)clock() / CLOCKS_PER_SEC;
#endif
    if(g_cart_id==0) fprintf(stdout, "[%2d] time to contract cvc: %e seconds\n", g_cart_id, retime-ratime);


    /************************************************
     * save results for count = multiple of Nsave 
     ************************************************/
    if(count%Nsave == 0) {
      if(g_cart_id == 0) fprintf(stdout, "save results for count = %d\n", count);

      /* save the result in position space */
      fnorm = 1. / ( (double)count * g_prop_normsqr );
      if(g_cart_id==0) fprintf(stdout, "# X-fnorm = %e\n", fnorm);
      for(mu=0; mu<4; mu++) {
        for(ix=0; ix<VOLUME; ix++) {
          work[_GWI(mu,ix,VOLUME)  ] = disc[_GWI(mu,ix,VOLUME)  ] * fnorm;
          work[_GWI(mu,ix,VOLUME)+1] = disc[_GWI(mu,ix,VOLUME)+1] * fnorm;
        }
      }
      sprintf(filename, "cvc_hpe_X.%.4d.%.4d", Nconf, count);
      sprintf(contype, "cvc_disc_hpe_loops_3_to_3_stoch_X");
      write_lime_contraction(work, filename, 64, 4, contype, Nconf, count);

#ifdef MPI
      ratime = MPI_Wtime();
#else
      ratime = (double)clock() / CLOCKS_PER_SEC;
#endif
      /* Fourier transform data, copy to work */
      for(mu=0; mu<4; mu++) {
        memcpy((void*)in, (void*)(work+_GWI(mu,0,VOLUME)), 2*VOLUME*sizeof(double));
#ifdef MPI
        fftwnd_mpi(plan_m, 1, in, NULL, FFTW_NORMAL_ORDER);
#else
        fftwnd_one(plan_m, in, NULL);
#endif
        memcpy((void*)(work+_GWI(4+mu,0,VOLUME)), (void*)in, 2*VOLUME*sizeof(double));

        memcpy((void*)in, (void*)(work+_GWI(mu,0,VOLUME)), 2*VOLUME*sizeof(double));
#ifdef MPI
        fftwnd_mpi(plan_p, 1, in, NULL, FFTW_NORMAL_ORDER);
#else
        fftwnd_one(plan_p, in, NULL);
#endif
        memcpy((void*)(work+_GWI(mu,0,VOLUME)), (void*)in, 2*VOLUME*sizeof(double));
      }  /* of mu =0 ,..., 3*/

      fnorm = 1. / (double)(T_global*LX*LY*LZ);
      if(g_cart_id==0) fprintf(stdout, "# P-fnorm = %e\n", fnorm);
      for(mu=0; mu<4; mu++) {
      for(nu=0; nu<4; nu++) {
        cp1 = (complex*)(work+_GWI(mu,0,VOLUME));
        cp2 = (complex*)(work+_GWI(4+nu,0,VOLUME));
        cp3 = (complex*)(work+_GWI(8+4*mu+nu,0,VOLUME));
     
        for(x0=0; x0<T; x0++) {
	  q[0] = (double)(x0+Tstart) / (double)T_global;
        for(x1=0; x1<LX; x1++) {
	  q[1] = (double)(x1) / (double)LX;
        for(x2=0; x2<LY; x2++) {
	  q[2] = (double)(x2) / (double)LY;
        for(x3=0; x3<LZ; x3++) {
	  q[3] = (double)(x3) / (double)LZ;
	  ix = g_ipt[x0][x1][x2][x3];
	  w.re = cos( M_PI * (q[mu]-q[nu]) );
	  w.im = sin( M_PI * (q[mu]-q[nu]) );
	  _co_eq_co_ti_co(&w1, cp1, cp2);
	  _co_eq_co_ti_co(cp3, &w1, &w);
	  _co_ti_eq_re(cp3, fnorm);
	  cp1++; cp2++; cp3++;
	}}}}
      }}
  
      /* save the result in momentum space */
      sprintf(filename, "cvc_hpe_P.%.4d.%.4d", Nconf, count);
      sprintf(contype, "cvc_disc_hpe_loops_3_to_3_stoch_P");
      write_lime_contraction(work+_GWI(8,0,VOLUME), filename, 64, 16, contype, Nconf, count);

#ifdef MPI
      retime = MPI_Wtime();
#else
      retime = (double)clock() / CLOCKS_PER_SEC;
#endif
      if(g_cart_id==0) fprintf(stdout, "time to save cvc results: %e seconds\n", retime-ratime);

    }  /* of count % Nsave == 0 */
  }  /* of loop on sid */

  /***********************************************
   * free the allocated memory, finalize 
   ***********************************************/
  free(g_gauge_field);
  for(i=0; i<no_fields; i++) free(g_spinor_field[i]);
  free(g_spinor_field);
  free_geometry();
  fftw_free(in);
  free(disc);

  free(work);

#ifdef MPI
  fftwnd_mpi_destroy_plan(plan_p);
  fftwnd_mpi_destroy_plan(plan_m);
  free(status);
  MPI_Finalize();
#else
  fftwnd_destroy_plan(plan_p);
  fftwnd_destroy_plan(plan_m);
#endif

  return(0);

}
void test01 ( void )

/******************************************************************************/
/*
  Purpose:

    TEST01: apply FFT to complex 1D data.

  Discussion:

    In this example, we generate N=100 random complex values stored as
    a vector of type FFTW_COMPLEX named "IN".

    We have FFTW3 compute the Fourier transform of this data named "OUT".

    We have FFTW3 compute the inverse Fourier transform of "OUT" to get
    "IN2", which should be the original input data, scaled by N.

  Modified:

    04 November 2007

  Author:

    John Burkardt
*/
{
  int i;
  fftw_complex *in;
  fftw_complex *in2;
  int n = 100;
  fftw_complex *out;
  fftw_plan plan_backward;
  fftw_plan plan_forward;
  unsigned int seed = 123456789;

  printf ( "\n" );
  printf ( "TEST01\n" );
  printf ( "  Demonstrate FFTW3 on a single vector of complex data.\n" );
  printf ( "\n" );
  printf ( "  Transform data to FFT coefficients.\n" );
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
  printf ( "  Compare recovered data to original data.\n" );
/*
  Create the input array.
*/
  in = fftw_malloc ( sizeof ( fftw_complex ) * n );

  srand ( seed );

  for ( i = 0; i < n; i++ )
  {
    in[i][0] = frand ( );
    in[i][1] = frand ( );
  }

  printf ( "\n" );
  printf ( "  Input Data:\n" );
  printf ( "\n" );

  for ( i = 0; i < n; i++ )
  {
    printf ( "  %3d  %12f  %12f\n", i, in[i][0], in[i][1] );
  }
/*
  Create the output array.
*/
  out = fftw_malloc ( sizeof ( fftw_complex ) * n );

  plan_forward = fftw_plan_dft_1d ( n, in, out, FFTW_FORWARD, FFTW_ESTIMATE );

  fftw_execute ( plan_forward );

  printf ( "\n" );
  printf ( "  Output FFT Coefficients:\n" );
  printf ( "\n" );

  for ( i = 0; i < n; i++ )
  {
    printf ( "  %3d  %12f  %12f\n", i, out[i][0], out[i][1] );
  }
/*
  Recreate the input array.
*/
  in2 = fftw_malloc ( sizeof ( fftw_complex ) * n );

  plan_backward = fftw_plan_dft_1d ( n, out, in2, FFTW_BACKWARD, FFTW_ESTIMATE );

  fftw_execute ( plan_backward );

  printf ( "\n" );
  printf ( "  Recovered input data:\n" );
  printf ( "\n" );

  for ( i = 0; i < n; i++ )
  {
    printf ( "  %3d  %12f  %12f\n", i, in2[i][0], in2[i][1] );
  }

  printf ( "\n" );
  printf ( "  Recovered input data divided by N:\n" );
  printf ( "\n" );

  for ( i = 0; i < n; i++ )
  {
    printf ( "  %3d  %12f  %12f\n", i, 
      in2[i][0] / ( double ) ( n ), in2[i][1] / ( double ) ( n ) );
  }
/*
  Free up the allocated memory.
*/
  fftw_destroy_plan ( plan_forward );
  fftw_destroy_plan ( plan_backward );

  fftw_free ( in );
  fftw_free ( in2 );
  fftw_free ( out );

  return;
}
void calc_envelope(float ** datatrace, float ** envelope, int ns, int ntr){

	/* declaration of variables */
	int i,j, nfreq, npad, k;
	float xr, yr, x, y, dump, a, *h;
	double npadd;
		
	/* declaration of variables for FFTW3*/
	fftw_complex *in, *out;
	fftw_plan p1, p2;

	/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
	/* calculation of the Hilbert transform */
	/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */


	/* calculation of the FFT */
	npad = (int)(pow(2.0, ceil(log((double)(ns))/log(2.0))+2.0) );  /* ns -> npad for usage in FFT*/
        npadd = (double)npad;
	in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * npad);
	out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * npad);
	
	/* calculation of the vector h */
	     h = vector(1,npad);
	     if ((2*(npad/2))==npad) {
		/* npad is even */
		h[1]=1.0;
		h[npad/2+1]=1.0;
		for (i=2;i<=(npad/2);i++) {
	   	     h[i] = 2.0; }
	     } else {
		/* npad is odd */
		h[1]=1.0;
		for (i=2;i<=((npad+1)/2);i++) {
	   	     h[i]=2.0;}
	     }
	     
	for(k=1;k<=ntr;k++){
						
	     for (j=0;j<ns;j++){
	     in[j][0]=datatrace[k][j+1];
	     in[j][1]=0.0;
		     }
	     for (j=ns;j<npad;j++){
	     in[j][0]=0.0;
	     in[j][1]=0.0;
		     }
	     /* FFT */
	     p1 = fftw_plan_dft_1d(npad, in, out, 1, FFTW_ESTIMATE);
	     fftw_execute(p1);
	     fftw_destroy_plan(p1);		    

	     /* elementwise multiplication of FFT and h */
	     for (i=0;i<npad;i++){
		out[i][0] *= h[i+1];
		out[i][1] *= h[i+1];
	     }


	     /* inverse FFT */
	     p2 = fftw_plan_dft_1d(npad, out, in, -1, FFTW_ESTIMATE);
	     fftw_execute(p2);
             fftw_destroy_plan(p2);

	     /* %%%%%%%%%%%%%%%%%%%%%%% */
	     /* calculation of envelope */
	     /* %%%%%%%%%%%%%%%%%%%%%%% */
	     for (j=0;j<ns;j++){
	     	envelope[k][j+1]=(1.0/npadd)*sqrt(in[j][0]*in[j][0]+in[j][1]*in[j][1]);
	     }
	     
	}

	fftw_free(in);
	fftw_free(out);
	free_vector(h,1,npad);
	
}
Exemple #27
0
void rfftwnd_complex_to_real(fftwnd_plan p, int howmany,
			     fftw_complex *in, int istride, int idist,
			     fftw_real *out, int ostride, int odist)
{
     fftw_complex *work = p->work;
     int rank = p->rank;
     int free_work = 0;

     if (p->dir != FFTW_COMPLEX_TO_REAL)
	  fftw_die("rfftwnd_complex_to_real with real-to-complex plan");

#ifdef FFTW_DEBUG
     if (p->rank > 0 && (p->plans[0]->flags & FFTW_THREADSAFE)
	 && p->nwork && p->work)
	  fftw_die("bug with FFTW_THREADSAFE flag");
#endif

     if (p->is_in_place) {
	  ostride = istride;
	  odist = idist;
	  odist = (idist == 1 && idist < istride) ? 1 : (idist * 2);  /* ugh */
	  out = (fftw_real *) in;
	  if (howmany > 1 && istride > idist && rank > 0) {
	       int new_nwork = p->n[rank - 1] * howmany;
	       if (new_nwork > p->nwork) {
		    work = (fftw_complex *)
			fftw_malloc(sizeof(fftw_complex) * new_nwork);
		    if (!work)
			 fftw_die("error allocating work array");
		    free_work = 1;
	       }
	  }
     }
     if (p->nwork && !work) {
	  work = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * p->nwork);
	  free_work = 1;
     }
     switch (rank) {
	 case 0:
	      break;
	 case 1:
	      if (p->is_in_place && howmany > 1 && istride > idist)
		   rfftw_c2real_overlap_aux(p->plans[0], howmany,
					    in, istride, idist,
					    out, ostride, odist,
					    (fftw_real *) work);
	      else
		   rfftw_c2real_aux(p->plans[0], howmany,
				    in, istride, idist,
				    out, ostride, odist,
				    (fftw_real *) work);
	      break;
	 default:		/* rank >= 2 */
	      {
		   if (howmany > 1 && ostride > odist)
			rfftwnd_c2real_aux_howmany(p, 0, howmany,
						   in, istride, idist,
						   out, ostride, odist,
						   work);
		   else {
			int i;

			for (i = 0; i < howmany; ++i)
			     rfftwnd_c2real_aux(p, 0,
						in + i * idist, istride,
						out + i * odist, ostride,
						(fftw_real *) work);
		   }
	      }
     }

     if (free_work)
	  fftw_free(work);
}
void test_in_place(int n, int istride,
		   int howmany, fftw_direction dir,
		   fftw_plan validated_plan, int specific)
{
     fftw_complex *in2, *out2;
     fftw_real *in1, *out1, *out3;
     fftw_plan plan;
     int i, j;
     int ostride = istride;
     int flags = measure_flag | wisdom_flag | FFTW_IN_PLACE;

     if (coinflip())
	  flags |= FFTW_THREADSAFE;

     in1 = (fftw_real *) fftw_malloc(istride * n * sizeof(fftw_real) * howmany);
     in2 = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     out1 = in1;
     out2 = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     out3 = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));

     if (!specific)
	  plan = rfftw_create_plan(n, dir, flags);
     else
	  plan = rfftw_create_plan_specific(n, dir, flags,
					    in1, istride, out1, ostride);
     CHECK(plan != NULL, "can't create plan");

     /* generate random inputs */
     fill_random(in1, n, istride);
     for (j = 1; j < howmany; ++j)
	  for (i = 0; i < n; ++i)
	       in1[(j * n + i) * istride] = in1[i * istride];

     /* copy random inputs to complex array for comparison with fftw: */
     if (dir == FFTW_REAL_TO_COMPLEX)
	  for (i = 0; i < n; ++i) {
	       c_re(in2[i]) = in1[i * istride];
	       c_im(in2[i]) = 0.0;
     } else {
	  int n2 = (n + 1) / 2;
	  c_re(in2[0]) = in1[0];
	  c_im(in2[0]) = 0.0;
	  for (i = 1; i < n2; ++i) {
	       c_re(in2[i]) = in1[i * istride];
	       c_im(in2[i]) = in1[(n - i) * istride];
	  }
	  if (n2 * 2 == n) {
	       c_re(in2[n2]) = in1[n2 * istride];
	       c_im(in2[n2]) = 0.0;
	       ++i;
	  }
	  for (; i < n; ++i) {
	       c_re(in2[i]) = c_re(in2[n - i]);
	       c_im(in2[i]) = -c_im(in2[n - i]);
	  }
     }

     /* 
      * fill in other positions of the array, to make sure that
      * rfftw doesn't overwrite them 
      */
     for (j = 1; j < istride; ++j)
	  for (i = 0; i < n * howmany; ++i)
	       in1[i * istride + j] = i * istride + j;

     WHEN_VERBOSE(2, rfftw_print_plan(plan));

     /* fft-ize */
     if (howmany != 1 || istride != 1 || coinflip())
	  rfftw(plan, howmany, in1, istride, n * istride, 0, 0, 0);
     else
	  rfftw_one(plan, in1, NULL);

     rfftw_destroy_plan(plan);

     /* check for overwriting */
     for (j = 1; j < ostride; ++j)
	  for (i = 0; i < n * howmany; ++i)
	       CHECK(out1[i * ostride + j] == i * ostride + j,
		     "output has been overwritten");

     fftw(validated_plan, 1, in2, 1, n, out2, 1, n);

     if (dir == FFTW_REAL_TO_COMPLEX) {
	  int n2 = (n + 1) / 2;
	  out3[0] = c_re(out2[0]);
	  for (i = 1; i < n2; ++i) {
	       out3[i] = c_re(out2[i]);
	       out3[n - i] = c_im(out2[i]);
	  }
	  if (n2 * 2 == n)
	       out3[n2] = c_re(out2[n2]);
     } else {
	  for (i = 0; i < n; ++i)
	       out3[i] = c_re(out2[i]);
     }

     for (j = 0; j < howmany; ++j)
	  CHECK(compute_error(out1 + j * n * ostride, ostride, out3, 1, n)
		< TOLERANCE,
		"test_in_place: wrong answer");
     WHEN_VERBOSE(2, printf("OK\n"));

     fftw_free(in1);
     fftw_free(in2);
     fftw_free(out2);
     fftw_free(out3);
}
Exemple #29
0
//==============================================================================
//cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
//==============================================================================
void RealStateSlab::destroy() {
  if(planeArr != NULL) {fftw_free(planeArr); planeArr=NULL; planeArrR = NULL;}
}
Exemple #30
0
void ath_2d_fft_free(ath_fft_data *data)
{
  if (data != NULL) fftw_free((void*)data);

  return;
}