/* * Allocate FFT buffers for a given grid. * This must be called before FFT can be carried out * (called automatically, users don't need to call this) * * grid = 3D grid for which the FFT allocation is to be done (rgrid3d *). * * Notes: * - This uses c2r transformation since it is much faster than r2r. * * No return value. * */ EXPORT void rgrid3d_fftw_periodic_alloc(rgrid3d *grid) { long s; double *plan_temp; s = 2 * grid->nx * grid->ny * (grid->nz/2 + 1); if(!(plan_temp = fftw_malloc(sizeof(double) * s))) { fprintf(stderr, "libgrid: Out of memory in rgrid3d_fft().\n"); return; } memcpy(plan_temp, grid->value, sizeof(double) * s); if(s > temp_len) { if(temp) free(temp); if(!(temp = fftw_malloc(sizeof(double) * s))) { fprintf(stderr, "libgrid: Out of memory in rgrid3d_fft().\n"); return; } temp_len = s; temp2 = (double complex *) temp; } fftw_plan_with_nthreads(grid_threads()); grid->plan = fftw_plan_dft_r2c_3d(grid->nx, grid->ny, grid->nz, grid->value, temp2, GRID_FFTW_PLAN | FFTW_DESTROY_INPUT); fftw_plan_with_nthreads(grid_threads()); grid->iplan = fftw_plan_dft_c2r_3d(grid->nx, grid->ny, grid->nz, grid->cint->value, temp, GRID_FFTW_PLAN | FFTW_DESTROY_INPUT); grid->fft_norm = 1.0 / (grid->nx * grid->ny * grid->nz); memcpy(grid->value, plan_temp, sizeof(double) * s); free(plan_temp); }
static gboolean output_spectra_event (GfsEvent * event, GfsSimulation * sim) { if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_spectra_class ())->parent_class)->event) (event, sim)) { GfsDomain * domain = GFS_DOMAIN (sim); GfsOutputSpectra * v = GFS_OUTPUT_SPECTRA (event); fftw_plan p; Datawrite data; data.fp = GFS_OUTPUT (event)->file->fp; data.L = v->L; data.kmax = init_kmax(v->L); data.dir1 = v->dir[0]; data.dir2 = v->dir[1]; fill_cartesian_matrix( v->cgd, v->v, domain); switch (v->Ndim) { case 1: { data.n1 = ( v->cgd->n[v->dir[0]] / 2 ) + 1; data.out = fftw_malloc( sizeof(fftw_complex)*data.n1 ); p = fftw_plan_dft_r2c_1d( v->cgd->n[v->dir[0]], v->cgd->v, data.out, FFTW_ESTIMATE); fftw_execute(p); write_spectra_1D ( &data ); break; } case 2: { data.n1 = v->cgd->n[v->dir[0]]; data.n2 = ( v->cgd->n[v->dir[1]] / 2 ) + 1; data.out = fftw_malloc( sizeof(fftw_complex)*v->cgd->n[v->dir[0]]*data.n2 ); p = fftw_plan_dft_r2c_2d( v->cgd->n[v->dir[0]], v->cgd->n[v->dir[1]], v->cgd->v, data.out, FFTW_ESTIMATE); fftw_execute(p); write_spectra_2D ( &data ); break; } case 3: { data.n1 = v->cgd->n[0]; data.n2 = v->cgd->n[1]; data.n3 = ( v->cgd->n[2] / 2 ) + 1; data.out = fftw_malloc( sizeof(fftw_complex)*v->cgd->n[0]*v->cgd->n[1]*data.n3 ); p = fftw_plan_dft_r2c_3d( v->cgd->n[0], v->cgd->n[1], v->cgd->n[2], v->cgd->v, data.out, FFTW_ESTIMATE); fftw_execute(p); write_spectra_3D ( &data ); break; } default: g_assert_not_reached (); } fftw_destroy_plan(p); fftw_free ( data.out ); return TRUE; } return FALSE; }
void psi_do_phi(psi_grid* grid, psi_real* phi_out, psi_real Gn) { fftw_plan p, pinv; fftw_complex* rhok; psi_int ax, i, j, k; psi_dvec halfn, dims; psi_rvec kvec, L, dx; psi_real kvec2; for(ax = 0; ax < 3; ++ax) { dims.ijk[ax] = grid->n.ijk[ax]; halfn.ijk[ax] = dims.ijk[ax]/2 + 1; L.xyz[ax] = grid->window[1].xyz[ax]-grid->window[0].xyz[ax]; dx.xyz[ax] = L.xyz[ax]/dims.ijk[ax]; } rhok = (fftw_complex*) fftw_malloc(dims.i*dims.j*halfn.k*sizeof(fftw_complex)); p = fftw_plan_dft_r2c_3d(dims.i, dims.j, dims.k, grid->fields[0], rhok, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); // Phi for(i = 0; i < dims.i; ++i) for(j = 0; j < dims.j; ++j) for(k = 0; k < halfn.k; ++k) { // zero the DC component if(i == 0 && j == 0 && k == 0) { rhok[0][0] = 0.0; rhok[0][1] = 0.0; continue; } // compute wavenumbers (arbitrary units) kvec.x = TWO_PI/L.x * ((i < halfn.i)? i : (i - dims.i)); kvec.y = TWO_PI/L.y * ((j < halfn.j)? j : (j - dims.j)); kvec.z = TWO_PI/L.z * k; kvec2 = kvec.x*kvec.x + kvec.y*kvec.y + kvec.z*kvec.z; // Filter the FFT rhok[dims.j*halfn.k*i + halfn.k*j + k][0] *= FOUR_PI*Gn/(dims.i*dims.j*dims.k)*laplace(kvec, dx); rhok[dims.j*halfn.k*i + halfn.k*j + k][1] *= FOUR_PI*Gn/(dims.i*dims.j*dims.k)*laplace(kvec, dx); } pinv = fftw_plan_dft_c2r_3d(dims.i, dims.j, dims.k, rhok, phi_out, FFTW_ESTIMATE); fftw_execute(pinv); fftw_destroy_plan(pinv); fftw_free(rhok); return; }
void power_spectrum(double a) { FILE *output; int i, l, m, n; const double scale = L_BOX / (double) GRID_SIZE; const double volume = (GRID_SIZE * GRID_SIZE * GRID_SIZE); for (i = 0; i < NUM_BINS; i+=2) { Pk_M[i] = 0.0; Pk_M[i + 1] = 0.0; av[i] = 0; av[i + 1] = 0; const register double tmp1 = (M_PI - 2 * M_PI / GRID_SIZE) / NUM_BINS; const register double tmp2 = 2 * M_PI / GRID_SIZE; k_M[i] = i * tmp1 + tmp2; k_M[i + 1] = (i+1) * tmp1 + tmp2; } re2co = fftw_plan_dft_r2c_3d(GRID_SIZE, GRID_SIZE, GRID_SIZE, &rho[0][0][0], F_rho, FFTW_ESTIMATE); fftw_execute(re2co); register const double factor = 2 * M_PI / (double) GRID_SIZE; #pragma omp parallel for private(l,m,n,i) for (l = 0; l < GRID_SIZE; l++) { for (m = 0; m < GRID_SIZE; m++) { for (n = 0; n < GRID_SIZE / 2 + 1; n++) { register const int index = (l * GRID_SIZE + m) * (GRID_SIZE / 2 + 1) + n; i = 0; register const double tmp = factor * sqrt(l * l + m * m + n * n); while (tmp > k_M[i]) i++; if(i == 0 && tmp < k_M[i]) continue; else if(i < NUM_BINS && i >= 0 && l+m+n !=0){ Pk_M[i] += F_rho[index][0] * F_rho[index][0] + F_rho[index][1] * F_rho[index][1]; av[i]++; } } } } char pkname[50]; sprintf(pkname, "Pk_%g.dat",1/a-1); output = fopen(pkname, "w"); for (i = 0; i < NUM_BINS; i++) { if (av[i] != 0) { Pk_M[i] = Pk_M[i] / (double) av[i] * (scale * scale * scale); fprintf(output, "%g\t%g\t%g\n", k_M[i] / scale, Pk_M[i] / volume, dPlus(a)); } } fclose(output); }
void FFT::forward(Volume &vol) { if (vol.domain != Domain::Frequency) { fftw_plan plan; try { plan = forward_plans.at(vol.real_data); } catch (...) { plan = fftw_plan_dft_r2c_3d(vol.width, vol.height, vol.depth, vol.real_data, reinterpret_cast<fftw_complex *>(vol.complex_data), FFTW_ESTIMATE); forward_plans[vol.real_data] = plan; } fftw_execute(plan); vol.domain = Domain::Frequency; } }
void init_gfft() { double complex *wi1; double *wir1; DEBUG_START_FUNC; wi1 = (double complex *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX); if (wi1 == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for wi1 allocation"); wir1 = (double *) wi1; #ifdef _OPENMP fftw_plan_with_nthreads( nthreads ); #endif #ifdef WITH_2D r2cfft = fftw_plan_dft_r2c_2d( NX, NY, wr1, w1, FFT_PLANNING); if (r2cfft == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW R2C plan creation failed"); c2rfft = fftw_plan_dft_c2r_2d( NX, NY, w1, wr1, FFT_PLANNING); if (c2rfft == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW C2R plan creation failed"); #else r2cfft = fftw_plan_dft_r2c_3d( NX, NY, NZ, wr1, w1, FFT_PLANNING); if (r2cfft == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW R2C plan creation failed"); c2rfft = fftw_plan_dft_c2r_3d( NX, NY, NZ, w1, wr1, FFT_PLANNING); if (c2rfft == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW C2R plan creation failed"); r2cfft_2Dslice = fftw_plan_dft_r2c_2d(NX,NY,wrh3,wh3,FFT_PLANNING); if (r2cfft_2Dslice == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW r2c slice plan creation failed"); #endif fftw_free(wi1); fft_timer=0.0; DEBUG_END_FUNC; return; }
void gen_gf_k(){ static real_t rbuf[2*NZ][2*NY][2*NX]; static cplx_t kbuf[2*NZ][2*NY][1+NX]; fftw_plan plan_fwd = fftw_plan_dft_r2c_3d( 2*NZ, 2*NY, 2*NX, (double *)(rbuf), (fftw_complex *)(kbuf), FFTW_ESTIMATE); for(int lm=0; lm<LEN2; lm++){ int i, j, k; for(k=0; k<2*NZ; k++) for(int j=0; j<2*NY; j++) for(i=0; i<2*NX; i++) { rbuf[k][j][i] = gf_r[k][j][i] [lm]; } // CALL FFTW fftw_execute(plan_fwd); for(k=0; k<2*NZ; k++) for(j=0; j<2*NY; j++) for(i=0; i<1+NX; i++) { gf_k[k][j][i] [lm] = kbuf[k][j][i]; } } }
FFTFittingOutput *FFTFitting::do_local_fitting(em::DensityMap *dmap, double density_threshold, atom::Hierarchy mol2fit, double angle_sampling_interval_rad, double max_angle_sampling_rad, double max_translation, int num_fits_to_report, bool cluster_fits, int num_angle_per_voxel, double max_clustering_translation, double max_clustering_rotation, const std::string &angles_filename) { num_angle_per_voxel_=num_angle_per_voxel; multifit::internal::EulerAnglesList rots_all; if (angles_filename != "") { rots_all=parse_angles_file(angles_filename); } else { rots_all= internal::get_uniformly_sampled_rotations(angle_sampling_interval_rad); } std::cout<<"all rots size:"<<rots_all.size()<<std::endl; //now remove rotations if reqruied multifit::internal::EulerAnglesList rots; for(unsigned int i=0;i<rots_all.size();i++) { if (((rots_all[i].psi<=max_angle_sampling_rad)|| (rots_all[i].psi>=(2*PI-max_angle_sampling_rad)))&& ((rots_all[i].theta<=max_angle_sampling_rad)|| (rots_all[i].theta>=(PI-max_angle_sampling_rad)))&& ((rots_all[i].phi<=max_angle_sampling_rad)|| (rots_all[i].phi>=(2*PI-max_angle_sampling_rad)))){ // std::cout<<"ACCEPTED"<<std::endl; rots.push_back(rots_all[i]); } } std::cout<<"number of rotations:"<<rots.size()<<std::endl; resolution_ = dmap->get_header()->get_resolution(); rots_=rots; num_fits_reported_=num_fits_to_report; //----------- TODO FIX THAT, should be in the parameters low_cutoff_=density_threshold; if (resolution_ >= 10) corr_mode_=1;//1-laplacian else corr_mode_=0; //TODO - do not use lap // corr_mode_=0; if (corr_mode_==0) fftw_pad_factor_=0.1; else fftw_pad_factor_=0.2; //---------------------------- orig_cen_=core::get_centroid(core::XYZs(core::get_leaves(mol2fit))); std::cout<<"orig_cen_:"<<orig_cen_<<std::endl; //prepare low resolution map prepare_lowres_map(dmap); //prepare probe, the molecule is being centered prepare_probe(mol2fit); //prepare kernels prepare_kernels(); //pad low res map for FFT pad_resolution_map(); fftw_scale_ = 1.0/(double)nvox_; nx_half_=(nx_-1)/2; ny_half_=(ny_-1)/2; nz_half_=(nz_-1)/2; map_cen_=algebra::Vector3D( (nx_/2.0)*spacing_+origx_, (ny_/2.0)*spacing_+origy_, (nz_/2.0)*spacing_+origz_); prepare_poslist_flipped(low_map_); prepare_poslist(low_map_); sampled_map_data_.resize(fftw_nvox_r2c_); fftw_grid_lo_.resize(fftw_nvox_c2r_); fftw_grid_hi_.resize(fftw_nvox_c2r_); //create the sample map sampled_map_ = new em::SampledDensityMap(*(low_map_->get_header())); sampled_map_->set_was_used(true); kernel::ParticlesTemp mol_ps=core::get_leaves(orig_mol_); IMP_LOG_TERSE("Projecting probe structure to lattice \n"); sampled_map_->reset_data(); sampled_map_->project(core::get_leaves(orig_mol_), margin_ignored_in_conv_[0], margin_ignored_in_conv_[1], margin_ignored_in_conv_[2], map_cen_-core::get_centroid(core::XYZs(mol_ps))); IMP_LOG_TERSE("Applying filters to target and probe maps\n"); switch (corr_mode_) { case 0: low_map_->convolute_kernel(kernel_filter_.get(), kernel_filter_ext_); break; case 1: internal::relax_laplacian(low_map_,fftw_zero_padding_extent_,5.); internal::convolve_kernel_inside_erode(low_map_, kernel_filter_.get(), kernel_filter_ext_); break; } sampled_map_->convolute_kernel(filtered_kernel_.get(), filtered_kernel_ext_); sampled_norm_ = sampled_map_->calcRMS(); asmb_norm_ = low_map_->calcRMS(); sampled_map_->multiply(1./sampled_norm_); low_map_->multiply(1./asmb_norm_); //create plan for low res map fftw_plan_forward_lo_ = fftw_plan_dft_r2c_3d( nz_, ny_, nx_, low_map_data_, fftw_grid_lo_,FFTW_MEASURE); copy_density_data(low_map_,low_map_data_); //do the actual fitting //init results hash fits_hash_.insert(fits_hash_.end(),nvox_, internal::RotScores()); for (unsigned int m=0;m<nvox_;m++) { std::make_heap(fits_hash_[m].begin(),fits_hash_[m].end(), cmp_rot_scores_min); } fftw_execute(fftw_plan_forward_lo_.get()); IMP_LOG_TERSE("Start FFT search for all rotations\n"); //create all plans needed for fft //plan for FFT the molecule fftw_r_grid_mol_.resize(nx_*ny_*nz_); fftw_grid_hi_.resize(fftw_nvox_c2r_); fftw_plan_forward_hi_ = fftw_plan_dft_r2c_3d( nz_, ny_, nx_, fftw_r_grid_mol_, fftw_grid_hi_,FFTW_MEASURE); //plan for IFFT (mol*EM) reversed_fftw_data_.resize(fftw_nvox_r2c_); fftw_plan_reverse_hi_ = fftw_plan_dft_c2r_3d( nz_, ny_, nx_, fftw_grid_hi_,reversed_fftw_data_ ,FFTW_MEASURE); boost::progress_display show_progress(rots_.size()); std::cout<<"number of rots_:"<<rots_.size()<<std::endl; for (unsigned int kk=0;kk<rots_.size();kk++) { fftw_translational_search(rots_[kk],kk); ++show_progress; } //clear grids fftw_grid_lo_.release(); fftw_grid_hi_.release(); //detect the best fits std::cout<<"going to detect top fits"<<std::endl; best_fits_=detect_top_fits(fits_hash_,cluster_fits,max_translation, max_clustering_translation,max_clustering_rotation); std::cout<<"END detect top fits"<<std::endl; if (best_fits_.size()==0) { std::cout<<"No fits found"<<std::endl; // Return empty output IMP_NEW(FFTFittingOutput, ret, ()); return ret.release(); }
void M2L_convolution_OBC( const GreenFunction_OBC<p, NX, NY, NZ> &gf, Cell_FMM<p> cell[NZ][NY][NX]) { typedef typename GreenFunction_OBC<p, NX, NY, NZ>::real_t real_t; typedef typename GreenFunction_OBC<p, NX, NY, NZ>::cplx_t cplx_t; enum{ LEN = lmbuf<p>::length, }; // Multipole Moments // static real_t mm_r[2*NZ][2*NY][2*NX][LEN]; static cplx_t mm_k[2*NZ][2*NY][1+NX][LEN]; // Local Expansions // static real_t le_r[2*NZ][2*NY][2*NX][LEN]; static cplx_t le_k[2*NZ][2*NY][1+NX][LEN]; // FFT buffer static real_t rbuf[2*NZ][2*NY][2*NX]; static cplx_t kbuf[2*NZ][2*NY][1+NX]; fftw_plan plan_fwd = fftw_plan_dft_r2c_3d( 2*NZ, 2*NY, 2*NX, (double *)(rbuf), (fftw_complex *)(kbuf), FFTW_ESTIMATE); fftw_plan plan_bkw = fftw_plan_dft_c2r_3d( 2*NZ, 2*NY, 2*NX, (fftw_complex *)(kbuf), (double *)(rbuf), FFTW_ESTIMATE); int i, j, k; // clear rbuf for(k=0; k<2*NZ; k++) for(j=0; j<2*NY; j++) for(i=0; i<2*NX; i++) { rbuf[k][j][i] = 0.0; } // forward multipole for(int lm=0; lm<LEN; lm++){ for(k=0; k<NZ; k++) for(j=0; j<NY; j++) for(i=0; i<NX; i++) { rbuf[k][j][i] = cell[k][j][i].mm.buf[lm]; } fftw_execute(plan_fwd); for(k=0; k<2*NZ; k++) for(j=0; j<2*NY; j++) for(i=0; i<1+NX; i++) { mm_k[k][j][i][lm] = kbuf[k][j][i]; } } // M2L transformation typedef MultipoleMoment<p, cplx_t> (*mmarray)[2*NY][1+NX]; typedef LocalExpansion <p, cplx_t> (*learray)[2*NY][1+NX]; gf.transform((mmarray)mm_k, (learray)le_k); // backward local expansion for(int lm=0; lm<LEN; lm++){ for(k=0; k<2*NZ; k++) for(j=0; j<2*NY; j++) for(i=0; i<1+NX; i++) { kbuf[k][j][i] = le_k[k][j][i][lm]; } fftw_execute(plan_bkw); const double norm = 1.0 / (8*NX*NY*NZ); for(k=0; k<NZ; k++) for(j=0; j<NY; j++) for(i=0; i<NX; i++) { cell[k][j][i].le.buf[lm] = norm * rbuf[k][j][i]; } } fftw_destroy_plan(plan_fwd); fftw_destroy_plan(plan_bkw); }
void psi_do_power_spectrum(psi_grid* grid, psi_real* P, psi_real* kk, psi_real dk, psi_int nbins) { fftw_plan p; fftw_complex* rhok; psi_int ax, i, j, k, ll; psi_dvec halfn, dims; psi_rvec kvec, L; psi_real ksc, zre, zim, kvol, kvolfac; for(ax = 0; ax < 3; ++ax) { dims.ijk[ax] = grid->n.ijk[ax]; halfn.ijk[ax] = dims.ijk[ax]/2 + 1; L.xyz[ax] = grid->window[1].xyz[ax]-grid->window[0].xyz[ax]; } psi_int *cellcount = (psi_int*) psi_malloc(nbins*sizeof(psi_int)); memset(cellcount, 0, nbins*sizeof(psi_int)); // do the FFT and bin the power rhok = (fftw_complex*) fftw_malloc(dims.i*dims.j*halfn.k*sizeof(fftw_complex)); p = fftw_plan_dft_r2c_3d(dims.i, dims.j, dims.k, grid->fields[0], rhok, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); for(i = 0; i < dims.i; ++i) for(j = 0; j < dims.j; ++j) for(k = 0; k < halfn.k; ++k) { // compute wavenumbers (arbitrary units) kvec.x = TWO_PI/L.x * ((i < halfn.i)? i : (i - dims.i)); kvec.y = TWO_PI/L.y * ((j < halfn.j)? j : (j - dims.j)); kvec.z = TWO_PI/L.z * k; ksc = sqrt(kvec.x*kvec.x + kvec.y*kvec.y + kvec.z*kvec.z); // get the index and bin the power ll = floor(ksc/dk); if(ll < nbins) { zre = rhok[dims.j*halfn.k*i + halfn.k*j + k][0]; zim = rhok[dims.j*halfn.k*i + halfn.k*j + k][1]; P[ll] += zre*zre + zim*zim; ++cellcount[ll]; } } fftw_free(rhok); // normalize // the factor of 2 is for the real FFT, // we have only counted the +- mode pairs once //kvolfac = for(ll = 0; ll < nbins; ++ll) { kk[ll] = dk*(ll+0.5); P[ll] *= 2.0/(dims.i*dims.j*dims.k); P[ll] /= cellcount[ll]; //kvol = (FOUR_PI*dk*dk*dk/3.0)*(1+3*ll+3*ll*ll); //P[ll] *= 1.0/kvol; } free(cellcount); }
/*==============================*/ int main (void) { fftw_complex *delta1k; fftw_complex *delta2k; double *delta1r; double *delta2r; fftw_plan plan1; fftw_plan plan2; int nn = 1024; // 768 could be changed to nc int cn2= nn/2 + 1; int N = nn*nn*nn; int Nc = nn*nn*cn2; delta1k = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Nc); delta2k = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Nc); delta1r = (double *) fftw_malloc(N * sizeof(double)); delta2r = (double *) fftw_malloc(N * sizeof(double)); plan1 = fftw_plan_dft_r2c_3d(nn, nn, nn, delta1r, delta1k, FFTW_ESTIMATE); plan2 = fftw_plan_dft_r2c_3d(nn, nn, nn, delta2r, delta2k, FFTW_ESTIMATE); /*===Finishing FFTW initialization===*/ int i, j, k, index_0; float input; FILE *DEN1 = fopen(path1, "rb"); FILE *DEN2 = 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(&input, 4, 1, DEN1); //delta1r[index_0] = input - 1.; fread(&input, 4, 1, DEN2); delta2r[index_0] = input; } } } printf("Finish reading...\n"); /*===Finishing reading data===*/ double r_part1, i_part1, r_part2, i_part2, deltak2, p1, p2; // fftw_execute(plan1); fftw_execute(plan2); printf("Finish fftw...\n"); for(k = 0; k < nn; k++) { printf("Squareing...%d\n", k); for(j = 0; j < nn; j++) { for(i = 0; i < cn2; i++) { index_0 = index_k(k, j, i); //r_part1 = delta1k[index_0][0]; //i_part1 = delta1k[index_0][1]; r_part2 = delta2k[index_0][0]; i_part2 = delta2k[index_0][1]; deltak2 = r_part2*r_part2 + i_part2*i_part2; //p1 = r_part1*r_part1 + i_part1*i_part1; //p2 = r_part2*r_part2 + i_part2*i_part2; delta1k[index_0][0] = deltak2;///sqrt(p1*p2); } } } printf("Finish square...\n"); /*===Finishing FFTW & Calculating module===*/ int x, y, z, ka, kb; double k2, k_mag, kv2, kv_mag, kz2, kz_mag, logk, logkv, logkz, Dlogk; double sincx, sincy, sincz, window, Wait; int countk[bins][bins] = {0.}; double countp[bins][bins] = {0.}; double k_bin[bins][bins] = {0.}; double p_bin[bins][bins] = {0.}; Dlogk = (log10(nn/2) - log10(1))/bins; //Calculating spacing in log bins printf("%f\t%f\t%d\t%f\t\n", log10(nn/2), log10(1), bins, Dlogk); printf("%d\t%d\n", nn, nn/2); 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 x = i; // index to calculating wavenumber if(j < cn2) y = j; else y = nn - j; if(k < cn2) z = k; else z = nn - k; k2 = x*x + y*y + z*z; kv2 = x*x + y*y; kz2 = z*z; if (k2 == 0) continue; if (kv2 == 0) { kb = 0; } else { kv_mag = sqrt(kv2); logkv = log10(kv_mag); kb = logkv/Dlogk; } if (kz2 == 0) { ka = 0; } else { kz_mag = sqrt(kz2); logkz = log10(kz_mag); ka = logkz/Dlogk; } if(ka >= bins) continue; if(kb >= bins) continue; /* if(x == 0) sincx = 1.; else sincx = sin(PI*x/nn)/(PI*x/nn); if(y == 0) sincy = 1.; else sincy = sin(PI*y/nn)/(PI*y/nn); if(z == 0) sincz = 1.; else sincz = sin(PI*z/nn)/(PI*z/nn); window = pow(sincx, 1)*pow(sincy, 1)*pow(sincz, 1); */ countk[ka][kb] = countk[ka][kb] + 1; countp[ka][kb] = countp[ka][kb] + 1.; k_bin[ka][kb] = k_bin[ka][kb] + k_mag; p_bin[ka][kb] = p_bin[ka][kb] + delta1k[index_0][0];///window; } } } printf("finish bins...\n"); for(i = 0; i < bins; i++) { for(j = 0; j < bins; j++) { printf("avaraging bins...%d\n", i); k_bin[i][j] = k_bin[i][j]/countk[i][j]; p_bin[i][j] = p_bin[i][j]/countp[i][j]; // k_bin[i] = k_bin[i]*kf; p_bin[i][j] = p_bin[i][j]*pow(box, 3)/pow(nn, 6); // p_bin[i] = p_bin[i]*pow(box, 3)/pow(nn, 6)*pow(k_bin[i], 3)/2./PI/PI; } } /*===Deconvolving window function & Caculating power specturm in bins===*/ FILE *OUT = fopen(pathout, "w"); for(i = 0; i < bins; i++) { for(j = 0; j < bins; j++) { fprintf(OUT, "%e\t", p_bin[i][j]); //printf("Outputing...%d\n", i); } fprintf(OUT, "\n"); } /*============================*/ fftw_destroy_plan(plan1); fftw_destroy_plan(plan2); fftw_free(delta1k); fftw_free(delta2k); fftw_free(delta1r); fftw_free(delta2r); return 0; }
/******************************************************************** NAME: potential FUNCTION: Calculates the potential of the contrast density in the k-space (from the FFT)in the grid[m] order, and then with an IFFT calculates the potential in the real space INPUT: density contrast in the k-space RETURN: File with the input and outputs (sorted in the grid[m] order) **********************************************************************/ int potential() { int m, i, j, k; double factor; FILE *pf=NULL; /*+++++ Computing the potential in k-space +++++*/ printf("Computing potential in k-space\n"); printf("-----------------------------------------\n"); /*----- Factor of the potential -----*/ factor = (-3.0/2.0) * (GV.H0*GV.H0) * GV.Omega_M0 / GV.a_SF; for(m=0; m<GV.NTOTK; m++) { if( gp[m].k_module > GV.ZERO ) { gp[m].poten_k[0] = factor * gp[m].DenCon_K[0]/(gp[m].k_module * gp[m].k_module); //Re() gp[m].poten_k[1] = factor * gp[m].DenCon_K[1]/(gp[m].k_module * gp[m].k_module); //Im() }//if else { gp[m].poten_k[0] = 0.0; //Re() gp[m].poten_k[1] = 0.0; //Im() }//else }//for m printf("Potential in k-space saved!\n"); printf("-----------------------------------------\n"); #ifdef OUTOFPLACE /*+++++ Definitions +++++*/ fftw_complex *in=NULL; double *out=NULL; fftw_complex *in2=NULL; fftw_plan plan_k2r; // FFTW from k-space to r-space fftw_plan plan_r2k; // FFTW from r-space to k-space /*----- Creating input/output arrays -----*/ in = (fftw_complex *) fftw_malloc( sizeof( fftw_complex ) * GV.NTOTK ); out = (double *) fftw_malloc( sizeof( double ) * GV.NTOTALCELLS ); /*----- Saving the potential input of the FFT -----*/ for(m=0; m<GV.NTOTK; m++) { in[m][0] = gp[m].poten_k[0]; //Re() in[m][1] = gp[m].poten_k[1]; //Im() }//for m /*----- Making the FFT -----*/ //plan_k2r = fftw_plan_dft_c2r_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, out, FFTW_ESTIMATE ); //out-of-place transform plan_k2r = fftw_plan_dft_c2r_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, out, FFTW_MEASURE ); //out-of-place transform fftw_execute( plan_k2r ); printf("FFT potential k2r finished!\n"); printf("---------------------------------------\n"); /*----- Saving the output data for an out-of-place transform -----*/ pf = fopen("./../Potential_r_out.dat", "w"); fprintf(pf, "%s%14s %15s\n", "#", "ID", "Poten(r)"); for( m=0; m<GV.NTOTALCELLS; m++ ) { gp[m].poten_r = out[m]/GV.NORM; //Re() fprintf(pf, "%10d %16.8lf\n", m, gp[m].poten_r ); }//for m fclose(pf); printf("---------------------------------------\n"); printf("Potential in r space from an out-of-place transform saved!\n"); printf("---------------------------------------\n"); /*----- Recreating input array -----*/ in2 = (fftw_complex *) fftw_malloc( sizeof( fftw_complex ) * GV.NTOTK ); plan_r2k = fftw_plan_dft_r2c_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, out, in2, FFTW_ESTIMATE ); fftw_execute( plan_r2k ); printf("Recreated input of potential in k-space from out-of-place transform performed\n"); printf("---------------------------------------\n"); /*+++++ Saving recreated data +++++*/ pf = fopen("./../Testing_potential_k_space.dat", "w"); fprintf(pf, "%s%14s %15s %15s %15s\n", "#", "Re_Pot(k)", "Im_Pot(k)", "Reconst_Re", "Reconst_Im"); for(m=0; m<GV.NTOTK; m++) { fprintf(pf, "%10d %20.8lf %20.8lf %20.8lf %20.8lf\n", m, gp[m].poten_k[0], gp[m].poten_k[1], in2[m][0]/(GV.NORM*GV.NORM), in2[m][1]/(GV.NORM*GV.NORM)); }//for m fclose(pf), printf("Recreated input of potential in k-space from out-of-place transform saved\n"); printf("---------------------------------------\n"); fftw_destroy_plan( plan_k2r ); fftw_destroy_plan( plan_r2k ); fftw_free( in ); fftw_free( in2 ); fftw_free( out ); #endif #ifdef INPLACE /*+++++ Definitions +++++*/ fftw_complex *in=NULL; fftw_plan plan_k2r; // FFTW from k-space to r-space fftw_plan plan_r2k; // FFTW from r-space to k-space /*----- Creating input/output arrays -----*/ in = (fftw_complex *) fftw_malloc( sizeof( fftw_complex ) * GV.NTOTALCELLS ); /*----- Saving the potential input of the FFT -----*/ for(m=0; m<GV.NTOTK; m++) { in[m][0] = gp[m].poten_k[0]; //Re() in[m][1] = gp[m].poten_k[1]; //Im() }//for m /*----- Making the FFT -----*/ //plan_k2r = fftw_plan_dft_c2r_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, (double *)in, FFTW_ESTIMATE ); //in-place transform plan_k2r = fftw_plan_dft_c2r_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, (double *)in, FFTW_MEASURE ); //in-place transform //plan_k2r = fftw_plan_dft_c2r_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, (double *)in, FFTW_IN_PLACE ); //in-place transform fftw_execute( plan_k2r ); /*----- Saving the output data for an in-place transform -----*/ for( m=0; m<GV.NTOTALCELLS/2; m++ ) { gp[2*m].poten_r = in[m][0]/GV.NORM; gp[2*m+1].poten_r = in[m][1]/GV.NORM; }//for m pf = fopen("./../Potential_r_in.dat", "w"); fprintf(pf, "%s%14s %15s\n", "#", "ID", "Poten(r)"); for( m=0; m<GV.NTOTALCELLS; m++ ) { fprintf(pf, "%10d %16.8lf\n", m, gp[m].poten_r ); }//for m fclose(pf); //fftw_free( in ); /*----- Recreating input array -----*/ //in = (double *) fftw_malloc( sizeof( double ) * GV.PADDING ); plan_r2k = fftw_plan_dft_r2c_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, (double*) in, in, FFTW_ESTIMATE ); //plan_r2k = fftw_plan_dft_r2c_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, (fftw_complex*)in, FFTW_IN_PLACE ); fftw_execute( plan_r2k ); printf("Recreated input of potential in k-space from out-of-place transform performed\n"); printf("---------------------------------------\n"); /*+++++ Saving recreated data +++++*/ pf = fopen("./../Testing_potential_k_space_in-place.dat", "w"); fprintf(pf, "%s%14s %15s %15s %15s\n", "#", "Re_Pot(k)", "Im_Pot(k)", "Reconst_Re", "Reconst_Im"); for(m=0; m<GV.NTOTK; m++) { fprintf(pf, "%10d %20.8lf %20.8lf %20.8lf %20.8lf\n", m, gp[m].poten_k[0], gp[m].poten_k[1], in[m][0]/(GV.NORM*GV.NORM), in[m][1]/(GV.NORM*GV.NORM)); }//for m fclose(pf), printf("Recreated input of potential in k-space from out-of-place transform saved\n"); printf("---------------------------------------\n"); fftw_free( in ); fftw_destroy_plan( plan_k2r ); fftw_destroy_plan( plan_r2k ); #endif printf("FFT_potential code finished!\n"); printf("----------------------------\n"); return 0; }//potential
int fftw3_test(GPU_INFO *gpu_info,CUFFT_INFO *cufft_info){ int i,j,k; double *array; int Nx=cufft_info->Nx; int Ny=cufft_info->Ny; int Nz=cufft_info->Nz; array=(double *)malloc(sizeof(double)*cufft_info->NxNyNz); double *in; fftw_complex *in_one; fftw_complex *out,*out_one; in=(double *)malloc(sizeof(double)*cufft_info->NxNyNz); out=(fftw_complex *)malloc(sizeof(fftw_complex)*cufft_info->NxNyNz); in_one=(fftw_complex *)malloc(sizeof(fftw_complex)*cufft_info->NxNyNz); out_one=(fftw_complex *)malloc(sizeof(fftw_complex)*cufft_info->NxNyNz); fftw_plan plan_forward; int temp; int rank=3;int n[3]; n[0]=cufft_info->Nx;n[1]=cufft_info->Ny;n[2]=cufft_info->Nz; unsigned flags; for(long ijk=0;ijk<cufft_info->NxNyNz;ijk++) { array[ijk]=ijk; in[ijk]=ijk; } int Nxh1=Nx/2+1; cufft_info->Nxh1NyNz=Nxh1*Ny*Nz; long ijk,ijkr; /*fftw_plan fftw_plan_dft_2d(int n0, int n1, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);*/ for(i=0;i<cufft_info->Nz;i++){ plan_forward=fftw_plan_dft_r2c_3d(1, Ny, Nx, in+Nx*Ny*i, out+Nx*Ny*i, FFTW_ESTIMATE); fftw_execute ( plan_forward ); } for(i=0;i<Nxh1;i++){ for(j=0;j<cufft_info->Ny;j++){ for(k=0;k<Nz;k++) {in_one[k][0]=out[i+j*Nxh1+k*Nx*Ny][0];in_one[k][1]=out[i+j*Nxh1+k*Nx*Ny][1];} //if(i==0&&j==0) for(k=0;k<Nz;k++) printf("%g %g\n",in_one[k][0],in_one[k][1]); plan_forward=fftw_plan_dft_1d(Nz, in_one, out_one,FFTW_FORWARD, FFTW_ESTIMATE); fftw_execute ( plan_forward ); for(k=0;k<Nz;k++) {out[i+j*Nxh1+k*Nx*Ny][0]=out_one[k][0];out[i+j*Nxh1+k*Nx*Ny][1]=out_one[k][1];} } } FILE *dp; dp=fopen("fftw3_compare.dat","w"); for(k=0;k<Nz;k++) for(j=0;j<Ny;j++) for(i=0;i<Nx;i++){ ijkr=(long)((k*Ny+j)*Nx+i); ijk=(long)(i+Nx*j+Nxh1*Ny*k); if(abs(out[ijkr][0])>0.0000001||abs(out[ijkr][1])>0.0000001) fprintf(dp,"%d %g %g\n",ijk,out[ijkr][0],out[ijkr][1]); } fclose(dp); for(i=0;i<Nxh1;i++){ for(j=0;j<cufft_info->Ny;j++){ for(k=0;k<Nz;k++) {in_one[k][0]=out[i+j*Nxh1+k*Nx*Ny][0];in_one[k][1]=out[i+j*Nxh1+k*Nx*Ny][1];} // for(k=0;k<Nz;k++) printf("%g %g\n",in_one[k][0],in_one[k][1]); plan_forward=fftw_plan_dft_1d(Nz, in_one, out_one,FFTW_BACKWARD, FFTW_ESTIMATE); fftw_execute ( plan_forward ); //for(k=0;k<Nz;k++) printf("%g %g\n",out_one[k][0],out_one[k][1]); for(k=0;k<Nz;k++) {out[i+j*Nxh1+k*Nx*Ny][0]=out_one[k][0];out[i+j*Nxh1+k*Nx*Ny][1]=out_one[k][1];} //for(k=0;k<Nz;k++) printf("%g %g\n",out_one[k][0],out_one[k][1]); } } for(i=0;i<16;i++) {out[i][0]=i;out[i][1]=0;} plan_forward=fftw_plan_dft_c2r_3d(2, 8, 1, out,in, FFTW_ESTIMATE); fftw_execute ( plan_forward ); /* for(i=0;i<cufft_info->Nz;i++){ //for(k=0;k<8;k++) printf("%g %g\n",out[k+8*i][0],out[k+8*i][1]); plan_forward=fftw_plan_dft_c2r_3d(1, 8, 1, out+Nx*Ny*i,in+Nx*Ny*i, FFTW_ESTIMATE); fftw_execute ( plan_forward ); } */ //for(i=0;i<16;i++) {printf("%g\n",in[i]);} /* for(k=0;k<Nz;k++) for(j=0;j<Ny;j++) for(i=0;i<Nxh1;i++){ //ijk=(long)((k*Ny+j)*Nxh1+i); ijkr=(long)((k*Ny+j)*Nx+i); ijk=(long)(k*Nx*Ny+j*Nxh1+i); if(abs(out[ijk][0])>=0.00000000001||abs(out[ijk][1])>=0.00000000001){ fprintf(dp,"%d %g %g %g\n",ijkr,out[ijk][0],out[ijk][1],in[ijkr]/512); } } */ printf("finish writiing\n"); free(array); free(in); free(out); return 1; }
/*==============================*/ 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; }
void compute_measures ( char **argv, int block_size, int dim_x, int dim_y, int dim_z, int FFT, FILE *file_A, FILE *file_B, int peak) { int counter = 0; double mse, rmse, snr, snr_db, psnr, psnr_db; TYPE *buf_A = (TYPE *)malloc(sizeof(TYPE) * block_size * DIMENSION_Z); TYPE *buf_B = (TYPE *)malloc(sizeof(TYPE) * block_size * DIMENSION_Z); int block; // FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT FFT if(FFT) { /*--FFT: Specifies the use of the Fourier domain to carry out the comparison. This domain is invariant to a shift of the average amplitude of the signal and a constant shift between the samples, which is much more likely to the way the human beings perceive signals.*/ // reserva espacio de memoria para las 2 señales. double *signal_A = (double *)fftw_malloc(sizeof(double) * block_size * DIMENSION_Z); double *signal_B = (double *)fftw_malloc(sizeof(double) * block_size * DIMENSION_Z); // reserva espacio de memoria para las 2 señales en 3 estructuras de datos para FFT fftw_complex *fourier_A = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * block_size * DIMENSION_Z); // dim_x * (dim_y/2+1) fftw_complex *fourier_B = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * block_size * DIMENSION_Z); fftw_plan f_A = fftw_plan_dft_r2c_3d(dim_x, dim_y, dim_z, signal_A, fourier_A, 0); // 0 ó FFTW_ESTIMATE ó FFTW_MEASURE http://www.fftw.org/doc/Complex-One_002dDimensional-DFTs.html fftw_plan f_B = fftw_plan_dft_r2c_3d(dim_x, dim_y, dim_z, signal_B, fourier_B, 0); // El espectro es invariante de la fase. Se comparan los espectros. double *spectrum_A = (double *)malloc(sizeof(double) * block_size * DIMENSION_Z); double *spectrum_B = (double *)malloc(sizeof(double) * block_size * DIMENSION_Z); // snr con FFT double energy_A=0, energy_B=0, energy_error=0; // unsigned printf("%s: performing the FFT!\n",argv[0]); int i; for(block = 0;; block * DIMENSION_Z) { // Contabiliza la cantidad de energia de cada señal y su diferencia para cada porción de las señales, de tamaño block (cuadro del vídeo) double local_energy_error = energy_error, local_energy_A = energy_A; int local_counter = counter; int r_A = fread(buf_A, sizeof(TYPE), block_size * DIMENSION_Z, file_A); int r_B = fread(buf_B, sizeof(TYPE), block_size * DIMENSION_Z, file_B); // Establece la condición del bucle: hasta que una de las 2 señales se termine. int min = r_B; if(r_A < r_B) min = r_A; // Populates and execution. // A if(min==0) break; { for(i=0; i<min; i++) { signal_A[i] = buf_A[i]; } } fftw_execute(f_A); for(i=0; i<min/2; i++) { spectrum_A[i] = sqrt(fourier_A[i][0]*fourier_A[i][0] + fourier_A[i][1]*fourier_A[i][1]); } // B if(min==0) break; { for(i=0; i<min; i++) { signal_B[i] = buf_B[i]; } } fftw_execute(f_B); for(i=0; i<min/2; i++) { spectrum_B[i] = sqrt(fourier_B[i][0]*fourier_B[i][0] + fourier_B[i][1]*fourier_B[i][1]); } // Contabiliza la cantidad de energia de cada señal y su diferencia. double a,b,ab; for(i=0; i<min/2; i++) { a = spectrum_A[i]; // porción de la señal A (seguramente píxel) b = spectrum_B[i]; // porción de la señal B (seguramente píxel) energy_A += a*a; // acumulación de la energía de la señal A energy_B += b*b; // acumulación de la energía de la señal B ab = a - b; // diferencia = error entre ambas señales energy_error += ab*ab; // acumulación del error entre ambas señales counter++; // resulta con el tamaño de la porción de señal que se está tratando (seguramente una imagen) } // -------- local_energy_error = error para cada block (para cada imagen) if(energy_error) { // Ambas señales son distintas (a nivel de imagen) local_energy_error = energy_error - local_energy_error; // por la forma en que se va contabilizando "energy_error" para tener la "local_energy_error" se resta todo el error que hemos ido contando que está en "energy_error" MENOS el error de la imágen anterior, que está en "local_energy_error". local_counter = counter - local_counter; // " local_energy_A = energy_A - local_energy_A; // " mse=local_energy_error/(double)(local_counter); psnr=(double)(peak)*(double)(peak)/mse; psnr_db=10.0*log10(psnr); rmse=sqrt(mse); snr=local_energy_A/local_energy_error; snr_db=10.0*log10(snr); } else { // Ambas señales son iguales (a nivel de imagen) snr_db=1.0; psnr_db=1.0; //printf("SNR infinito !!!\n"); //return 1; } fprintf(stderr,"%3d\t%f\n", block, psnr_db); } // for(block = 0;; block++) // -------- Calcula resultados if(energy_error) { mse=(double)(energy_error)/(double)(counter); psnr=(double)(peak)*(double)(peak)/mse; psnr_db=10.0*log10(psnr); rmse=sqrt(mse); snr=(double)(energy_A)/(double)(energy_error); snr_db=10.0*log10(snr); } else { mse=0.0; psnr=1.0; psnr_db=1.0; rmse=0.0; snr=1.0; snr_db=1.0; //printf("SNR infinito !!!\n"); //return 1; } // -------- RESULTADOS printf("Energy_A\t=\t%f\n",energy_A); printf("Energy_B\t=\t%f\n",energy_B); printf("Energy_error\t=\t%f\n",energy_error); printf("Number of samples\t=\t%d\n",counter); printf("MSE\t=\t%f\n",mse); printf("RMSE\t=\t%f\n",rmse); printf("SNR\t=\t%f\n",snr); printf("SNR[dB]\t=\t%f\n",snr_db); printf("PSNR\t=\t%f\n",psnr); printf("PSNR[dB]\t=\t%f\n",psnr_db); // -------- Free memory fftw_destroy_plan(f_A); fftw_destroy_plan(f_B); fftw_free(fourier_A); fftw_free(fourier_B); // !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT !FFT } else { // Pág. 231 SNR // snr sin FFT long long energy_A=0, energy_B=0, energy_error=0; // unsigned for(block = 0;; block++) { // Contabiliza la cantidad de energia de cada señal y su diferencia para cada porción de las señales, de tamaño block (cuadro del video) long long local_energy_error = energy_error, local_energy_A = energy_A; int local_counter = counter; int r_A = fread(buf_A,sizeof(TYPE),block_size,file_A); // Lee la primera imagen de la señal A (original) int r_B = fread(buf_B,sizeof(TYPE),block_size,file_B); // Lee la primera imagen de la señal B (reconstruido) // Establece la condición del bucle: hasta que una de las 2 señales se termine. int min = r_B; if(r_A < r_B) min = r_A; // Contabiliza la cantidad de energia de cada señal y su diferencia. if(min==0) break; { int a,b,ab; for(int i=0; i<min; i++) { a = buf_A[i]; // porción de la señal A (seguramente píxel) b = buf_B[i]; // porción de la señal B (seguramente píxel) energy_A += a*a; // acumulación de la energía de la señal A energy_B += b*b; // acumulación de la energía de la señal B ab = a - b; // diferencia = error entre ambas señales energy_error += ab*ab; // acumulación del error entre ambas señales counter++; // resulta con el tamaño de la porción de señal que se está tratando (seguramente una imagen) } } // -------- local_energy_error = error para cada block (para cada imagen) if(energy_error) { // Ambas señales son distintas (a nivel de imagen) local_energy_error = energy_error - local_energy_error; // por la forma en que se va contabilizando "energy_error" para tener la "local_energy_error" se resta todo el error que hemos ido contando que está en "energy_error" MENOS el error de la imágen anterior, que está en "local_energy_error". local_counter = counter - local_counter; // " local_energy_A = energy_A - local_energy_A; // " mse=(double)(local_energy_error)/(double)(local_counter); psnr=(double)(peak)*(double)(peak)/mse; psnr_db=10.0*log10(psnr); rmse=sqrt(mse); snr=(double)(local_energy_A)/(double)(local_energy_error); snr_db=10.0*log10(snr); } else { // Ambas señales son iguales (a nivel de imagen) snr_db=1.0; psnr_db=1.0; //printf("SNR infinito !!!\n"); //return 1; } fprintf(stderr,"%3d\t%f\n", block, psnr_db); } // for(block = 0;; block++) // -------- Calcula resultados if(energy_error) { // Ambas señales son distintas (a nivel de video) mse=(double)(energy_error)/(double)(counter); psnr=(double)(peak)*(double)(peak)/mse; psnr_db=10.0*log10(psnr); rmse=sqrt(mse); snr=(double)(energy_A)/(double)(energy_error); snr_db=10.0*log10(snr); } else { // Ambas señales son iguales (a nivel de video) mse=0.0; psnr=1.0; psnr_db=1.0; rmse=0.0; snr=1.0; snr_db=1.0; //printf("SNR infinito !!!\n"); //return 1; } // -------- RESULTADOS printf("Energy_A\t=\t%Ld\n",energy_A); printf("Energy_B\t=\t%Ld\n",energy_B); printf("Energy_error\t=\t%Ld\n",energy_error); printf("Number of samples\t=\t%d\n",counter); printf("MSE\t=\t%f\n",mse); printf("RMSE\t=\t%f\n",rmse); printf("SNR\t=\t%f\n",snr); printf("SNR[dB]\t=\t%f\n",snr_db); printf("PSNR\t=\t%f\n",psnr); printf("PSNR[dB]\t=\t%f\n",psnr_db); } } //void compute_measures
/*==============================*/ int main (void) { fftw_complex *deltak; double *deltar; double *deltars; fftw_plan plan; fftw_plan plans; int nn = 1024; // 768 could be changed to nc int cn2= nn/2 + 1; int N = nn*nn*nn; int Nc = nn*nn*cn2; deltak = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Nc); deltar = (double *) fftw_malloc(N * sizeof(double)); deltars= (double *) fftw_malloc(N * sizeof(double)); plan = fftw_plan_dft_r2c_3d(nn, nn, nn, deltar, deltak, FFTW_ESTIMATE); plans= fftw_plan_dft_c2r_3d(nn, nn, nn, deltak, deltars,FFTW_ESTIMATE); /*===Finishing FFTW initialization===*/ int i, j, k, index_0; float input; FILE *DEN = fopen(path, "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(&input, 4, 1, DEN); deltar[index_0] = input; } } } printf("Finish reading...\n"); /*===Finishing reading data===*/ fftw_execute(plan); printf("Finish fftw for the first time...\n"); /*===Finishing FFTW one===*/ double r_part, i_part; int x, y, z; double k2, factor, window; 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_part = deltak[index_0][0]; i_part = deltak[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; //factor = (-1.)*k2*kf*kf*R*R/2.; window = 1.; deltak[index_0][0] = i_part*window*kf*y*(-1.); deltak[index_0][1] = r_part*window*kf*y; } } } fftw_execute(plans); /*===Multiplying window function===*/ FILE *OUT = fopen(pathout, "wb"); 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); input = deltars[index_0]/pow(nc, 3); fwrite(&input, 4, 1, OUT); } } } /*============================*/ fftw_destroy_plan(plan); fftw_destroy_plan(plans); fftw_free(deltak); fftw_free(deltar); fftw_free(deltars); return 0; }
/****************************************************************************** NAME: transform FUNCTION: makes a FFT of an 3D input array and the inverse FFT to obtain the initial array to verify. Reorganizes the order of the output array to put it in an order according to the filled of the grid[m]. INPUT: A file with the data of densities and velocities. The files contains 11 columns: 1.Cell ID - 2.Density - 3,4,5.gp[m].pos[X,Y,Z] - 6,7,8. gp[m].v_cm[X,Y,Z] - 9,10,11 gp[m].avg_v[X,Y,Z] columns are used. RETURN: The output of the FFT ordered in c-order ******************************************************************************/ int transform() { /*--- DEFINITIONS ---*/ int m, i, j, k; double fx, fy, fz, k2; double wx_NGP, wy_NGP, wz_NGP, wx_CIC, wy_CIC, wz_CIC; double fundamental_freq; FILE *pf=NULL; /*---------------------------------------------------------------------------- FFT OF DENSITIES --------------------------------------------------------------------------*/ /****** OUT-OF-PLACE TRANSFORM ******/ #ifdef OUTOFPLACE /*------ Definitions for the out-of-place transform ------*/ double *in=NULL; fftw_complex *out=NULL; fftw_plan plan_r2k; //plan_forward double *in2=NULL; fftw_plan plan_k2r; //plan_backward /*+++++ Creating the input/output array +++++*/ in = (double *) fftw_malloc( sizeof( double )*GV.NTOTALCELLS); //out-of-place transform out = (fftw_complex *) fftw_malloc( sizeof( fftw_complex )*GV.NTOTK); /*----- Copying DenCon data to input array -----*/ for(m=0; m<GV.NTOTALCELLS; m++) { in[m] = gp[m].DenConCell; //Re(DenCon_in) }//for m printf("Copy of input of Density Contrast for FFTW finished.\n"); printf("-----------------------------------------------------------------\n"); /*--- Making the FFT ---*/ plan_r2k = fftw_plan_dft_r2c_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, out, FFTW_ESTIMATE ); //Out-of-place transform fftw_execute( plan_r2k ); printf("FFT: density contrast r2k out-of-place finished!\n"); printf("-----------------------------------------------------------------\n"); /*--- Saving the output of the out-of-place transform ---*/ pf = fopen("./../DenCon_k_raw.dat", "w"); fprintf(pf, "%s%14s %15s\n", "#", "Re_DenCon", "Im_DenCon"); for(m=0; m<GV.NTOTK; m++) { gp[m].DenCon_FFTout[0] = out[m][0]/GV.NORM; //Re() gp[m].DenCon_FFTout[1] = out[m][1]/GV.NORM; //Im() fprintf(pf, "%10d %16.8lf %16.8lf\n", m, out[m][0], out[m][1]); }//for m fclose(pf); /*+++++ Recreating the input +++++*/ in2 = (double *) fftw_malloc( sizeof(double) * GV.NTOTALCELLS ); plan_k2r = fftw_plan_dft_c2r_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, out, in2, FFTW_ESTIMATE ); fftw_execute( plan_k2r ); printf("Inverse FFT for contrast density finished!\n"); printf("-----------------------------------------------------------------\n"); /*----- Saving recreated data in the out-of-place transform------*/ pf = fopen("./../Testing_c2r.dat", "w"); fprintf(pf, "%s%9s %15s\n", "#", "DenCon", "Reconstruted"); for(m=0; m<GV.NTOTALCELLS; m++) { fprintf(pf, "%10d %16.8lf %16.8lf\n", m, gp[m].DenConCell, in2[m]/(GV.NORM*GV.NORM)); }//for m fclose(pf); /*--- Freeing up memory! ---*/ printf("Freeing up memory!\n"); printf("--------------------------------------------------\n"); fftw_free(in); fftw_free(in2); fftw_free(out); /*--- Destroying plans ---*/ printf("Destroying plans!\n"); printf("--------------------------------------------------\n"); fftw_destroy_plan( plan_r2k ); printf("plan_r2k destroyed!"); fftw_destroy_plan( plan_k2r ); printf("plan_r2k destroyed!"); #endif /****** IN-PLACE TRANSFORM ******/ #ifdef INPLACE double *in=NULL; fftw_plan plan_r2k; //plan_forward fftw_plan plan_k2r; //plan_backward /*+++++ Creating the input/output array +++++*/ in = (double *) fftw_malloc( sizeof( double )*GV.PADDING); //in-place transform /*----- Copying DenCon data to input array -----*/ for(m=0; m<GV.NTOTALCELLS; m++) { in[m] = gp[m].DenConCell; //Re(DenCon_in) }//for m printf("Copy of input of Density Contrast for FFTW finished.\n"); printf("-----------------------------------------------------------------\n"); /*--- Making the FFT ---*/ plan_r2k = fftw_plan_dft_r2c_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, (fftw_complex*)in, FFTW_ESTIMATE ); //In-place transform //plan_r2k = fftw_plan_dft_r2c_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, in, (fftw_complex*)in, FFTW_IN_PLACE ); //In-place transform fftw_execute( plan_r2k ); printf("FFT: density contrast r2k in-place finished!\n"); printf("-----------------------------------------------------------------\n"); /*--- Saving the output of the in-place transform ---*/ pf = fopen("./../DenCon_k_raw_in-place.dat", "w"); fprintf(pf, "%s%14s %15s\n", "#", "Re_DenCon", "Im_DenCon"); for(m=0; m<GV.NTOTK; m++) { gp[m].DenCon_FFTout[0] = in[2*m]/GV.NORM; //Re() gp[m].DenCon_FFTout[1] = in[2*m+1]/GV.NORM; //Im() fprintf(pf, "%10d %16.8lf %16.8lf\n", m, in[2*m], in[2*m+1]); }//for m fclose(pf); //fftw_free(in); /*+++++ Recreating the input +++++*/ //in = (double *) fftw_malloc( sizeof( double )*GV.PADDING); //in-place transform plan_k2r = fftw_plan_dft_c2r_3d( GV.NCELLS, GV.NCELLS, GV.NCELLS, (fftw_complex*)in, in, FFTW_ESTIMATE ); fftw_execute( plan_k2r ); /*----- Saving recreated data in the in-place transform------*/ pf = fopen("./../Testing_c2r_in-place.dat", "w"); fprintf(pf, "%s%9s %15s\n", "#", "DenCon", "In-place_rec"); for(m=0; m<GV.NTOTALCELLS; m++) { fprintf(pf, "%10d %16.8lf %16.8lf\n", m, gp[m].DenConCell, in[m]/(GV.NORM*GV.NORM) ); }//for m fclose(pf); /*--- Freeing up memory! ---*/ printf("Freeing up memory!\n"); printf("--------------------------------------------------\n"); fftw_free(in); /*--- Destroying plans ---*/ printf("Destroying plans!\n"); printf("--------------------------------------------------\n"); fftw_destroy_plan( plan_r2k ); printf("plan_r2k destroyed!"); fftw_destroy_plan( plan_k2r ); printf("plan_r2k destroyed!"); #endif /*+++++ K vector: components and module +++++*/ fundamental_freq = 2.0*M_PI/(1.0*GV.BoxSize); for(i=0; i<GV.NCELLS; i++) { for(j=0; j<GV.NCELLS; j++) { for(k=0; k<=GV.CNMESH; k++) { //m = INDEX_GRID(i,j,k); //ID in C-order m = INDEX_K(i,j,k); //ID in C-order for Fourier space after r2c /*::: k_x :::*/ gp[m].k_vector[X] = fundamental_freq * KVALUE(i); /*::: k_y :::*/ gp[m].k_vector[Y] = fundamental_freq * KVALUE(j); /*::: k_z :::*/ gp[m].k_vector[Z] = fundamental_freq * KVALUE(k); /*::: k-vector module :::*/ k2 = gp[m].k_vector[X]*gp[m].k_vector[X] + gp[m].k_vector[Y]*gp[m].k_vector[Y] + gp[m].k_vector[Z]*gp[m].k_vector[Z] ; gp[m].k_module = sqrt(k2); }//for k }//for j }//for i printf("k vectors computed!\n"); printf("------------------------------------------------\n"); /*--- Density contrast in k-space with NGP weight function ---*/ #ifdef NGP printf("Computing density contrast in k space with NGP weight fn!\n"); printf("------------------------------------------------\n"); for(m=0; m<GV.NTOTALCELLS; m++) { /*----- Weight function in x -----*/ if(fabs(gp[m].k_vector[X]) > GV.ZERO) { fx = (gp[m].k_vector[X]*GV.BoxSize)/(2.0*GV.NCELLS); wx_NGP = (sin(fx)/fx); }//if 1 else { wx_NGP = 1.0; }//else /*----- Weight function in y -----*/ if(fabs(gp[m].k_vector[Y]) > GV.ZERO) { fy = (gp[m].k_vector[Y]*GV.BoxSize)/(2.0*GV.NCELLS); wy_NGP = (sin(fy)/fy); }//if 1 else { wy_NGP = 1.0; }//else /*----- Weight function in z -----*/ if(fabs(gp[m].k_vector[Z]) > GV.ZERO) { fz = (gp[m].k_vector[Z]*GV.BoxSize)/(2.0*GV.NCELLS); wz_NGP = (sin(fz)/fz); }//if 1 else { wz_NGP = 1.0; }//else /*----- Total weight function -----*/ gp[m].weight_NGP = wx_NGP*wy_NGP*wz_NGP; /*----- Deconvolution of DenCon -----*/ if(fabs(gp[m].weight_NGP) > GV.ZERO) { gp[m].DenCon_K[0] = gp[m].DenCon_FFTout[0] / gp[m].weight_NGP; gp[m].DenCon_K[1] = gp[m].DenCon_FFTout[1] / gp[m].weight_NGP; }//if else { gp[m].DenCon_K[0] = 0.0; gp[m].DenCon_K[1] = 0.0; }//else }//for m printf("Density contrast in k-space with NGP weight fn ready!!\n"); printf("------------------------------------------------\n"); #endif /*--- Density contrast in k-space with CIC weight function ---*/ #ifdef CIC printf("Computing density contrast in k space with CIC weight-function!\n"); printf("------------------------------------------------\n"); for(m=0; m<GV.NTOTALCELLS; m++) { /*----- Weight function in x -----*/ if(fabs(gp[m].k_vector[X]) > GV.ZERO) { fx = (gp[m].k_vector[X]*GV.BoxSize)/(2.0*GV.NCELLS); wx_CIC = (sin(fx)/fx)*(sin(fx)/fx); }//if 1 else { wx_CIC = 1.0; }//else /*----- Weight function in y -----*/ if(fabs(gp[m].k_vector[Y]) > GV.ZERO) { fy = (gp[m].k_vector[Y]*GV.BoxSize)/(2.0*GV.NCELLS); wy_CIC = (sin(fy)/fy)*(sin(fy)/fy); }//if 1 else { wy_CIC = 1.0; }//else /*----- Weight function in z -----*/ if(fabs(gp[m].k_vector[Z]) > GV.ZERO) { fz = (gp[m].k_vector[Z]*GV.BoxSize)/(2.0*GV.NCELLS); wz_CIC = (sin(fz)/fz)*(sin(fz)/fz); }//if 1 else { wz_CIC = 1.0; }//else /*----- Total weight function -----*/ gp[m].weight_CIC = wx_CIC*wy_CIC*wz_CIC; /*----- Deconvolution of DenCon with the total weight function -----*/ if(fabs(gp[m].weight_CIC) > GV.ZERO) { gp[m].DenCon_K[0] = gp[m].DenCon_FFTout[0] / gp[m].weight_CIC; gp[m].DenCon_K[1] = gp[m].DenCon_FFTout[1] / gp[m].weight_CIC; }//if else { gp[m].DenCon_K[0] = 0.0; gp[m].DenCon_K[1] = 0.0; }//else gp[m].DenCon_K_2 = gp[m].DenCon_K[0]*gp[m].DenCon_K[0] + gp[m].DenCon_K[1]*gp[m].DenCon_K[1]; if(gp[m].DenCon_K_2 < 0.0) { printf("Negative Delta^2=%lf for m=%d\n", gp[m].DenCon_K_2, m); } }//for m printf("Density contrast in k-space with CIC weight fn ready!!\n"); printf("-----------------------------------------------------------------\n"); #endif printf("FFT_transform code finished!\n"); printf("--------------------------------------------------\n"); return 0; }//transform
PetscInt main(PetscInt argc,char **args) { typedef enum {RANDOM, CONSTANT, TANH, NUM_FUNCS} FuncType; const char *funcNames[NUM_FUNCS] = {"random", "constant", "tanh"}; PetscMPIInt size; PetscInt n = 10,N,Ny,ndim=4,dim[4],DIM,i; Vec x,y,z; PetscScalar s; PetscRandom rdm; PetscReal enorm; PetscInt func=RANDOM; FuncType function = RANDOM; PetscBool view = PETSC_FALSE; PetscErrorCode ierr; PetscScalar *x_array,*y_array,*z_array; fftw_plan fplan,bplan; const ptrdiff_t N0 = 20, N1 = 20; ptrdiff_t alloc_local, local_n0, local_0_start; ierr = PetscInitialize(&argc,&args,(char *)0,help);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This example requires real numbers"); #endif ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); alloc_local=fftw_mpi_local_size_2d(N0, N1, PETSC_COMM_WORLD, &local_n0, &local_0_start); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This is a uniprocessor example only!"); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, PETSC_NULL, "FFTW Options", "ex142");CHKERRQ(ierr); ierr = PetscOptionsEList("-function", "Function type", "ex142", funcNames, NUM_FUNCS, funcNames[function], &func, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-vec_view draw", "View the functions", "ex112", view, &view, PETSC_NULL);CHKERRQ(ierr); function = (FuncType) func; ierr = PetscOptionsEnd();CHKERRQ(ierr); for (DIM = 0; DIM < ndim; DIM++){ dim[DIM] = n; /* size of real space vector in DIM-dimension */ } ierr = PetscRandomCreate(PETSC_COMM_SELF, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); for (DIM = 1; DIM < 5; DIM++){ /* create vectors of length N=dim[0]*dim[1]* ...*dim[DIM-1] */ /*----------------------------------------------------------*/ N = Ny = 1; for (i = 0; i < DIM-1; i++) { N *= dim[i]; } Ny = N; Ny *= 2*(dim[DIM-1]/2 + 1); /* add padding elements to output vector y */ N *= dim[DIM-1]; ierr = PetscPrintf(PETSC_COMM_SELF, "\n %d-D: FFTW on vector of size %d \n",DIM,N);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,Ny,&y);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = VecDuplicate(x,&z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); /* Set fftw plan */ /*----------------------------------*/ ierr = VecGetArray(x,&x_array);CHKERRQ(ierr); ierr = VecGetArray(y,&y_array);CHKERRQ(ierr); ierr = VecGetArray(z,&z_array);CHKERRQ(ierr); unsigned int flags = FFTW_ESTIMATE; //or FFTW_MEASURE /* The data in the in/out arrays is overwritten during FFTW_MEASURE planning, so such planning should be done before the input is initialized by the user. */ printf("DIM: %d, N %d, Ny %d\n",DIM,N,Ny); switch (DIM){ case 1: fplan = fftw_plan_dft_r2c_1d(dim[0], (double *)x_array, (fftw_complex*)y_array, flags); bplan = fftw_plan_dft_c2r_1d(dim[0], (fftw_complex*)y_array, (double *)z_array, flags); break; case 2: fplan = fftw_plan_dft_r2c_2d(dim[0],dim[1],(double *)x_array, (fftw_complex*)y_array,flags); bplan = fftw_plan_dft_c2r_2d(dim[0],dim[1],(fftw_complex*)y_array,(double *)z_array,flags); break; case 3: fplan = fftw_plan_dft_r2c_3d(dim[0],dim[1],dim[2],(double *)x_array, (fftw_complex*)y_array,flags); bplan = fftw_plan_dft_c2r_3d(dim[0],dim[1],dim[2],(fftw_complex*)y_array,(double *)z_array,flags); break; default: fplan = fftw_plan_dft_r2c(DIM,dim,(double *)x_array, (fftw_complex*)y_array,flags); bplan = fftw_plan_dft_c2r(DIM,dim,(fftw_complex*)y_array,(double *)z_array,flags); break; } ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr); ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr); ierr = VecRestoreArray(z,&z_array);CHKERRQ(ierr); /* Initialize Real space vector x: The data in the in/out arrays is overwritten during FFTW_MEASURE planning, so planning should be done before the input is initialized by the user. --------------------------------------------------------*/ if (function == RANDOM) { ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); } else if (function == CONSTANT) { ierr = VecSet(x, 1.0);CHKERRQ(ierr); } else if (function == TANH) { ierr = VecGetArray(x, &x_array);CHKERRQ(ierr); for (i = 0; i < N; ++i) { x_array[i] = tanh((i - N/2.0)*(10.0/N)); } ierr = VecRestoreArray(x, &x_array);CHKERRQ(ierr); } if (view) { ierr = VecView(x, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* FFT - also test repeated transformation */ /*-------------------------------------------*/ ierr = VecGetArray(x,&x_array);CHKERRQ(ierr); ierr = VecGetArray(y,&y_array);CHKERRQ(ierr); ierr = VecGetArray(z,&z_array);CHKERRQ(ierr); for (i=0; i<3; i++){ /* FFTW_FORWARD */ fftw_execute(fplan); //printf("\n fout:\n"); //fftw_complex* fout = (fftw_complex*)y_array; //for (i=0; i<N/2+1; i++) printf("%d (%g %g)\n",i,fout[i][0],fout[i][1]); /* FFTW_BACKWARD: destroys its input array 'y_array' even for out-of-place transforms! */ fftw_execute(bplan); } ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr); ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr); ierr = VecRestoreArray(z,&z_array);CHKERRQ(ierr); /* Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ /*------------------------------------------------------------------*/ s = 1.0/(PetscReal)N; ierr = VecScale(z,s);CHKERRQ(ierr); if (view) {ierr = VecView(x, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} if (view) {ierr = VecView(z, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-11){ ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %G\n",enorm);CHKERRQ(ierr); } /* free spaces */ fftw_destroy_plan(fplan); fftw_destroy_plan(bplan); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); } ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc, char * argv[]) { fftw_plan pc2r; fftw_plan pr2c; fftw_complex *dvdk; DIR* dir; float *temp; char fname[256]; FILE *fid,*fidtxt, *fidtxt2; double *t21, *dvdr; long int i,j,p,indi,indj; int nmaxcut,nmincut; double aver,Tcmb,kk,growth,dgdt,Hubz,TS,xtot; double zmin,zmax,dz,z; /* Check for correct number of parameters*/ if(argc != 2) { printf("Usage : t21 base_dir\n"); exit(1); } get_Simfast21_params(argv[1]); if(global_use_Lya_xrays==0) printf("Lya and xray use set to false - assuming TS>>TCMB in t21 calculation.\n"); zmin=global_Zminsim; zmax=global_Zmaxsim; dz=global_Dzsim; #ifdef _OMPTHREAD_ omp_set_num_threads(global_nthreads); fftw_init_threads(); fftw_plan_with_nthreads(global_nthreads); printf("Using %d threads\n",global_nthreads); #endif /* Create directory deltaTb */ sprintf(fname,"%s/deltaTb",argv[1]); if((dir=opendir(fname))==NULL) { printf("Creating t21 directory\n"); if(mkdir(fname,(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))!=0) { printf("Error creating directory!\n"); exit(1); } } sprintf(fname,"%s/Output_text_files/t21_av_N%ld_L%.1f.dat",argv[1],global_N_smooth,global_L/global_hubble); if((fidtxt=fopen(fname,"a"))==NULL){ printf("\nError opening output %s file...\n",fname); exit(1); } sprintf(fname,"%s/Output_text_files/TS_av_N%ld_L%.1f.dat",argv[1],global_N_smooth,global_L/global_hubble); if((fidtxt2=fopen(fname,"a"))==NULL){ printf("\nError opening output %s file...\n",fname); exit(1); } if(!(temp=(float *) malloc(global_N3_smooth*sizeof(float)))) { printf("Problem...\n"); exit(1); } if(!(t21=(double *) malloc(global_N3_smooth*sizeof(double)))) { printf("Problem...\n"); exit(1); } if(!(dvdk = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*global_N_smooth*global_N_smooth*(global_N_smooth/2+1)))) { printf("Problem...\n"); exit(1); } if(!(dvdr=(double *) fftw_malloc(global_N3_smooth*sizeof(double)))) { printf("Problem...\n"); exit(1); } if(!(pr2c=fftw_plan_dft_r2c_3d(global_N_smooth, global_N_smooth, global_N_smooth, dvdr , dvdk, FFTW_MEASURE))) { printf("Problem...\n"); exit(1); } if(!(pc2r=fftw_plan_dft_c2r_3d(global_N_smooth, global_N_smooth, global_N_smooth, dvdk, dvdr, FFTW_MEASURE))) { printf("Problem...\n"); exit(1); } /**************************************************/ /************** redshift cycle ********************/ /**************************************************/ for(z=zmax;z>(zmin-dz/10);z-=dz){ printf("z = %f\n",z);fflush(0); sprintf(fname,"%s/deltaTb/deltaTb_z%.3lf_N%ld_L%.1f.dat",argv[1],z,global_N_smooth,global_L/global_hubble); if((fid = fopen(fname,"rb"))!=NULL) { printf("File:%s already exists - skipping this redshift...\n",fname); fclose(fid); }else { if(z>(global_Zminsfr-global_Dzsim/10) && global_use_Lya_xrays==1) { Tcmb=Tcmb0*(1.+z); sprintf(fname,"%s/x_c/xc_z%.3lf_N%ld_L%.1f.dat",argv[1],z,global_N_smooth,global_L/global_hubble); if((fid = fopen(fname,"rb"))==NULL) { printf("Error opening file:%s\n",fname); exit(1); } fread(temp,sizeof(float),global_N3_smooth,fid); fclose(fid); for(i=0;i<global_N3_smooth;i++) t21[i]=(double)temp[i]; sprintf(fname,"%s/Lya/xalpha_z%.3lf_N%ld_L%.1f.dat",argv[1],z,global_N_smooth,global_L/global_hubble); if((fid = fopen(fname,"rb"))==NULL) { printf("Error opening file:%s\n",fname); exit(1); } fread(temp,sizeof(float),global_N3_smooth,fid); fclose(fid); aver=0.; for(i=0;i<global_N3_smooth;i++) { xtot=(double)temp[i]+t21[i]; t21[i]=xtot/(1.+xtot); } sprintf(fname,"%s/xrays/TempX_z%.3lf_N%ld_L%.1f.dat",argv[1],z,global_N_smooth,global_L/global_hubble); if((fid = fopen(fname,"rb"))==NULL) { printf("Error opening file:%s\n",fname); exit(1); } fread(temp,sizeof(float),global_N3_smooth,fid); fclose(fid); TS=0.; for(i=0;i<global_N3_smooth;i++) { t21[i]=t21[i]*(1.-Tcmb/(double)temp[i]); // Temperature correction for high redshifts TS+=Tcmb/(1.-t21[i]); } }else { for(i=0;i<global_N3_smooth;i++) t21[i]=1.0; } sprintf(fname, "%s/delta/deltanl_z%.3f_N%ld_L%.1f.dat",argv[1],z,global_N_smooth,global_L/global_hubble); fid=fopen(fname,"rb"); if (fid==NULL) {printf("Error reading deltanl file... Check path or if the file exists..."); exit (1);} fread(temp,sizeof(float),global_N3_smooth,fid); fclose(fid); for(i=0;i<global_N3_smooth;i++) dvdr[i]=(double)temp[i]; /* Executes FFT */ fftw_execute(pr2c); /********************************************************************/ printf("Computing v field...\n"); #ifdef _OMPTHREAD_ #pragma omp parallel for shared(dvdk,global_dk) private(i,indi,j,indj,p,kk) #endif for(i=0;i<global_N_smooth;i++) { if(i>global_N_smooth/2) { /* Large frequencies are equivalent to smaller negative ones */ indi=-(global_N_smooth-i); }else indi=i; for(j=0;j<global_N_smooth;j++) { if(j>global_N_smooth/2) { indj=-(global_N_smooth-j); }else indj=j; for(p=0;p<=global_N_smooth/2;p++) { if(i==0 && j==0 && p==0) { dvdk[i*global_N_smooth*(global_N_smooth/2+1)+j*(global_N_smooth/2+1)+p]=0.; }else { kk=global_dk*sqrt(indi*indi+indj*indj+p*p); if(global_vi==1) { dvdk[i*global_N_smooth*(global_N_smooth/2+1)+j*(global_N_smooth/2+1)+p]=(global_dk*indi)*(global_dk*indi)/(kk*kk)*dvdk[i*global_N_smooth*(global_N_smooth/2+1)+j*(global_N_smooth/2+1)+p]; }else if(global_vi==2) { dvdk[i*global_N_smooth*(global_N_smooth/2+1)+j*(global_N_smooth/2+1)+p]=(global_dk*indj)*(global_dk*indj)/(kk*kk)*dvdk[i*global_N_smooth*(global_N_smooth/2+1)+j*(global_N_smooth/2+1)+p]; }else { dvdk[i*global_N_smooth*(global_N_smooth/2+1)+j*(global_N_smooth/2+1)+p]=(global_dk*p)*(global_dk*p)/(kk*kk)*dvdk[i*global_N_smooth*(global_N_smooth/2+1)+j*(global_N_smooth/2+1)+p]; } } } } } /* Executes FFT */ fftw_execute(pc2r); nmaxcut=0; nmincut=0; growth=getGrowth(z); dgdt=dgrowthdt(z); Hubz=Hz(z); #ifdef _OMPTHREAD_ #pragma omp parallel for shared(dvdr,global_L,global_dx_smooth,global_N3_smooth) private(i) #endif for(i=0;i<global_N3_smooth;i++) { dvdr[i]=-dgdt*dvdr[i]/global_L/global_L/global_L/Hubz*global_dx_smooth*global_dx_smooth*global_dx_smooth/growth; /* FT normalization + divide by H(z). Divide by growth to get deltanl back to z=0 */ } for(i=0;i<global_N3_smooth;i++) { if(dvdr[i] > maxcut) {dvdr[i]=maxcut; nmaxcut++;} else if(dvdr[i] < mincut) {dvdr[i]=mincut; nmincut++;} } printf("nmaxcut: %d (%f %%), nmincut: %d (%f %%)\n\n",nmaxcut,100.*nmaxcut/global_N3_smooth,nmincut,100.*nmincut/global_N3_smooth);fflush(0); #ifdef _OMPTHREAD_ #pragma omp parallel for shared(t21,temp,dvdr,global_hubble,global_omega_b,global_omega_m,global_N3_smooth,z) private(i) #endif for(i=0;i<global_N3_smooth;i++) { /* output in K */ t21[i]=23.0/1000.*(1.+(double)temp[i])*t21[i]/(1.+1.*dvdr[i])*(0.7/global_hubble)*(global_omega_b*global_hubble*global_hubble/0.02)*sqrt((0.15/global_omega_m/global_hubble/global_hubble)*(1.+z)/10.); /*Units in Kelvin */ } sprintf(fname,"%s/Ionization/xHII_z%.3f_eff%.2lf_N%ld_L%.1f.dat",argv[1],z,global_eff,global_N_smooth,global_L/global_hubble); if((fid = fopen(fname,"rb"))==NULL) { printf("Error opening file:%s\n",fname); exit(1); } fread(temp,sizeof(float),global_N3_smooth,fid); fclose(fid); for(i=0;i<global_N3_smooth;i++) { t21[i]=t21[i]*(1.-(double)temp[i]); // neutral fraction... } sprintf(fname,"%s/deltaTb/deltaTb_z%.3lf_N%ld_L%.1f.dat",argv[1],z,global_N_smooth,global_L/global_hubble); if((fid = fopen(fname,"wb"))==NULL) { printf("Cannot open file:%s...\n",fname); exit(1); } for(i=0;i<global_N3_smooth;i++) temp[i]=(float)t21[i]; fwrite(temp,sizeof(float),global_N3_smooth,fid); fclose(fid); aver=0.; for(i=0; i<global_N3_smooth; i++) aver+=t21[i]; fprintf(fidtxt,"%f %.8E\n",z,aver/global_N3_smooth); if(z>(global_Zminsfr-global_Dzsim/10) && global_use_Lya_xrays==1) fprintf(fidtxt2,"%f %.8E\n",z,TS/global_N3_smooth); } } /* ends z cycle */ fclose(fidtxt); exit(0); }