Exemplo n.º 1
0
void so3CombineCoef_fftw( int bwIn,
			  int bwOut,
			  int degLim,
			  REAL *sigCoefR, REAL *sigCoefI,
			  REAL *patCoefR, REAL *patCoefI,
			  fftw_complex *so3Coef )
{
  int l, m1, m2 ;
  int fudge, dummy ;
  REAL tmpSigCoefR, tmpSigCoefI ;
  REAL tmpPatCoefR, tmpPatCoefI ;

  /* for sanity, set all so3coefs to 0 */
  memset( so3Coef, 0, sizeof(fftw_complex) * totalCoeffs_so3( bwOut ) );

  for( l = 0 ; l <= degLim ; l ++ )
    {
      for( m1 = -l ; m1 <= l ; m1 ++ )
	{
	  /* grab signal coefficient, at this degree and order */
	  dummy = seanindex(-m1, l, bwIn) ;
	  tmpSigCoefR = sigCoefR[ dummy ];
	  tmpSigCoefI = sigCoefI[ dummy ];

	  /* need to reset the -1 fudge factor */
	  if ( (m1 + l) % 2 )
	    fudge = -1 ;
	  else
	    fudge = 1 ;

	  for( m2 = -l ; m2 <= l ; m2 ++ )
	    {
	      dummy = seanindex( -m2, l, bwIn );

	      /*
		first take the CONJUGATE of the pattern coef
		and multiply it by the fudge factor
	      */
	      tmpPatCoefR = fudge *   patCoefR[ dummy ];
	      tmpPatCoefI = fudge * (-patCoefI[ dummy ]);

	      /* now multiply the signal coef by the pattern coef,
		 and save it in the so3 coefficient array */
	      
	      dummy = so3CoefLoc( m1, m2, l, bwOut ) ;

	      so3Coef[ dummy ][0] =
		tmpSigCoefR*tmpPatCoefR -
		tmpSigCoefI*tmpPatCoefI ;

	      so3Coef[ dummy ][1] =
		tmpSigCoefR*tmpPatCoefI +
		tmpSigCoefI*tmpPatCoefR ;

	      /* multiply fudge factor by -1 */
	      fudge *= -1 ;
	    }
	}
    }
}
Exemplo n.º 2
0
Data::Data(const Config & configSettings)
{
    bw = configSettings.Read<int>("Band_width");
    m[0] = configSettings.Read<int>("Grid_Size_x");
    if(DIM==2){
        m[1] = configSettings.Read<int>("Grid_Size_y");
    }

    n_coeff = totalCoeffs_so3(bw);
    n = bw*2;
    n3 = n*n*n;
    md = 1;
    for(int i = 0; i<DIM; i++)
        md *= m[i];
    realdata = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*n3*md);
    spectdata = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*n_coeff*md);
}
Exemplo n.º 3
0
void so3CombineCoef( int bwIn,
		     int bwOut,
		     int degLim,
		     double *sigCoefR, double *sigCoefI,
		     double *patCoefR, double *patCoefI,
		     double *so3CoefR, double *so3CoefI )
{
  int l, m1, m2 ;
  int fudge, dummy ;
  double tmpSigCoefR, tmpSigCoefI ;
  double tmpPatCoefR, tmpPatCoefI ;
  double wigNorm ;

  /* for sanity, set all so3coefs to 0 */
  memset( so3CoefR, 0, sizeof(double) * totalCoeffs_so3( bwOut ) );
  memset( so3CoefI, 0, sizeof(double) * totalCoeffs_so3( bwOut ) );

  for( l = 0 ; l <= degLim ; l ++ )
    {
      wigNorm = 2.*M_PI*sqrt(2./(2.*l+1)) ;
      for( m1 = -l ; m1 <= l ; m1 ++ )
	{
	  /* grab signal coefficient, at this degree and order */
	  dummy = seanindex(-m1, l, bwIn) ;
	  tmpSigCoefR = sigCoefR[ dummy ];
	  tmpSigCoefI = sigCoefI[ dummy ];

	  /* need to reset the -1 fudge factor */
	  if ( (m1 + l) % 2 )
	    fudge = -1 ;
	  else
	    fudge = 1 ;

	  for( m2 = -l ; m2 <= l ; m2 ++ )
	    {
	      dummy = seanindex( -m2, l, bwIn );

	      /*
		first take the CONJUGATE of the pattern coef
		and multiply it by the fudge factor
	      */
	      tmpPatCoefR = fudge *   patCoefR[ dummy ];
	      tmpPatCoefI = fudge * (-patCoefI[ dummy ]);

	      /* now multiply the signal coef by the pattern coef,
		 and save it in the so3 coefficient array */
	      
	      dummy = so3CoefLoc( m1, m2, l, bwOut ) ;
	      so3CoefR[ dummy ] = wigNorm *
		(
		 tmpSigCoefR*tmpPatCoefR -
		 tmpSigCoefI*tmpPatCoefI ) ;

	      so3CoefI[ dummy ] = wigNorm *
		(
		 tmpSigCoefR*tmpPatCoefI +
		 tmpSigCoefI*tmpPatCoefR ) ;

	      /* multiply fudge factor by -1 */
	      fudge *= -1 ;
	    }
	}
    }
}
Exemplo n.º 4
0
void Forward_SO3_Naive_fftw( int bw,
			     fftw_complex *data,
			     fftw_complex *coeffs,
			     fftw_complex *workspace_cx,
			     fftw_complex *workspace_cx2,
			     double *workspace_re,
			     double *weights,
			     fftw_plan *p1,
			     int flag )
{
  int j, n, n3 ;
  int m1, m2 ;
  int sampHere, coefHere ;
  int coefHere2 ;
  int tmpInt ;
  double *sinPts, *cosPts, *sinPts2, *cosPts2 ;
  double *wigners, *scratch ;
  double fudge ;
  fftw_complex *coeffsPtr ;
  fftw_complex *dataPtr ;
  double dn ;

  n = 2 * bw ;
  n3 = n * n * n ;

  /* I'll need these for later */
  coeffsPtr = coeffs ;
  dataPtr = data ;

  sinPts = workspace_re ;
  cosPts = sinPts + n ;
  sinPts2 = cosPts + n ;
  cosPts2 = sinPts2 + n ;
  wigners = cosPts2 + n ;
  scratch = wigners + ( bw * n ) ; /* wigners need at most bw*n space AT
				      ANY given orders m1, m2 */
  /*
    before going further, let's precompute all the sines
    and cosines I'll need. No matter what order transform
    I'm doing, these'll stay the same.
  */
  SinEvalPts( n, sinPts );
  CosEvalPts( n, cosPts );
  SinEvalPts2( n, sinPts2 );
  CosEvalPts2( n, cosPts2 );

  /*
    I also need to copy the contents of data to workspace_cx2,
    given that's where the fftw plan expects data to be. I wish
    I didn't have to waste so much memory
  */
  memcpy( workspace_cx2, data, sizeof(fftw_complex) * n3 );

  /*
    Stage 1: FFT the "rows". Instead of treating the signal as
    3-D object, I can also think of it as an array of size
    (n^2) x n. This means all I'm doing in the first stage
    is taking n^2-many FFTs, each of length n.

    NOTE: Since I'm reusing the FFT code from SpharmonicKit,
    even though I'm doing the FORWARD SO(3) transform
    here, I need to call grid_invfourier  -> the signs
    on the complex exponentials are switched (detailed
    explanation to be put here eventually, but trust
    me)
  */

  fftw_execute( *p1 ) ;
  
  /* normalize the Fourier coefficients (sorry, have to do it) */
  /* no, I don't! I can wait till the end */
  /*
    dn = 1. / sqrt( (double) n ) ;
    for ( j = 0 ; j < n*n*n; j++ )
    {
    workspace_cx[ j ][0] *= dn ;
    workspace_cx[ j ][1] *= dn ;
    }
  */

  /*
    Stage 2: transpose!
  */
  
  transpose_cx( workspace_cx, workspace_cx2, n*n, n ) ;

  /*
    Stage 3: FFT again.
  */

  fftw_execute( *p1 ) ;


  /* normalize the Fourier coefficients (sorry, have to do it) */
  /* no, I don't! I can wait till the end */
  /*
    dn = 1. / ((double) n) ;
    for ( j = 0 ; j < n*n*n; j++ )
    {
    workspace_cx[ j ][0] *= dn ;
    workspace_cx[ j ][1] *= dn ;
    }
  */

  /*
    Stage 4: transpose again! And note I'm using the tmp space
    of t2r, t2i again.
  */
  transpose_cx( workspace_cx, workspace_cx2, n*n, n ) ;

  /*
    Stage 5: Do the Wigner transforms. This is the tricky bit.

    Since I'm working with two order indeces, m1 and m2, the
    for-loops will be more intricate than in the case of the
    "ordinary" spherical transform on S^2.

    Also, I will be taking advantage of the symmetries of the
    Wigner-d functions. As long as I keep my signs and flips
    right, the Wigner-d's I precompute for an order (m1, m2)
    transform can generally  be used in seven more transforms:
    (m1,-m2), (m2,m1), (m2,-m1), (-m2,m1), (-m2,-m1), (-m1,m2)
    and (-m1,-m2).

    I say "general" because, of course, I'll be transforming
    at orders (m1,m1), (m1,0) and (0,m1), so I won't get such
    a huge reduction. Still, this should save time.

    If assumptions are made regarding the original input signal,
    e.g. it's strictly real, then one may take advantage of
    symmetries of the big D wigners (i.e. function of all 3
    parameters alpha, beta, gamma) and so simplify the for-loops
    some and hence increase the speed of the program. However,
    the for-loops to follow will make no such assumptions.
    Whether the signal is real or complex, these for-loops will
    handle it.

    The for-loops will be "designed" as follows. They will be
    divided into cases according to the orders:

    0) {f_{0,0}}

    1) for 0 <= m1 <= bw-1
    compute the coefficients
    i)   {f_{ m1, m1}}
    ii)  {f_{-m1,-m1}}
    iii) {f_{-m1, m1}}
    iv)  {f_{ m1,-m1}}

    2) for 1 <= m1 <= bw-1
    compute the coefficients
    i)   {f_{ m1,  0}}
    ii)  {f_{-m1,  0}}
    iii) {f_{  0, m1}}
    iv)  {f_{  0,-m1}}

    3) for 1 <= m1 <= bw-1
    for m1+1 <= m2 <= bw-1
    compute the coefficients
    i)    {f_{ m1, m2}}
    ii)   {f_{-m1,-m2}}
    iii)  {f_{ m1,-m2}}
    iv)   {f_{-m1, m2}}
    v)    {f_{ m2, m1}}
    vi)   {f_{-m2,-m1}}
    vii)  {f_{ m2,-m1}}
    viii) {f_{-m2, m1}}


    Fasten your seatbelt, folks. It's going to be a bumpy ride.

  */


  /***************************/
  /*                         */
  /* {f_{0,0}} coefficient   */
  /*                         */
  /***************************/


  /* compute the wigners I'll need */
  genWig_L2( 0, 0, bw,
	     sinPts, cosPts,
	     sinPts2, cosPts2,
	     wigners, scratch ) ;
  
  /* now, get the locations of where the
     samples I have to transform are, and
     where the coefficients have to go */
  
  sampHere = sampLoc_so3( 0, 0, bw ) ;
  coefHere = coefLoc_so3( 0, 0, bw ) ;

  /* ok, reset sample, coef ptrs */
  coeffsPtr = coeffs ;
  dataPtr = workspace_cx2 ;
  
  /* now advance by the computed amounts */
  dataPtr += sampHere ;
  coeffsPtr += coefHere ;
  
  /* now transform the real and imaginary parts
     of the data */
  
  wigNaiveAnalysis_fftw( 0, 0, bw, dataPtr,
			 wigners, weights,
			 coeffsPtr, workspace_cx ) ;


  /*** 0 <= m1 <= bw-1 ***/
  for ( m1 = 1 ; m1 < bw ; m1 ++ )
    {

      /* compute the wigners I'll need */
      genWig_L2( m1, m1, bw,
		 sinPts, cosPts,
		 sinPts2, cosPts2,
		 wigners, scratch ) ;

      /***************************/
      /*                         */
      /* {f_{m1,m1}} coefficient */
      /*                         */
      /***************************/

      /* now, get the locations of where the
	 samples I have to transform are, and
	 where the coefficients have to go */
      
      sampHere = sampLoc_so3( m1, m1, bw ) ;
      coefHere = coefLoc_so3( m1, m1, bw ) ;
      
      /* ok, reset sample, coef ptrs */
      coeffsPtr = coeffs ;
      dataPtr = workspace_cx2 ;
      
      /* now advance by the computed amounts */
      dataPtr += sampHere ;
      coeffsPtr += coefHere ;
      
      /* now transform the real and imaginary parts
	 of the data */
      
      wigNaiveAnalysis_fftw( m1, m1, bw, dataPtr,
			     wigners, weights,
			     coeffsPtr, workspace_cx ) ;

      /*****************************/
      /*                           */
      /* {f_{-m1,-m1}} coefficient */
      /*                           */
      /*****************************/

      if ( flag == 0 ) /* if data is complex */
	{
	  /* now, get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( -m1, -m1, bw ) ;
	  coefHere = coefLoc_so3( -m1, -m1, bw ) ;
	  
	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = workspace_cx2 ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftw( -m1, -m1, bw, dataPtr,
				 wigners, weights,
				 coeffsPtr, workspace_cx ) ;

	}
      else  /* data is real, so use symmetry */
	{
	  coefHere = coefLoc_so3( m1, m1, bw ) ;
	  coefHere2 = coefLoc_so3( -m1, -m1, bw ) ;

	  for ( j = 0 ; j < bw - m1 ; j ++ )
	    {
	      coeffs[coefHere2+j][0] = coeffs[coefHere+j][0];
	      coeffs[coefHere2+j][1] = -coeffs[coefHere+j][1];
	    }

	}

      /*****************************/
      /*                           */
      /* {f_{-m1,m1}} coefficient  */
      /*                           */
      /*****************************/


      /* now, get the locations of where the
	 samples I have to transform are, and
	 where the coefficients have to go */

      sampHere = sampLoc_so3( -m1, m1, bw ) ;
      coefHere = coefLoc_so3( -m1, m1, bw ) ;

      /* ok, reset sample, coef ptrs */
      coeffsPtr = coeffs ;
      dataPtr = workspace_cx2 ;
      
      /* now advance by the computed amounts */
      dataPtr += sampHere ;
      coeffsPtr += coefHere ;

      /* now transform the real and imaginary parts
	 of the data */

      wigNaiveAnalysis_fftwY( -m1, m1, bw, dataPtr,
			      wigners, weights,
			      coeffsPtr, workspace_cx ) ;

      /*****************************/
      /*                           */
      /* {f_{m1,-m1}} coefficient  */
      /*                           */
      /*****************************/

      if ( flag == 0 ) /* data is complex */
	{
	  
	  /* now, get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m1, -m1, bw ) ;
	  coefHere = coefLoc_so3( m1, -m1, bw ) ;
	  
	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = workspace_cx2 ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftwY( m1, -m1, bw, dataPtr,
				  wigners, weights,
				  coeffsPtr, workspace_cx ) ;

	}
      else /* data is real, so use symmetry */
	{
	  coefHere = coefLoc_so3( -m1, m1, bw );
	  coefHere2 = coefLoc_so3( m1, -m1, bw );

	  for ( j = 0 ; j < bw - m1 ; j ++ )
	    {
	      coeffs[coefHere2+j][0] = coeffs[coefHere+j][0];
	      coeffs[coefHere2+j][1] = -coeffs[coefHere+j][1];
	    }

	}

    }

  /*** for 1 <= m1 <= bw-1 ***/
  for ( m1 = 1 ; m1 < bw ; m1 ++ )
    {
      
      /* compute the wigners I'll need */
      genWig_L2( m1, 0, bw,
		 sinPts, cosPts,
		 sinPts2, cosPts2,
		 wigners, scratch ) ;

      /***************************/
      /*                         */
      /* {f_{m1,0}} coefficient */
      /*                         */
      /***************************/


      /* get the locations of where the
	 samples I have to transform are, and
	 where the coefficients have to go */

      sampHere = sampLoc_so3( m1, 0, bw ) ;
      coefHere = coefLoc_so3( m1, 0, bw ) ;

      /* ok, reset sample, coef ptrs */
      coeffsPtr = coeffs ;
      dataPtr = workspace_cx2 ;
      
      /* now advance by the computed amounts */
      dataPtr += sampHere ;
      coeffsPtr += coefHere ;

      /* now transform the real and imaginary parts
	 of the data */

      wigNaiveAnalysis_fftw( m1, 0, bw, dataPtr,
			     wigners, weights,
			     coeffsPtr, workspace_cx ) ;

      /***************************/
      /*                         */
      /* {f_{-m1,0}} coefficient */
      /*                         */
      /***************************/


      if ( flag == 0 ) /* data is complex */
	{
	        
	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */

	  sampHere = sampLoc_so3( -m1, 0, bw ) ;
	  coefHere = coefLoc_so3( -m1, 0, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = workspace_cx2 ;
      
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;

	  /* now transform the real and imaginary parts
	     of the data */

	  wigNaiveAnalysis_fftwX( -m1, 0, bw, dataPtr,
				  wigners, weights,
				  coeffsPtr, workspace_cx ) ;
	}
      else  /* data is real, so use symmetry */
	{
	  coefHere = coefLoc_so3( m1, 0, bw );
	  coefHere2 = coefLoc_so3( -m1, 0, bw );

	  if ( (m1 % 2) == 0 )
	    fudge = 1.0 ;
	  else
	    fudge = -1.0 ;

	  for ( j = 0 ; j < bw - m1 ; j ++ )
	    {
	      coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
	      coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
	    }
	  
	}

      /***************************/
      /*                         */
      /* {f_{0,m1}} coefficient */
      /*                         */
      /***************************/

      
      /* get the locations of where the
	 samples I have to transform are, and
	 where the coefficients have to go */

      sampHere = sampLoc_so3( 0, m1, bw ) ;
      coefHere = coefLoc_so3( 0, m1, bw ) ;

      /* ok, reset sample, coef ptrs */
      coeffsPtr = coeffs ;
      dataPtr = workspace_cx2 ;
      
      /* now advance by the computed amounts */
      dataPtr += sampHere ;
      coeffsPtr += coefHere ;

      /* now transform the real and imaginary parts
	 of the data */

      wigNaiveAnalysis_fftwX( 0, m1, bw, dataPtr,
			      wigners, weights,
			      coeffsPtr, workspace_cx ) ;


      /***************************/
      /*                         */
      /* {f_{0,-m1}} coefficient */
      /*                         */
      /***************************/


      if ( flag == 0 ) /* data is complex */
	{
      
	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */

	  sampHere = sampLoc_so3( 0, -m1, bw ) ;
	  coefHere = coefLoc_so3( 0, -m1, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = workspace_cx2 ;
      
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;

	  /* now transform the real and imaginary parts
	     of the data */

	  wigNaiveAnalysis_fftw( 0, -m1, bw, dataPtr,
				 wigners, weights,
				 coeffsPtr, workspace_cx ) ;
	}
      else  /* data is real, so use symmetry */
	{
   	  coefHere = coefLoc_so3( 0, m1, bw );
	  coefHere2 = coefLoc_so3( 0, -m1, bw );

	  if ( (m1 % 2) == 0 )
	    fudge = 1.0 ;
	  else
	    fudge = -1.0 ;

	  for ( j = 0 ; j < bw - m1 ; j ++ )
	    {
	      coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
	      coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
	    }
	  
	}
    }


  /***
      1 <= m1 <= bw-1
      m1+1 <= m2 <= bw-1
  ***/

  for ( m1 = 1 ; m1 < bw ; m1 ++ )
    {
      for ( m2 = m1 + 1 ; m2 < bw ; m2 ++ )
	{

	  
	  /* compute the wigners I'll need */
	  genWig_L2( m1, m2, bw,
		     sinPts, cosPts,
		     sinPts2, cosPts2,
		     wigners, scratch ) ;

	  /***************************/
	  /*                         */
	  /* {f_{m1,m2}} coefficient */
	  /*                         */
	  /***************************/

	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m1, m2, bw ) ;
	  coefHere = coefLoc_so3( m1, m2, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = workspace_cx2 ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftw( m1, m2, bw, dataPtr,
				 wigners, weights,
				 coeffsPtr, workspace_cx ) ;
	  
	  /*****************************/
	  /*                           */
	  /* {f_{-m1,-m2}} coefficient */
	  /*                           */
	  /*****************************/

	  if ( flag == 0 ) /* data is complex */
	    {

	      /* get the locations of where the
		 samples I have to transform are, and
		 where the coefficients have to go */
	  
	      sampHere = sampLoc_so3( -m1, -m2, bw ) ;
	      coefHere = coefLoc_so3( -m1, -m2, bw ) ;

	      /* ok, reset sample, coef ptrs */
	      coeffsPtr = coeffs ;
	      dataPtr = workspace_cx2 ;
	  
	      /* now advance by the computed amounts */
	      dataPtr += sampHere ;
	      coeffsPtr += coefHere ;
	  
	      /* now transform the real and imaginary parts
		 of the data */
	  
	      wigNaiveAnalysis_fftwX( -m1, -m2, bw, dataPtr,
				      wigners, weights,
				      coeffsPtr, workspace_cx ) ;
	    }
	  else  /* data is real, so use symmetry */
	    {
	      coefHere = coefLoc_so3( m1, m2, bw );
	      coefHere2 = coefLoc_so3( -m1, -m2, bw );
	  

	      if ( ((m2-m1) % 2) == 0 )
		fudge = 1.0 ;
	      else
		fudge = -1.0 ;

	      for ( j = 0 ; j < bw - m2 ; j ++ )
		{
		  coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
		  coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
		}

	    }


	  /****************************/
	  /*                          */
	  /* {f_{m1,-m2}} coefficient */
	  /*                          */
	  /****************************/
  

	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m1, -m2, bw ) ;
	  coefHere = coefLoc_so3( m1, -m2, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = workspace_cx2 ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftwY( m1, -m2, bw, dataPtr,
				  wigners, weights,
				  coeffsPtr, workspace_cx ) ;

	  /*****************************/
	  /*                           */
	  /* {f_{-m1,m2}} coefficient  */
	  /*                           */
	  /*****************************/

	  if ( flag == 0 ) /* data is complex */
	    {

	      /* get the locations of where the
		 samples I have to transform are, and
		 where the coefficients have to go */
	  
	      sampHere = sampLoc_so3( -m1, m2, bw ) ;
	      coefHere = coefLoc_so3( -m1, m2, bw ) ;

	      /* ok, reset sample, coef ptrs */
	      coeffsPtr = coeffs ;
	      dataPtr = workspace_cx2 ;
	  
	      /* now advance by the computed amounts */
	      dataPtr += sampHere ;
	      coeffsPtr += coefHere ;
	  
	      /* now transform the real and imaginary parts
		 of the data */
	  
	      wigNaiveAnalysis_fftwY( -m1, m2, bw, dataPtr,
				      wigners, weights,
				      coeffsPtr, workspace_cx ) ;

	    }
	  else  /* data is real, so use symmetry */
	    {
	      coefHere = coefLoc_so3( m1, -m2, bw );
	      coefHere2 = coefLoc_so3( -m1, m2, bw );


	      if ( ((m2-m1) % 2) == 0 )
		fudge = 1.0 ;
	      else
		fudge = -1.0 ;
	      
	      for ( j = 0 ; j < bw - m2 ; j ++ )
		{
		  coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
		  coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
		}
	  
	    }


	  
	  /***************************/
	  /*                         */
	  /* {f_{m2,m1}} coefficient */
	  /*                         */
	  /***************************/
	  
	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m2, m1, bw ) ;
	  coefHere = coefLoc_so3( m2, m1, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = workspace_cx2 ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftwX( m2, m1, bw, dataPtr,
				  wigners, weights,
				  coeffsPtr, workspace_cx ) ;


	  /*****************************/
	  /*                           */
	  /* {f_{-m2,-m1}} coefficient */
	  /*                           */
	  /*****************************/
	  
	  if ( flag == 0 ) /* data is complex */
	    {


	      /* get the locations of where the
		 samples I have to transform are, and
		 where the coefficients have to go */
	  
	      sampHere = sampLoc_so3( -m2, -m1, bw ) ;
	      coefHere = coefLoc_so3( -m2, -m1, bw ) ;

	      /* ok, reset sample, coef ptrs */
	      coeffsPtr = coeffs ;
	      dataPtr = workspace_cx2 ;
	  
	      /* now advance by the computed amounts */
	      dataPtr += sampHere ;
	      coeffsPtr += coefHere ;
	  
	      /* now transform the real and imaginary parts
		 of the data */
	  
	      wigNaiveAnalysis_fftw( -m2, -m1, bw, dataPtr,
				     wigners, weights,
				     coeffsPtr, workspace_cx ) ;

	    }
	  else  /* data is real, so use symmetry */
	    {
	      coefHere = coefLoc_so3( m2, m1, bw );
	      coefHere2 = coefLoc_so3( -m2, -m1, bw );


	      if ( ((m2-m1) % 2) == 0 )
		fudge = 1.0 ;
	      else
		fudge = -1.0 ;

	      for ( j = 0 ; j < bw - m2 ; j ++ )
		{
		  coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
		  coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
		}

	    }


	  /****************************/
	  /*                          */
	  /* {f_{m2,-m1}} coefficient */
	  /*                          */
	  /****************************/
  

	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m2, -m1, bw ) ;
	  coefHere = coefLoc_so3( m2, -m1, bw ) ;
	  
	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = workspace_cx2 ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftwY( m1, -m2, bw, dataPtr,
				  wigners, weights,
				  coeffsPtr, workspace_cx ) ;


	  /****************************/
	  /*                          */
	  /* {f_{-m2,m1}} coefficient */
	  /*                          */
	  /****************************/
  

	  if ( flag == 0 ) /* data is complex */
	    {
	      /* get the locations of where the
		 samples I have to transform are, and
		 where the coefficients have to go */
	  
	      sampHere = sampLoc_so3( -m2, m1, bw ) ;
	      coefHere = coefLoc_so3( -m2, m1, bw ) ;

	      /* ok, reset sample, coef ptrs */
	      coeffsPtr = coeffs ;
	      dataPtr = workspace_cx2 ;
	  
	      /* now advance by the computed amounts */
	      dataPtr += sampHere ;
	      coeffsPtr += coefHere ;
	  
	      /* now transform the real and imaginary parts
		 of the data */
	  
	      wigNaiveAnalysis_fftwY( -m1, m2, bw, dataPtr,
				      wigners, weights,
				      coeffsPtr, workspace_cx ) ;

	    }
	  else  /* data is real, so use symmetry */
	    {
	      coefHere = coefLoc_so3( m2, -m1, bw );
	      coefHere2 = coefLoc_so3( -m2, m1, bw );
	      
	      if ( ((m2-m1) % 2) == 0 )
		fudge = 1.0 ;
	      else
		fudge = -1.0 ;
	      
	      for ( j = 0 ; j < bw - m2 ; j ++ )
		{
		  coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
		  coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
		}

	    }
	}
    }

  	  
  /* reset coef ptrs */
  coeffsPtr = coeffs ;

  /* need to normalize, one last time */
  dn = (M_PI /  ( (double) (bw * n )) );
  tmpInt = totalCoeffs_so3( bw ) ;
  for ( j = 0 ; j < tmpInt ; j ++ )
    {
      coeffsPtr[ j ][0] *= dn ;
      coeffsPtr[ j ][1] *= dn ;
    }

  /*** and we're done ! ***/
}
Exemplo n.º 5
0
int main( int argc,
	  char **argv )

{
  int i, bw, n, n3 ;
  int l, m1, m2, dummy, format ;
  double *rsignal, *isignal ;
  double *rcoeffs, *icoeffs ;
  double *workspace1, *workspace2 ;
  double tstart, tstop, runtime ;
  FILE *fp ;
  
  if (argc != 5)
    {
      fprintf(stdout,"Usage: test_soft_for bw sampleFile ");
      fprintf(stdout,"coefFile order_flag\n");
      exit(0);
    }

  bw = atoi( argv[1] );
  n = 2 * bw ;
  n3 = n * n * n ;
  format = atoi( argv[4] );

  /* real and imaginary parts of signal each need n^3 space */
  rsignal = ( double * ) malloc( sizeof( double ) * n3 ) ;
  isignal = ( double * ) malloc( sizeof( double ) * n3 ) ;

  /* real and imaginary parts of coeffs each need
     totalCoeffs_so3( bw) amount of space */
  rcoeffs = ( double * ) malloc(sizeof( double ) * totalCoeffs_so3( bw ) ) ;
  icoeffs = ( double * ) malloc(sizeof( double ) * totalCoeffs_so3( bw ) ) ;

  /* now for LOTS OF workspace */
  workspace1 = ( double * ) malloc(sizeof( double ) * 4 * n3 ) ;
  workspace2 = ( double * ) malloc(sizeof( double ) * ( 26 * bw + 2 * bw * bw) );


  if ( ( rsignal == NULL ) || ( isignal == NULL ) ||
       ( rcoeffs == NULL ) || ( icoeffs == NULL ) ||
       ( workspace1 == NULL ) || ( workspace2 == NULL ) )
    {
      perror("Error in allocating memory");
      exit( 1 ) ;
    }

  /* read in samples */
  fp = fopen( argv[2], "r" );
  for ( i = 0 ; i < n3 ; i ++ )
    {
      /* first the real part */
      fscanf(fp, "%lf", rsignal+i) ;
      /* now the imaginary part */
      fscanf(fp, "%lf", isignal+i) ;
    }
  fclose ( fp ) ;

  /* turn on stopwatch */
  tstart = csecond( ) ;

  /* now do the forward transform */
  Forward_SO3_Naive( bw,
		     rsignal, isignal,
		     rcoeffs, icoeffs,
		     workspace1, workspace2 ) ;

  /* turn off stopwatch */
  tstop = csecond( ) ;
  runtime = tstop - tstart ;

  fprintf(stdout,"runtime: %.5f seconds\n", runtime);

  /* write out coefficients to disk */
  /* ordered as the inverse transform expects the coefficients */
  if ( format == 0 )
    {
      fp = fopen( argv[ 3 ], "w" );
      for ( i = 0 ; i < totalCoeffs_so3( bw ) ; i ++ )
	fprintf(fp, "%.16f\n%.16f\n",
		rcoeffs[ i ], icoeffs[ i ] ) ;
      fclose( fp ) ;
    }
  else /* ordered in a more human friendly way */
    {
      fp = fopen( argv[ 3 ], "w" );
      for ( l = 0 ; l < bw ; l ++ )
	for ( m1 = -l ; m1 < l + 1 ; m1 ++ )
	  for ( m2 = -l ; m2 < l + 1 ; m2 ++ )
	    {
	      dummy = so3CoefLoc( m1, m2, l, bw ) ;
	      fprintf(fp, "l = %d m1 = %d m2 = %d\t%.15f\t%.15f\n",
		      l, m1, m2,
		      rcoeffs[ dummy ], icoeffs[ dummy ] ) ;
	    }
      fclose( fp ) ;
    }

  /* free up memory (and there's lots of it) */
  free( workspace2 );
  free( workspace1 );
  free( icoeffs );
  free( rcoeffs );
  free( isignal );
  free( rsignal );

  return 0 ;
}
Exemplo n.º 6
0
int main( int argc,
	  char **argv )
{
  int i, bw, n, n3 ;
  int isReal ;
  int tmpInt ;
  // int l, m1, m2 ;
  // int dummy, format, isReal ;
  double tmpbuf[2] ;
  fftw_complex *signal, *coeffs ;
  double tstartI, tstopI, runtimeI ;
  FILE *fp ;
  
  if (argc < 5)
    {
      fprintf(stdout, "Usage: test_soft_fftw_inv bw coefFile ");
      fprintf(stdout, "sample_file isReal\n");
      exit(0);
    }

  bw = atoi( argv[1] );
  isReal = atoi( argv[4] );

  n = 2 * bw ;
  n3 = n * n * n ;

  /* signal */
  signal = fftw_malloc( sizeof( fftw_complex ) * n3 ) ;

  /* coefficients totalCoeffs_so3( bw) amount of space */
  coeffs = fftw_malloc(sizeof( fftw_complex ) * totalCoeffs_so3( bw ) ) ;

  /* check if any problems allocating memory */
  if ( ( signal == NULL) || ( coeffs == NULL ) )
    {
      perror("Error in allocating memory");
      exit( 1 ) ;
    }

  /* read in coeffs */
  tmpInt = totalCoeffs_so3( bw ) ;
  fp = fopen( argv[2], "r" );
  for ( i = 0 ; i < tmpInt ; i ++ )
    {
      /* first the real part */
      fscanf(fp, "%lf", tmpbuf) ;

      /* now the imaginary part */
      fscanf(fp, "%lf", tmpbuf+1);

      coeffs[i][0] = tmpbuf[0];
      coeffs[i][1] = tmpbuf[1];
    }
  fclose ( fp ) ;

  /* initialize time */
  runtimeI = 0.0 ;

  /* turn on stopwatch */
  tstartI = csecond( ) ;

  Inverse_SO3_Naive_fftw_W( bw,
			    coeffs,
			    signal,
			    isReal ) ;

  /* turn off stopwatch */
  tstopI = csecond( ) ;
  runtimeI += tstopI - tstartI ;
  fprintf(stderr,"inverse time \t = %.4e\n", tstopI - tstartI);

  /* write out samples to disk */
  fp = fopen( argv[ 3 ], "w" );
  if ( isReal ) /* strictly real */
    for ( i = 0 ; i < n3 ; i ++ )
      fprintf(fp, "%.16f\n",
	      signal[ i ][0] ) ;
  else /* complex samples */
    for ( i = 0 ; i < n3 ; i ++ )
      fprintf(fp, "%.16f\n%.16f\n",
	      signal[ i ][0], signal[ i ][1] ) ;

  fclose( fp ) ;


  fftw_free( coeffs );
  fftw_free( signal );

  return 0 ;
}
Exemplo n.º 7
0
void Forward_SO3_Naive_fftw_wo( int bw,
				fftw_complex *data,
				fftw_complex *coeffs,
				fftw_complex *workspace_cx,
				REAL *workspace_re,
				fftw_plan *p1,
				int flag )
{
  int j, n ;
  int m1, m2 ;
  int sampHere, coefHere ;
  int coefHere2 ;
  double *sinPts, *cosPts, *sinPts2, *cosPts2 ;
  double *wigners, *scratch ;
  double fudge ;
  fftw_complex *coeffsPtr ;
  fftw_complex *dataPtr ;
  double dn ;

  n = 2 * bw ;

  sinPts = workspace_re ;
  cosPts = sinPts + n ;
  sinPts2 = cosPts + n ;
  cosPts2 = sinPts2 + n ;
  wigners = cosPts2 + n ;
  scratch = wigners + ( bw * n ) ; /* wigners need at most bw*n space AT
				      ANY given orders m1, m2 */
  /*
    before going further, let's precompute all the sines
    and cosines I'll need. No matter what order transform
    I'm doing, these'll stay the same.
  */
  SinEvalPts( n, sinPts );
  CosEvalPts( n, cosPts );
  SinEvalPts2( n, sinPts2 );
  CosEvalPts2( n, cosPts2 );
    
  /*
    Stage 1: FFT
  */

  fftw_execute( *p1 ) ;
  
  /*
    Stage 2: Do the Wigner transforms. This is the tricky bit.

    Since I'm working with two order indeces, m1 and m2, the
    for-loops will be more intricate than in the case of the
    "ordinary" spherical transform on S^2.

    Also, I will be taking advantage of the symmetries of the
    Wigner-d functions. As long as I keep my signs and flips
    right, the Wigner-d's I precompute for an order (m1, m2)
    transform can generally  be used in seven more transforms:
    (m1,-m2), (m2,m1), (m2,-m1), (-m2,m1), (-m2,-m1), (-m1,m2)
    and (-m1,-m2).

    I say "general" because, of course, I'll be transforming
    at orders (m1,m1), (m1,0) and (0,m1), so I won't get such
    a huge reduction. Still, this should save time.

    If assumptions are made regarding the original input signal,
    e.g. it's strictly real, then one may take advantage of
    symmetries of the big D wigners (i.e. function of all 3
    parameters alpha, beta, gamma) and so simplify the for-loops
    some and hence increase the speed of the program. However,
    the for-loops to follow will make no such assumptions.
    Whether the signal is real or complex, these for-loops will
    handle it.

    The for-loops will be "designed" as follows. They will be
    divided into cases according to the orders:

    0) {f_{0,0}}

    1) for 0 <= m1 <= bw-1
    compute the coefficients
    i)   {f_{ m1, m1}}
    ii)  {f_{-m1,-m1}}
    iii) {f_{-m1, m1}}
    iv)  {f_{ m1,-m1}}

    2) for 1 <= m1 <= bw-1
    compute the coefficients
    i)   {f_{ m1,  0}}
    ii)  {f_{-m1,  0}}
    iii) {f_{  0, m1}}
    iv)  {f_{  0,-m1}}

    3) for 1 <= m1 <= bw-1
    for m1+1 <= m2 <= bw-1
    compute the coefficients
    i)    {f_{ m1, m2}}
    ii)   {f_{-m1,-m2}}
    iii)  {f_{ m1,-m2}}
    iv)   {f_{-m1, m2}}
    v)    {f_{ m2, m1}}
    vi)   {f_{-m2,-m1}}
    vii)  {f_{ m2,-m1}}
    viii) {f_{-m2, m1}}


    Fasten your seatbelt, folks. It's going to be a bumpy ride.

  */


  /***************************/
  /*                         */
  /* {f_{0,0}} coefficient   */
  /*                         */
  /***************************/


  /* compute the wigners I'll need */
  genWig_L2( 0, 0, bw,
	     sinPts, cosPts,
	     sinPts2, cosPts2,
	     wigners, scratch ) ;

  /* now, get the locations of where the
     samples I have to transform are, and
     where the coefficients have to go */
  
  sampHere = sampLoc_so3( 0, 0, bw ) ;
  coefHere = coefLoc_so3( 0, 0, bw ) ;

  /* ok, reset sample, coef ptrs */
  coeffsPtr = coeffs ;
  dataPtr = data ;
  
  /* now advance by the computed amounts */
  dataPtr += sampHere ;
  coeffsPtr += coefHere ;
  
  /* now transform the real and imaginary parts
     of the data */
  
  wigNaiveAnalysis_fftw( 0, 0, bw, dataPtr,
			 wigners, coeffsPtr,
			 workspace_cx ) ;
  

  /*** 0 <= m1 <= bw-1 ***/
  for ( m1 = 1 ; m1 < bw ; m1 ++ )
    {

      /* compute the wigners I'll need */
      genWig_L2( m1, m1, bw,
		 sinPts, cosPts,
		 sinPts2, cosPts2,
		 wigners, scratch ) ;

      /***************************/
      /*                         */
      /* {f_{m1,m1}} coefficient */
      /*                         */
      /***************************/

      /* now, get the locations of where the
	 samples I have to transform are, and
	 where the coefficients have to go */
      
      sampHere = sampLoc_so3( m1, m1, bw ) ;
      coefHere = coefLoc_so3( m1, m1, bw ) ;
      
      /* ok, reset sample, coef ptrs */
      coeffsPtr = coeffs ;
      dataPtr = data ;
      
      /* now advance by the computed amounts */
      dataPtr += sampHere ;
      coeffsPtr += coefHere ;
      
      /* now transform the real and imaginary parts
	 of the data */
      
      wigNaiveAnalysis_fftw( m1, m1, bw, dataPtr,
			     wigners, coeffsPtr,
			     workspace_cx ) ;
      
      /*****************************/
      /*                           */
      /* {f_{-m1,-m1}} coefficient */
      /*                           */
      /*****************************/

      if ( flag == 0 ) /* if data is complex */
	{
	  /* now, get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( -m1, -m1, bw ) ;
	  coefHere = coefLoc_so3( -m1, -m1, bw ) ;
	  
	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = data ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftw( -m1, -m1, bw, dataPtr,
				 wigners, coeffsPtr,
				 workspace_cx ) ;

	}
      else  /* data is real, so use symmetry */
	{
	  coefHere = coefLoc_so3( m1, m1, bw ) ;
	  coefHere2 = coefLoc_so3( -m1, -m1, bw ) ;

	  for ( j = 0 ; j < bw - m1 ; j ++ )
	    {
	      coeffs[coefHere2+j][0] = coeffs[coefHere+j][0];
	      coeffs[coefHere2+j][1] = -coeffs[coefHere+j][1];
	    }

	}

      /*****************************/
      /*                           */
      /* {f_{-m1,m1}} coefficient  */
      /*                           */
      /*****************************/


      /* now, get the locations of where the
	 samples I have to transform are, and
	 where the coefficients have to go */

      sampHere = sampLoc_so3( -m1, m1, bw ) ;
      coefHere = coefLoc_so3( -m1, m1, bw ) ;

      /* ok, reset sample, coef ptrs */
      coeffsPtr = coeffs ;
      dataPtr = data ;
      
      /* now advance by the computed amounts */
      dataPtr += sampHere ;
      coeffsPtr += coefHere ;

      /* now transform the real and imaginary parts
	 of the data */

      wigNaiveAnalysis_fftwY( -m1, m1, bw, dataPtr,
			      wigners, coeffsPtr,
			      workspace_cx ) ;
      
      /*****************************/
      /*                           */
      /* {f_{m1,-m1}} coefficient  */
      /*                           */
      /*****************************/

      if ( flag == 0 ) /* data is complex */
	{
	  
	  /* now, get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m1, -m1, bw ) ;
	  coefHere = coefLoc_so3( m1, -m1, bw ) ;
	  
	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = data ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftwY( m1, -m1, bw, dataPtr,
				  wigners, coeffsPtr,
				  workspace_cx ) ;
	  
	}
      else /* data is real, so use symmetry */
	{
	  coefHere = coefLoc_so3( -m1, m1, bw );
	  coefHere2 = coefLoc_so3( m1, -m1, bw );

	  for ( j = 0 ; j < bw - m1 ; j ++ )
	    {
	      coeffs[coefHere2+j][0] = coeffs[coefHere+j][0];
	      coeffs[coefHere2+j][1] = -1.*coeffs[coefHere+j][1];
	    }

	}

    }

  /*** for 1 <= m1 <= bw-1 ***/
  for ( m1 = 1 ; m1 < bw ; m1 ++ )
    {
      
      /* compute the wigners I'll need */
      genWig_L2( m1, 0, bw,
		 sinPts, cosPts,
		 sinPts2, cosPts2,
		 wigners, scratch ) ;

      /***************************/
      /*                         */
      /* {f_{m1,0}} coefficient */
      /*                         */
      /***************************/


      /* get the locations of where the
	 samples I have to transform are, and
	 where the coefficients have to go */

      sampHere = sampLoc_so3( m1, 0, bw ) ;
      coefHere = coefLoc_so3( m1, 0, bw ) ;

      /* ok, reset sample, coef ptrs */
      coeffsPtr = coeffs ;
      dataPtr = data ;
      
      /* now advance by the computed amounts */
      dataPtr += sampHere ;
      coeffsPtr += coefHere ;

      /* now transform the real and imaginary parts
	 of the data */

      wigNaiveAnalysis_fftw( m1, 0, bw, dataPtr,
			     wigners, coeffsPtr,
			     workspace_cx ) ;
      
      /***************************/
      /*                         */
      /* {f_{-m1,0}} coefficient */
      /*                         */
      /***************************/


      if ( flag == 0 ) /* data is complex */
	{
	        
	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */

	  sampHere = sampLoc_so3( -m1, 0, bw ) ;
	  coefHere = coefLoc_so3( -m1, 0, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = data ;
      
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;

	  /* now transform the real and imaginary parts
	     of the data */

	  wigNaiveAnalysis_fftwX( -m1, 0, bw, dataPtr,
				  wigners, coeffsPtr,
				  workspace_cx ) ;
	}
      else  /* data is real, so use symmetry */
	{
	  coefHere = coefLoc_so3( m1, 0, bw );
	  coefHere2 = coefLoc_so3( -m1, 0, bw );

	  if ( (m1 % 2) == 0 )
	    fudge = 1.0 ;
	  else
	    fudge = -1.0 ;

	  for ( j = 0 ; j < bw - m1 ; j ++ )
	    {
	      coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
	      coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
	    }
	  
	}

      /***************************/
      /*                         */
      /* {f_{0,m1}} coefficient */
      /*                         */
      /***************************/

      
      /* get the locations of where the
	 samples I have to transform are, and
	 where the coefficients have to go */

      sampHere = sampLoc_so3( 0, m1, bw ) ;
      coefHere = coefLoc_so3( 0, m1, bw ) ;

      /* ok, reset sample, coef ptrs */
      coeffsPtr = coeffs ;
      dataPtr = data ;
      
      /* now advance by the computed amounts */
      dataPtr += sampHere ;
      coeffsPtr += coefHere ;

      /* now transform the real and imaginary parts
	 of the data */

      wigNaiveAnalysis_fftwX( 0, m1, bw, dataPtr,
			      wigners, coeffsPtr,
			      workspace_cx ) ;
      

      /***************************/
      /*                         */
      /* {f_{0,-m1}} coefficient */
      /*                         */
      /***************************/


      if ( flag == 0 ) /* data is complex */
	{
      
	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */

	  sampHere = sampLoc_so3( 0, -m1, bw ) ;
	  coefHere = coefLoc_so3( 0, -m1, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = data ;
      
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;

	  /* now transform the real and imaginary parts
	     of the data */

	  wigNaiveAnalysis_fftw( 0, -m1, bw, dataPtr,
				 wigners, coeffsPtr,
				 workspace_cx ) ;
	}
      else  /* data is real, so use symmetry */
	{
   	  coefHere = coefLoc_so3( 0, m1, bw );
	  coefHere2 = coefLoc_so3( 0, -m1, bw );

	  if ( (m1 % 2) == 0 )
	    fudge = 1.0 ;
	  else
	    fudge = -1.0 ;

	  for ( j = 0 ; j < bw - m1 ; j ++ )
	    {
	      coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
	      coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
	    }
	  
	}
    }


  /***
      1 <= m1 <= bw-1
      m1+1 <= m2 <= bw-1
  ***/

  for ( m1 = 1 ; m1 < bw ; m1 ++ )
    {
      for ( m2 = m1 + 1 ; m2 < bw ; m2 ++ )
	{

	  
	  /* compute the wigners I'll need */
	  genWig_L2( m1, m2, bw,
		     sinPts, cosPts,
		     sinPts2, cosPts2,
		     wigners, scratch ) ;


	  /***************************/
	  /*                         */
	  /* {f_{m1,m2}} coefficient */
	  /*                         */
	  /***************************/

	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m1, m2, bw ) ;
	  coefHere = coefLoc_so3( m1, m2, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = data ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftw( m1, m2, bw, dataPtr,
				 wigners, coeffsPtr,
				 workspace_cx ) ;
	  
	  /*****************************/
	  /*                           */
	  /* {f_{-m1,-m2}} coefficient */
	  /*                           */
	  /*****************************/

	  if ( flag == 0 ) /* data is complex */
	    {

	      /* get the locations of where the
		 samples I have to transform are, and
		 where the coefficients have to go */
	  
	      sampHere = sampLoc_so3( -m1, -m2, bw ) ;
	      coefHere = coefLoc_so3( -m1, -m2, bw ) ;

	      /* ok, reset sample, coef ptrs */
	      coeffsPtr = coeffs ;
	      dataPtr = data ;
	  
	      /* now advance by the computed amounts */
	      dataPtr += sampHere ;
	      coeffsPtr += coefHere ;
	  
	      /* now transform the real and imaginary parts
		 of the data */
	  
	      wigNaiveAnalysis_fftwX( -m1, -m2, bw, dataPtr,
				      wigners, coeffsPtr,
				      workspace_cx ) ;
	    }
	  else  /* data is real, so use symmetry */
	    {
	      coefHere = coefLoc_so3( m1, m2, bw );
	      coefHere2 = coefLoc_so3( -m1, -m2, bw );
	  
	      
	      if ( ((m2-m1) % 2) == 0 )
		fudge = 1.0 ;
	      else
		fudge = -1.0 ;

	      for ( j = 0 ; j < bw - m2 ; j ++ )
		{
		  coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
		  coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
		}
	     
	    }


	  /****************************/
	  /*                          */
	  /* {f_{m1,-m2}} coefficient */
	  /*                          */
	  /****************************/
  

	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m1, -m2, bw ) ;
	  coefHere = coefLoc_so3( m1, -m2, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = data ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftwY( m1, -m2, bw, dataPtr,
				  wigners, coeffsPtr,
				  workspace_cx ) ;

	  /*****************************/
	  /*                           */
	  /* {f_{-m1,m2}} coefficient  */
	  /*                           */
	  /*****************************/

	  if ( flag == 0 ) /* data is complex */
	    {

	      /* get the locations of where the
		 samples I have to transform are, and
		 where the coefficients have to go */
	  
	      sampHere = sampLoc_so3( -m1, m2, bw ) ;
	      coefHere = coefLoc_so3( -m1, m2, bw ) ;

	      /* ok, reset sample, coef ptrs */
	      coeffsPtr = coeffs ;
	      dataPtr = data ;
	  
	      /* now advance by the computed amounts */
	      dataPtr += sampHere ;
	      coeffsPtr += coefHere ;
	  
	      /* now transform the real and imaginary parts
		 of the data */
	  
	      wigNaiveAnalysis_fftwY( -m1, m2, bw, dataPtr,
				      wigners, coeffsPtr,
				      workspace_cx ) ;

	    }
	  else  /* data is real, so use symmetry */
	    {
	      coefHere = coefLoc_so3( m1, -m2, bw );
	      coefHere2 = coefLoc_so3( -m1, m2, bw );

	      
	      if ( ((m2-m1) % 2) == 0 )
		fudge = 1.0 ;
	      else
		fudge = -1.0 ;
	      
	      for ( j = 0 ; j < bw - m2 ; j ++ )
		{
		  coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
		  coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
		}
	      
	    }


	  
	  /***************************/
	  /*                         */
	  /* {f_{m2,m1}} coefficient */
	  /*                         */
	  /***************************/
	  
	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m2, m1, bw ) ;
	  coefHere = coefLoc_so3( m2, m1, bw ) ;

	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = data ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftwX( m2, m1, bw, dataPtr,
				  wigners, coeffsPtr,
				  workspace_cx ) ;


	  /*****************************/
	  /*                           */
	  /* {f_{-m2,-m1}} coefficient */
	  /*                           */
	  /*****************************/
	  
	  if ( flag == 0 ) /* data is complex */
	    {


	      /* get the locations of where the
		 samples I have to transform are, and
		 where the coefficients have to go */
	  
	      sampHere = sampLoc_so3( -m2, -m1, bw ) ;
	      coefHere = coefLoc_so3( -m2, -m1, bw ) ;

	      /* ok, reset sample, coef ptrs */
	      coeffsPtr = coeffs ;
	      dataPtr = data ;
	  
	      /* now advance by the computed amounts */
	      dataPtr += sampHere ;
	      coeffsPtr += coefHere ;
	  
	      /* now transform the real and imaginary parts
		 of the data */
	  
	      wigNaiveAnalysis_fftw( -m2, -m1, bw, dataPtr,
				     wigners, coeffsPtr,
				     workspace_cx ) ;

	    }
	  else  /* data is real, so use symmetry */
	    {
	      coefHere = coefLoc_so3( m2, m1, bw );
	      coefHere2 = coefLoc_so3( -m2, -m1, bw );

	      
	      if ( ((m2-m1) % 2) == 0 )
		fudge = 1.0 ;
	      else
		fudge = -1.0 ;

	      for ( j = 0 ; j < bw - m2 ; j ++ )
		{
		  coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
		  coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
		}
	      
	    }


	  /****************************/
	  /*                          */
	  /* {f_{m2,-m1}} coefficient */
	  /*                          */
	  /****************************/
  

	  /* get the locations of where the
	     samples I have to transform are, and
	     where the coefficients have to go */
	  
	  sampHere = sampLoc_so3( m2, -m1, bw ) ;
	  coefHere = coefLoc_so3( m2, -m1, bw ) ;
	  
	  /* ok, reset sample, coef ptrs */
	  coeffsPtr = coeffs ;
	  dataPtr = data ;
	  
	  /* now advance by the computed amounts */
	  dataPtr += sampHere ;
	  coeffsPtr += coefHere ;
	  
	  /* now transform the real and imaginary parts
	     of the data */
	  
	  wigNaiveAnalysis_fftwY( m1, -m2, bw, dataPtr,
				  wigners, coeffsPtr,
				  workspace_cx ) ;


	  /****************************/
	  /*                          */
	  /* {f_{-m2,m1}} coefficient */
	  /*                          */
	  /****************************/
  

	  if ( flag == 0 ) /* data is complex */
	    {
	      /* get the locations of where the
		 samples I have to transform are, and
		 where the coefficients have to go */
	  
	      sampHere = sampLoc_so3( -m2, m1, bw ) ;
	      coefHere = coefLoc_so3( -m2, m1, bw ) ;

	      /* ok, reset sample, coef ptrs */
	      coeffsPtr = coeffs ;
	      dataPtr = data ;
	  
	      /* now advance by the computed amounts */
	      dataPtr += sampHere ;
	      coeffsPtr += coefHere ;
	  
	      /* now transform the real and imaginary parts
		 of the data */
	  
	      wigNaiveAnalysis_fftwY( -m1, m2, bw, dataPtr,
				      wigners, coeffsPtr,
				      workspace_cx ) ;

	    }
	  else  /* data is real, so use symmetry */
	    {
	      coefHere = coefLoc_so3( m2, -m1, bw );
	      coefHere2 = coefLoc_so3( -m2, m1, bw );
	      

	      if ( ((m2-m1) % 2) == 0 )
		fudge = 1.0 ;
	      else
		fudge = -1.0 ;
	      
	      for ( j = 0 ; j < bw - m2 ; j ++ )
		{
		  coeffs[coefHere2+j][0] = fudge * coeffs[coefHere+j][0];
		  coeffs[coefHere2+j][1] = -fudge * coeffs[coefHere+j][1];
		}

	    }
	}
    }

  	  
  /* reset coef ptrs */
  coeffsPtr = coeffs ;

  /* need to normalize, one last time */
  dn = (M_PI /  ( (double) (bw * n )) );

  for ( j = 0 ; j < totalCoeffs_so3( bw ) ; j ++ )
    {
      coeffsPtr[ j ][0] *= dn ;
      coeffsPtr[ j ][1] *= dn ;
    }

  /*** and we're done ! ***/
}
Exemplo n.º 8
0
Arquivo: matrix.c Projeto: kogn/scft
void getmatrix(int bw, double alpha, double beta, double kappa, double tau,
    fftw_complex * gamma, double dt, fftw_complex *matrix, fftw_complex *matrix1)
{
  int l;
  init_and_openlink();

  WSPutFunction( lp, "EnterTextPacket", 1L);
  WSPutString(lp,"Get[\"src/matrix.m\"]");
  WSEndPacket(lp);
  for(l = 0; l<bw; l++)
  {
      WSPutFunction( lp, "EvaluatePacket", 1L);{
          WSPutFunction( lp, "matrix", 7L);{
              WSPutInteger( lp, l);
              WSPutReal64( lp, alpha);
              WSPutReal64( lp, beta);
              WSPutReal64( lp, kappa);
              WSPutReal64( lp, tau);
              WSPutReal64( lp, dt*gamma[0][0]);
              WSPutReal64( lp, dt*gamma[0][1]);
          }}WSEndPacket( lp);

    skip_packets(lp);

    double * data; 
    int *dims;
    char **heads;
    int d;
    WSGetReal64Array(lp, &data,&dims,&heads,&d);

    memcpy(matrix+totalCoeffs_so3(l),data,sizeof(fftw_complex)*(2*l+1)*(2*l+1));
    WSReleaseReal64Array(lp,data,dims,heads,d);
  }
  for(l = 0; l<bw; l++)
  {
    WSPutFunction( lp, "EvaluatePacket", 1L);
    WSPutFunction( lp, "matrix", 7L);
    WSPutInteger( lp, l);
    WSPutReal64( lp, alpha);
    WSPutReal64( lp, beta);
    WSPutReal64( lp, kappa);
    WSPutReal64( lp, tau);
    WSPutReal64( lp, dt*gamma[1][0]);
    WSPutReal64( lp, dt*gamma[1][1]);
    WSEndPacket( lp);

    skip_packets(lp);

    double * data; 
    int *dims;
    char **heads;
    int d;
    WSGetReal64Array(lp, &data,&dims,&heads,&d);

    memcpy(matrix1+totalCoeffs_so3(l),data,sizeof(fftw_complex)*(2*l+1)*(2*l+1));
    WSReleaseReal64Array(lp,data,dims,heads,d);
  }
  WSPutFunction( lp, "Exit", 0L);

  return;
}