Ejemplo n.º 1
0
/* Here's the big banana
   Convolves two functions defined on the 2-sphere.
   Uses seminaive algorithms for spherical harmonic transforms

   size = 2*bw

   Inputs:

   rdata, idata - (size * size) arrays containing real and
                  imaginary parts of sampled function.
   rfilter, ifilter - (size * size) arrays containing real and
                      imaginary parts of sampled filter function.
   rres, ires - (size * size) arrays containing real and
                  imaginary parts of result function.


   Suggestion - if you want to do multiple convolutions,
   don't keep allocating and freeing space with every call,
   or keep recomputing the spharmonic_pml tables.
   Allocate workspace once before you call this function, then
   just set up pointers as first step of this procedure rather
   than mallocing.  And do the same with the FST, FZT, and InvFST functions.

   ASSUMPTIONS:
   1. data is strictly REAL
   2. will do semi-naive algorithm for ALL orders -> change the cutoff
      value if you want it to be different

   Memory requirements for Conv2Sphere

   Need space for spharmonic tables and local workspace and
   scratchpad space for FST_semi

   Let legendreSize = Reduced_Naive_TableSize(bw,cutoff) +
                      Reduced_SpharmonicTableSize(bw,cutoff)

   Then the workspace needs to be this large:

   2 * legendreSize  +
   8 * (bw*bw)  + 10*bw +
   4 * (bw*bw) + 2*bw

   for a total of

   2 * legendreSize  +
   12 * (bw*bw) + 12*bw ;
   


*/
void Conv2Sphere_semi_memo(double *rdata, double *idata, 
			   double *rfilter, double *ifilter, 
			   double *rres, double *ires, 
			   int bw,
			   double *workspace)
{
  int size, spharmonic_bound ;
  int legendreSize, cutoff ;
  double *frres, *fires, *filtrres, *filtires, *trres, *tires;
  double **spharmonic_pml_table, **transpose_spharmonic_pml_table;
  double *spharmonic_result_space, *transpose_spharmonic_result_space;
  double *scratchpad;

  /* fftw */
  int rank, howmany_rank ;
  fftw_iodim dims[1], howmany_dims[1];

  /* forward transform stuff */
  fftw_plan dctPlan, fftPlan ;
  double *weights ;

  /* inverse transform stuff */
  fftw_plan idctPlan, ifftPlan ;

  size =2*bw ;
  cutoff = bw ;
  legendreSize = Reduced_Naive_TableSize(bw,cutoff) +
    Reduced_SpharmonicTableSize(bw,cutoff) ;

  /* assign space */

  spharmonic_bound = legendreSize ;

  spharmonic_result_space = workspace;          /* needs legendreSize */

  transpose_spharmonic_result_space =
    spharmonic_result_space +  legendreSize ;   /* needs legendreSize */

  frres = transpose_spharmonic_result_space + 
    legendreSize ;                              /* needs (bw*bw) */
  fires = frres + (bw*bw);                      /* needs (bw*bw) */
  trres = fires + (bw*bw);                      /* needs (bw*bw) */
  tires = trres + (bw*bw);                      /* needs (bw*bw) */
  filtrres = tires + (bw*bw);                   /* needs bw */
  filtires = filtrres + bw;                     /* needs bw */
  scratchpad = filtires + bw;                   /* needs (8*bw^2)+(10*bw) */

  /* allocate space, and compute, the weights for this bandwidth */
  weights = (double *) malloc(sizeof(double) * 4 * bw);
  makeweights( bw, weights );

  /* make the fftw plans */

  /* make DCT plans -> note that I will be using the GURU
     interface to execute these plans within the routines*/

  /* forward DCT */
  dctPlan = fftw_plan_r2r_1d( 2*bw, weights, rdata,
			      FFTW_REDFT10, FFTW_ESTIMATE ) ;
      
  /* inverse DCT */
  idctPlan = fftw_plan_r2r_1d( 2*bw, weights, rdata,
			       FFTW_REDFT01, FFTW_ESTIMATE );
  
  /*
    fft "preamble" ;
    note that this plan places the output in a transposed array
  */
  rank = 1 ;
  dims[0].n = 2*bw ;
  dims[0].is = 1 ;
  dims[0].os = 2*bw ;
  howmany_rank = 1 ;
  howmany_dims[0].n = 2*bw ;
  howmany_dims[0].is = 2*bw ;
  howmany_dims[0].os = 1 ;
 
  /* forward fft */
  fftPlan = fftw_plan_guru_split_dft( rank, dims,
				      howmany_rank, howmany_dims,
				      rdata, idata,
				      workspace, workspace+(4*bw*bw),
				      FFTW_ESTIMATE );

  /*
    now plan for inverse fft - note that this plans assumes
    that I'm working with a transposed array, e.g. the inputs
    for a length 2*bw transform are placed every 2*bw apart,
    the output will be consecutive entries in the array
  */
  rank = 1 ;
  dims[0].n = 2*bw ;
  dims[0].is = 2*bw ;
  dims[0].os = 1 ;
  howmany_rank = 1 ;
  howmany_dims[0].n = 2*bw ;
  howmany_dims[0].is = 1 ;
  howmany_dims[0].os = 2*bw ;

  /* inverse fft */
  ifftPlan = fftw_plan_guru_split_dft( rank, dims,
				       howmany_rank, howmany_dims,
				       rdata, idata,
				       workspace, workspace+(4*bw*bw),
				       FFTW_ESTIMATE );


  /* precompute the associated Legendre fcts */
  spharmonic_pml_table = 
    Spharmonic_Pml_Table(bw,
			 spharmonic_result_space,
			 scratchpad);

  transpose_spharmonic_pml_table = 
    Transpose_Spharmonic_Pml_Table(spharmonic_pml_table, 
				   bw,
				   transpose_spharmonic_result_space,
				   scratchpad);
  FST_semi_memo(rdata, idata, 
		frres, fires, 
		bw, 
		spharmonic_pml_table,
		scratchpad,
		1,
		bw,
		&dctPlan,
		&fftPlan,
		weights );

  FZT_semi_memo(rfilter, ifilter, 
		filtrres, filtires, 
		bw, 
		spharmonic_pml_table[0],
		scratchpad,
		1,
		&dctPlan,
		weights );

  TransMult(frres, fires, filtrres, filtires, trres, tires, bw);

  InvFST_semi_memo(trres, tires, 
		   rres, ires, 
		   bw,
		   transpose_spharmonic_pml_table,
		   scratchpad,
		   1,
		   bw,
		   &idctPlan,
		   &ifftPlan );

  free( weights ) ;

  /***
      have to free the memory that was allocated in
      Spharmonic_Pml_Table() and
      Transpose_Spharmonic_Pml_Table()
  ***/

  free(spharmonic_pml_table);
  free(transpose_spharmonic_pml_table);

  /* destroy plans */
  fftw_destroy_plan( ifftPlan ) ;
  fftw_destroy_plan( fftPlan ) ;
  fftw_destroy_plan( idctPlan ) ;
  fftw_destroy_plan( dctPlan ) ;
}
Ejemplo n.º 2
0
void s2Rotate( int bw,
	       double *sigIn,
	       double *sigOut,
	       double alpha, double beta, double gamma,
	       int isReal )
{
  int i, splat ;
  double *scratch ;
  double *tmpInR, *tmpInI, *tmpOutR, *tmpOutI;
  double *seminaive_naive_tablespace;
  double *trans_seminaive_naive_tablespace;
  double **seminaive_naive_table ;
  double **trans_seminaive_naive_table;

  tmpInR = (double *) malloc(sizeof(double)*(4*bw*bw));
  tmpInI = (double *) malloc(sizeof(double)*(4*bw*bw));
  tmpOutR = (double *) malloc(sizeof(double)*(4*bw*bw));
  tmpOutI = (double *) malloc(sizeof(double)*(4*bw*bw));

  scratch = (double *) malloc(sizeof(double)*((14*bw*bw) + (48 * bw)));

  splat = 0 ;

  seminaive_naive_tablespace =
    (double *) malloc(sizeof(double) *
		      (Reduced_Naive_TableSize(bw,splat) +
		       Reduced_SpharmonicTableSize(bw,splat)));
  
  trans_seminaive_naive_tablespace =
    (double *) malloc(sizeof(double) *
		      (Reduced_Naive_TableSize(bw,splat) +
		       Reduced_SpharmonicTableSize(bw,splat)));
  
  /****
       At this point, check to see if all the memory has been
       allocated. If it has not, there's no point in going further.
  ****/
  
  if ( (scratch == NULL) || 
       (tmpInR == NULL) || (tmpInI == NULL) ||
       (tmpOutR == NULL) || (tmpOutI == NULL) ||
       (seminaive_naive_tablespace == NULL) ||
       (trans_seminaive_naive_tablespace == NULL) )
    {
      perror("Error in allocating memory");
      exit( 1 ) ;
    }

  /* precompute for S^2 transform */
  seminaive_naive_table = SemiNaive_Naive_Pml_Table(bw, splat,
						    seminaive_naive_tablespace,
						    scratch);

  trans_seminaive_naive_table =
    Transpose_SemiNaive_Naive_Pml_Table(seminaive_naive_table,
					bw, splat,
					trans_seminaive_naive_tablespace,
					scratch);

  if ( isReal )
    {
      for(i = 0 ; i < 4*bw*bw ; i ++ )
	{
	  tmpInR[i] = sigIn[i];
	  tmpInI[i] = 0. ;
	}
    }
  else
    {
      for(i = 0 ; i < 4*bw*bw ; i ++ )
	{
	  tmpInR[i] = sigIn[2*i];
	  tmpInI[i] = sigIn[2*i+1];
	}
    }
  
  /* now rotate */
  rotateFct( bw, bw, bw - 1,
	     tmpInR, tmpInI,
	     tmpOutR, tmpOutI,
	     alpha, beta, gamma,
	     scratch,
	     seminaive_naive_table,
	     trans_seminaive_naive_table ) ;
  if ( 0 )
    for(i=0;i<5;i++)
      printf("%d\t%f\t%f\n",i,tmpOutR[i],tmpOutI[i]);

  if ( isReal )
    {
      for(i = 0 ; i < 4*bw*bw ; i ++ )
	{
	  sigOut[i] = tmpOutR[i];
	}
    }
  else
    {
      for(i = 0 ; i < 4*bw*bw ; i ++ )
	{
	  sigOut[2*i] = tmpOutR[i];
	  sigOut[2*i+1] = tmpOutI[i];
	}
    }

  /* clean up */ 
  free(trans_seminaive_naive_table);
  free(seminaive_naive_table);
  free(trans_seminaive_naive_tablespace); 
  free(seminaive_naive_tablespace); 
  free(scratch);
  free(tmpOutI);
  free(tmpOutR);
  free(tmpInI);
  free(tmpInR);


}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
  FILE *fp ;
  int i ;
  int bwIn, bwOut, degOut ;
  double alpha, beta, gamma ;
  double *sigInR, *sigInI, *sigOutR, *sigOutI ;
  double *scratch ;
  double tstart, tstop;
  double *seminaive_naive_tablespace, *trans_seminaive_naive_tablespace2;
  double *seminaive_naive_tablespace2 ;
  double **seminaive_naive_table2,**seminaive_naive_table ;
  double **trans_seminaive_naive_table2;
  int splat ;

  if (argc < 9)
    {
      fprintf(stdout, "Usage: test_s2_rotate bwIn bwOut degOut ");
      fprintf(stdout, "alpha beta gamma ");
      fprintf(stdout, "input_filename output_filename\n");
      exit(0);
    }


  bwIn = atoi( argv[ 1 ] );
  bwOut = atoi( argv[ 2 ] );
  degOut = atoi( argv[ 3 ] );
  alpha = (double) atof( argv[ 4 ] );
  beta = (double) atof( argv[ 5 ] );
  gamma = (double) atof( argv[ 6 ] );

  sigInR = (double *) malloc(sizeof(double)*(4*bwIn*bwIn));
  sigInI = (double *) malloc(sizeof(double)*(4*bwIn*bwIn));
  sigOutR = (double *) malloc(sizeof(double)*(4*bwOut*bwOut));
  sigOutI = (double *) malloc(sizeof(double)*(4*bwOut*bwOut));

  if ( bwOut > bwIn )
    scratch = (double *) malloc(sizeof(double)*((14*bwOut*bwOut) + (48 * bwOut)));
  else
    scratch = (double *) malloc(sizeof(double)*((14*bwIn*bwIn) + (48 * bwIn)));

  splat = 0 ;

  seminaive_naive_tablespace =
    (double *) malloc(sizeof(double) *
		      (Reduced_Naive_TableSize(bwIn,bwIn) +
		       Reduced_SpharmonicTableSize(bwIn,bwIn)));

  trans_seminaive_naive_tablespace2 =
    (double *) malloc(sizeof(double) *
		      (Reduced_Naive_TableSize(bwOut,bwOut) +
		       Reduced_SpharmonicTableSize(bwOut,bwOut)));

  seminaive_naive_tablespace2 =
    (double *) malloc(sizeof(double) *
		      (Reduced_Naive_TableSize(bwOut,bwOut) +
		       Reduced_SpharmonicTableSize(bwOut,bwOut)));

  /****
       At this point, check to see if all the memory has been
       allocated. If it has not, there's no point in going further.
  ****/

  if ( (scratch == NULL) || 
       (sigInR == NULL ) || (sigInI == NULL ) ||
       (sigOutR == NULL ) || (sigOutI == NULL ) ||
       (seminaive_naive_tablespace == NULL) ||
       (trans_seminaive_naive_tablespace2 == NULL) )
    {
      perror("Error in allocating memory");
      exit( 1 ) ;
    }
  
  fprintf(stdout,"Generating seminaive_naive tables...\n");
  seminaive_naive_table = SemiNaive_Naive_Pml_Table(bwIn, bwIn,
						    seminaive_naive_tablespace,
						    scratch);

  fprintf(stdout,"Generating seminaive_naive tables...\n");
  seminaive_naive_table2 = SemiNaive_Naive_Pml_Table(bwOut, bwOut,
						    seminaive_naive_tablespace2,
						    scratch);

  fprintf(stdout,"Generating trans_seminaive_naive tables...\n");
  trans_seminaive_naive_table2 =
    Transpose_SemiNaive_Naive_Pml_Table(seminaive_naive_table2,
					bwOut, bwOut,
					trans_seminaive_naive_tablespace2,
					scratch);

  fprintf(stdout,"reading in signal ...\n");

  /* read in signal */
  fp = fopen(argv[7], "r");
  for ( i = 0 ; i < (4*bwIn*bwIn) ; i ++ )
    {
      fscanf(fp,"%lf",sigInR+i);
      fscanf(fp,"%lf",sigInI+i);
    }
  fclose( fp ) ;

  fprintf(stdout,"about to rotate ...\n");
  tstart = csecond();

  rotateFct( bwIn, bwOut, degOut,
	     sigInR, sigInI,
	     sigOutR, sigOutI,
	     alpha, beta, gamma,
	     scratch,
	     seminaive_naive_table,
	     trans_seminaive_naive_table2 ) ;

  tstop = csecond();
  fprintf(stdout,"finished rotating ...\n");
  fprintf(stdout,"rotation time \t = %.4e\n", tstop - tstart);

  /* write out rotated signal */
  fp = fopen(argv[8], "w");
  for ( i = 0 ; i < (4*bwOut*bwOut) ; i ++ )
    {
      fprintf(fp,"%.15f\n%.15f\n",sigOutR[i],sigOutI[i]);
    }
  fclose( fp ) ;
 
  fprintf(stdout,"finished writing ...\n");
 
  free(trans_seminaive_naive_table2);
  free(seminaive_naive_table2);
  free(seminaive_naive_table);
  free(seminaive_naive_tablespace2);
  free(trans_seminaive_naive_tablespace2);
  free(seminaive_naive_tablespace);
 
  free(scratch);
  free(sigOutI);
  free(sigOutR);
  free(sigInI);
  free(sigInR);
 
  return 0 ;
 
}