static void PmlTableGen(int bw, int m, double *storeplm, double *workspace) { double *prev, *prevprev, *temp1, *temp2, *temp3, *temp4, *x_i, *eval_args; int i; /* double *storeplm_ptr; */ prevprev = workspace; prev = prevprev + (2*bw); temp1 = prev + (2*bw); temp2 = temp1 + (2*bw); temp3 = temp2 + (2*bw); temp4 = temp3 + (2*bw); x_i = temp4 + (2*bw); eval_args = x_i + (2*bw); /* storeplm_ptr = storeplm; */ /* get the evaluation nodes */ EvalPts(2*bw,x_i); ArcCosEvalPts(2*bw,eval_args); /* set initial values of first two Pmls */ for (i=0; i<2*bw; i++) prevprev[i] = 0.0; if (m == 0) for (i=0; i<2*bw; i++) { /* prev[i] = 0.5; */ prev[i] = 0.707106781186547 ; /* 1/sqrt(2) */ } else Pmm_L2(m, eval_args, 2*bw, prev); memcpy(storeplm, prev, (size_t) sizeof(double) * 2 * bw); for(i = 0; i < bw - m - 1; i++) { vec_mul(L2_cn(m,m+i),prevprev,temp1,2*bw); vec_pt_mul(prev, x_i, temp2, 2*bw); vec_mul(L2_an(m,m+i), temp2, temp3, 2*bw); vec_add(temp3, temp1, temp4, 2*bw); /* temp4 now contains P(m,m+i+1) */ storeplm += (2 * bw); memcpy(storeplm, temp4, (size_t) sizeof(double) * 2 * bw); memcpy(prevprev, prev, (size_t) sizeof(double) * 2 * bw); memcpy(prev, temp4, (size_t) sizeof(double) * 2 * bw); } /* storeplm = storeplm_ptr; */ }
void CosPmlTableGen(int bw, int m, double *tablespace, double *workspace) { double *prev, *prevprev, *temp1, *temp2, *temp3, *temp4; double *x_i, *eval_args; double *tableptr, *cosres ; int i, j, k; /* fftw stuff now */ double fudge ; fftw_plan p ; prevprev = workspace; prev = prevprev + bw; temp1 = prev + bw; temp2 = temp1 + bw; temp3 = temp2 + bw; temp4 = temp3 + bw; x_i = temp4 + bw; eval_args = x_i + bw; cosres = eval_args + bw; tableptr = tablespace; /* make fftw plan */ p = fftw_plan_r2r_1d( bw, temp4, cosres, FFTW_REDFT10, FFTW_ESTIMATE ) ; /* main loop */ /* Set the initial number of evaluation points to appropriate amount */ /* now get the evaluation nodes */ EvalPts(bw,x_i); ArcCosEvalPts(bw,eval_args); /* set initial values of first two Pmls */ for (i=0; i<bw; i++) prevprev[i] = 0.0; if (m == 0) for (i=0; i<bw; i++) prev[i] = 0.707106781186547; /* sqrt(1/2) */ else Pmm_L2(m, eval_args, bw, prev); if ( m % 2 ) /* need to divide out sin x */ for (i=0; i<bw; i++) prev[i] /= sin(eval_args[i]); /* set k to highest degree coefficient */ if ((m % 2) == 0) k = m; else k = m-1; /* now compute cosine transform */ memcpy( temp4, prev, sizeof(double) * bw ); fftw_execute( p ); cosres[0] *= 0.707106781186547 ; fudge = 1. / sqrt(((double) bw ) ); for ( i = 0 ; i < bw ; i ++ ) cosres[i] *= fudge ; /* store what I've got so far */ for (i=0; i<=k; i+=2) tableptr[i/2] = cosres[i]; /* update tableptr */ tableptr += k/2+1; /* now generate remaining pmls */ for (i=0; i<bw-m-1; i++) { vec_mul(L2_cn(m,m+i),prevprev,temp1,bw); vec_pt_mul(prev, x_i, temp2, bw); vec_mul(L2_an(m,m+i), temp2, temp3, bw); vec_add(temp3, temp1, temp4, bw); /* temp4 now contains P(m,m+i+1) */ /* compute cosine transform */ fftw_execute( p ); cosres[0] *= 0.707106781186547 ; for ( j = 0 ; j < bw ; j ++ ) cosres[j] *= fudge ; /* update degree counter */ k++; /* now put decimated result into table */ if ( i % 2 ) for (j=0; j<=k; j+=2) tableptr[j/2] = cosres[j]; else for (j=1; j<=k; j+=2) tableptr[j/2] = cosres[j]; /* update tableptr */ tableptr += k/2+1; /* now update Pi and P(i+1) */ memcpy(prevprev, prev, sizeof(double) * bw); memcpy(prev, temp4, sizeof(double) * bw); } fftw_destroy_plan( p ); }
void InvFST_semi_memo(double *rcoeffs, double *icoeffs, double *rdata, double *idata, int bw, double **transpose_seminaive_naive_table, double *workspace, int dataformat, int cutoff, fftw_plan *idctPlan, fftw_plan *ifftPlan ) { int size, m, i, n; double *rdataptr, *idataptr; double *rfourdata, *ifourdata; double *rinvfltres, *iminvfltres, *scratchpad; double *sin_values, *eval_pts; double tmpA ; size = 2*bw ; rfourdata = workspace; /* needs (size * size) */ ifourdata = rfourdata + (size * size); /* needs (size * size) */ rinvfltres = ifourdata + (size * size); /* needs (2 * bw) */ iminvfltres = rinvfltres + (2 * bw); /* needs (2 * bw) */ sin_values = iminvfltres + (2 * bw); /* needs (2 * bw) */ eval_pts = sin_values + (2 * bw); /* needs (2 * bw) */ scratchpad = eval_pts + (2 * bw); /* needs (2 * bw) */ /* total workspace = (8 * bw^2) + (10 * bw) */ /* load up the sin_values array */ n = 2*bw; ArcCosEvalPts(n, eval_pts); for (i=0; i<n; i++) sin_values[i] = sin(eval_pts[i]); /* Now do all of the inverse Legendre transforms */ rdataptr = rcoeffs; idataptr = icoeffs; for (m=0; m<bw; m++) { /* fprintf(stderr,"m = %d\n",m); */ if(m < cutoff) { /* do real part first */ InvSemiNaiveReduced(rdataptr, bw, m, rinvfltres, transpose_seminaive_naive_table[m], sin_values, scratchpad, idctPlan ); /* now do imaginary part */ InvSemiNaiveReduced(idataptr, bw, m, iminvfltres, transpose_seminaive_naive_table[m], sin_values, scratchpad, idctPlan); /* will store normal, then tranpose before doing inverse fft */ memcpy(rfourdata+(m*size), rinvfltres, sizeof(double) * size); memcpy(ifourdata+(m*size), iminvfltres, sizeof(double) * size); /* move to next set of coeffs */ rdataptr += bw-m; idataptr += bw-m; } else { /* first do the real part */ Naive_SynthesizeX(rdataptr, bw, m, rinvfltres, transpose_seminaive_naive_table[m]); /* now do the imaginary */ Naive_SynthesizeX(idataptr, bw, m, iminvfltres, transpose_seminaive_naive_table[m]); /* will store normal, then tranpose before doing inverse fft */ memcpy(rfourdata+(m*size), rinvfltres, sizeof(double) * size); memcpy(ifourdata+(m*size), iminvfltres, sizeof(double) * size); /* move to next set of coeffs */ rdataptr += bw-m; idataptr += bw-m; } } /* closes m loop */ /* now fill in zero values where m = bw (from problem definition) */ memset(rfourdata + (bw * size), 0, sizeof(double) * size); memset(ifourdata + (bw * size), 0, sizeof(double) * size); /* now if the data is real, we don't have to compute the coefficients whose order is less than 0, i.e. since the data is real, we know that invf-hat(l,-m) = conjugate(invf-hat(l,m)), so use that to get the rest of the real data dataformat =0 -> samples are complex, =1 -> samples real */ if(dataformat == 0){ /* now do negative m values */ for (m=bw+1; m<size; m++) { /* fprintf(stderr,"m = %d\n",-(size-m)); */ if ( (size-m) < cutoff ) { /* do real part first */ InvSemiNaiveReduced(rdataptr, bw, size - m, rinvfltres, transpose_seminaive_naive_table[size - m], sin_values, scratchpad, idctPlan); /* now do imaginary part */ InvSemiNaiveReduced(idataptr, bw, size - m, iminvfltres, transpose_seminaive_naive_table[size - m], sin_values, scratchpad, idctPlan ); /* will store normal, then tranpose before doing inverse fft */ if ((m % 2) != 0) for(i=0; i< size; i++){ rinvfltres[i] = -rinvfltres[i]; iminvfltres[i] = -iminvfltres[i]; } memcpy(rfourdata + (m*size), rinvfltres, sizeof(double) * size); memcpy(ifourdata + (m*size), iminvfltres, sizeof(double) * size); /* move to next set of coeffs */ rdataptr += bw-(size-m); idataptr += bw-(size-m); } else { /* first do the real part */ Naive_SynthesizeX(rdataptr, bw, size-m, rinvfltres, transpose_seminaive_naive_table[size-m]); /* now do the imaginary */ Naive_SynthesizeX(idataptr, bw, size-m, iminvfltres, transpose_seminaive_naive_table[size-m]); /* will store normal, then tranpose before doing inverse fft */ if ((m % 2) != 0) for(i=0; i< size; i++){ rinvfltres[i] = -rinvfltres[i]; iminvfltres[i] = -iminvfltres[i]; } memcpy(rfourdata + (m*size), rinvfltres, sizeof(double) * size); memcpy(ifourdata + (m*size), iminvfltres, sizeof(double) * size); /* move to next set of coeffs */ rdataptr += bw-(size-m); idataptr += bw-(size-m); } } /* closes m loop */ } else { for(m = bw + 1; m < size; m++){ memcpy(rfourdata+(m*size), rfourdata+((size-m)*size), sizeof(double) * size); memcpy(ifourdata+(m*size), ifourdata+((size-m)*size), sizeof(double) * size); for(i = 0; i < size; i++) ifourdata[(m*size)+i] *= -1.0; } } /* normalize */ tmpA = 1./(sqrt(2.*M_PI) ); for(i=0;i<4*bw*bw;i++) { rfourdata[i] *= tmpA ; ifourdata[i] *= tmpA ; } fftw_execute_split_dft( *ifftPlan, ifourdata, rfourdata, idata, rdata ); /* amscray */ }
void CosPmlTableGenLim( int bw, int m, int lim, double *tablespace, double *workspace) { double *prev, *prevprev, *temp1, *temp2, *temp3, *temp4; double *x_i, *eval_args; double *tableptr, *cosres, *cosworkspace; int i, j, k; prevprev = workspace; prev = prevprev + bw; temp1 = prev + bw; temp2 = temp1 + bw; temp3 = temp2 + bw; temp4 = temp3 + bw; x_i = temp4 + bw; eval_args = x_i + bw; cosres = eval_args + bw; cosworkspace = cosres + bw; tableptr = tablespace; /* main loop */ /* Set the initial number of evaluation points to appropriate amount */ /* now get the evaluation nodes */ EvalPts(bw,x_i); ArcCosEvalPts(bw,eval_args); /* set initial values of first two Pmls */ for (i=0; i<bw; i++) prevprev[i] = 0.0; if (m == 0) { for (i=0; i<bw; i++) { prev[i] = 1.0; } } else Pmm_L2(m, eval_args, bw, prev); if ((m % 2) == 1) { /* need to divide out sin x */ for (i=0; i<bw; i++) prev[i] /= sin(eval_args[i]); } /* set k to highest degree coefficient */ if ((m % 2) == 0) k = m; else k = m-1; /* now compute cosine transform */ kFCT(prev, cosres, cosworkspace, bw, bw, 1); for (i=0; i<=k; i+=2) tableptr[i/2] = cosres[i]; /* update tableptr */ tableptr += k/2+1; /* now generate remaining pmls */ for (i = 0 ; i < lim - m - 1 ; i ++) { vec_mul(L2_cn(m,m+i),prevprev,temp1,bw); vec_pt_mul(prev, x_i, temp2, bw); vec_mul(L2_an(m,m+i), temp2, temp3, bw); vec_add(temp3, temp1, temp4, bw); /* temp4 now contains P(m,m+i+1) */ /* compute cosine transform */ kFCT(temp4, cosres, cosworkspace, bw, bw, 1); /* update degree counter */ k++; /* now put decimated result into table */ if ((i % 2) == 1) { for (j=0; j<=k; j+=2) tableptr[j/2] = cosres[j]; } else { for (j=1; j<=k; j+=2) tableptr[j/2] = cosres[j]; } /* update tableptr */ tableptr += k/2+1; /* now update Pi and P(i+1) */ memcpy(prevprev, prev, sizeof(double) * bw); memcpy(prev, temp4, sizeof(double) * bw); } }