/** Reconstruction routine */ static void glacier(int N,int M) { int j,k,k0,k1,l,my_N[2],my_n[2]; double tmp_y; nfft_plan p; solver_plan_complex ip; FILE* fp; /* initialise p */ my_N[0]=N; my_n[0]=X(next_power_of_2)(N); my_N[1]=N; my_n[1]=X(next_power_of_2)(N); nfft_init_guru(&p, 2, my_N, M, my_n, 6, PRE_PHI_HUT| PRE_FULL_PSI| MALLOC_X| MALLOC_F_HAT| MALLOC_F| FFTW_INIT| FFT_OUT_OF_PLACE, FFTW_MEASURE| FFTW_DESTROY_INPUT); /* initialise ip, specific */ solver_init_advanced_complex(&ip,(nfft_mv_plan_complex*)(&p), CGNE| PRECOMPUTE_DAMP); fprintf(stderr,"Using the generic solver!"); /* init nodes */ fp=fopen("input_data.dat","r"); for(j=0;j<p.M_total;j++) { fscanf(fp,"%le %le %le",&p.x[2*j+0],&p.x[2*j+1],&tmp_y); ip.y[j]=tmp_y; } fclose(fp); /* precompute psi */ if(p.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); /* initialise damping factors */ if(ip.flags & PRECOMPUTE_DAMP) for(k0=0;k0<p.N[0];k0++) for(k1=0;k1<p.N[1];k1++) ip.w_hat[k0*p.N[1]+k1]= my_weight(((double)(k0-p.N[0]/2))/p.N[0],0.5,3,0.001)* my_weight(((double)(k1-p.N[1]/2))/p.N[1],0.5,3,0.001); /* init some guess */ for(k=0;k<p.N_total;k++) ip.f_hat_iter[k]=0; /* inverse trafo */ solver_before_loop_complex(&ip); for(l=0;l<40;l++) { fprintf(stderr,"Residual ||r||=%e,\n",sqrt(ip.dot_r_iter)); solver_loop_one_step_complex(&ip); } for(k=0;k<p.N_total;k++) printf("%le %le\n",creal(ip.f_hat_iter[k]),cimag(ip.f_hat_iter[k])); solver_finalize_complex(&ip); nfft_finalize(&p); }
void FC_FUNC(oct_nfft_precompute_one_psi_1d, OCT_NFFT_PRECOMPUTE_ONE_PSI_1D) (nfft_plan *plan, int *m, double *X1) { int ii; int M = *m; for (ii=0;ii< M;ii++){ plan->x[ii] = X1[ii]; } if(plan->nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(plan); }
static void simple_test_nfft_1d(void) { nfft_plan p; double t; int N=14; int M=19; ticks t0, t1; /** init an one dimensional plan */ nfft_init_1d(&p,N,M); /** init pseudo random nodes */ nfft_vrand_shifted_unit_double(p.x,p.M_total); /** precompute psi, the entries of the matrix B */ if(p.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); /** init pseudo random Fourier coefficients and show them */ nfft_vrand_unit_complex(p.f_hat,p.N_total); nfft_vpr_complex(p.f_hat,p.N_total,"given Fourier coefficients, vector f_hat"); /** direct trafo and show the result */ t0 = getticks(); nfft_trafo_direct(&p); t1 = getticks(); t = nfft_elapsed_seconds(t1,t0); nfft_vpr_complex(p.f,p.M_total,"ndft, vector f"); printf(" took %e seconds.\n",t); /** approx. trafo and show the result */ nfft_trafo(&p); nfft_vpr_complex(p.f,p.M_total,"nfft, vector f"); /** approx. adjoint and show the result */ nfft_adjoint_direct(&p); nfft_vpr_complex(p.f_hat,p.N_total,"adjoint ndft, vector f_hat"); /** approx. adjoint and show the result */ nfft_adjoint(&p); nfft_vpr_complex(p.f_hat,p.N_total,"adjoint nfft, vector f_hat"); /** finalise the one dimensional plan */ nfft_finalize(&p); }
void FC_FUNC(oct_nfft_precompute_one_psi_2d, OCT_NFFT_PRECOMPUTE_ONE_PSI_2D) (nfft_plan *plan, int *M, double* X1, double* X2) { int ii; int jj; for (ii=0; ii< M[0]; ii++){ for (jj=0; jj< M[1]; jj++){ plan->x[2*(M[1] * ii + jj) + 0] = X1[ii]; plan->x[2*(M[1] * ii + jj) + 1] = X2[jj]; } } if(plan->nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(plan); }
void FC_FUNC(oct_nfft_precompute_one_psi_3d, OCT_NFFT_PRECOMPUTE_ONE_PSI_3D) (nfft_plan *plan, int *M, double* X1, double* X2, double* X3) { int ii,jj,kk; for (ii=0;ii< M[0];ii++){ for (jj=0;jj< M[1];jj++){ for (kk=0;kk< M[2];kk++){ plan->x[3*(M[1]*M[2]*ii + M[2]*jj + kk) + 0] = X1[ii]; plan->x[3*(M[1]*M[2]*ii + M[2]*jj + kk) + 1] = X2[jj]; plan->x[3*(M[1]*M[2]*ii + M[2]*jj + kk) + 2] = X3[kk]; } } } if(plan->nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(plan); }
void // space to frequency mad_cmat_nfft (const cnum_t x[], const num_t x_node[], cnum_t r[], ssz_t m, ssz_t n, ssz_t nr) { assert( x && r ); int precomp = 0; if (m != p_n1 || n != p_n2 || nr != p_m) { nfft_finalize(&p); nfft_init_2d (&p, m, n, nr); p_n1 = m, p_n2 = n, p_m = nr, precomp = 1; } if (x_node || precomp) { for (ssz_t i=0; i < m*n; i++) // adjoint transform needs -x_node p.x[i] = x_node[i] == -0.5 ? 0.4999999999999999 : -x_node[i]; if(p.flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); } mad_cvec_copy(x, p.f, m*n); const char *error_str = nfft_check(&p); if (error_str) error("%s", error_str); nfft_adjoint(&p); // nfft_adjoint_direct(&p); // mad_cvec_copy(p.f_hat, r, nr); mad_cvec_copy(p.f_hat+nr/2, r, nr/2); // for compatibility with FFTW ?? (TBC) mad_cvec_copy(p.f_hat, r+nr/2, nr/2); }
void // frequency to space mad_cmat_infft (const cnum_t x[], const num_t r_node[], cnum_t r[], ssz_t m, ssz_t n, ssz_t nx) { assert( x && r ); int precomp = 0; if (m != p_n1 || n != p_n2 || nx != p_m) { nfft_finalize(&p); nfft_init_2d (&p, m, n, nx); p_n1 = m, p_n2 = n, p_m = nx, precomp = 1; } if (r_node || precomp) { for (ssz_t i=0; i < m*n; i++) // forward transform needs -r_node p.x[i] = r_node[i] == -0.5 ? 0.4999999999999999 : -r_node[i]; if(p.flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); } // mad_cvec_copy(x, p.f_hat, nx); mad_cvec_copy(x+nx/2, p.f_hat, nx/2); // for compatibility with FFTW ?? (TBC) mad_cvec_copy(x, p.f_hat+nx/2, nx/2); const char *error_str = nfft_check(&p); if (error_str) error("%s", error_str); nfft_trafo(&p); // nfft_trafo_direct(&p); mad_cvec_copy(p.f, r, m*n); mad_cvec_muln(r, 1.0/(m*n), r, m*n); }
/** Reconstruction routine with cross validation */ static void glacier_cv(int N,int M,int M_cv,unsigned solver_flags) { int j,k,k0,k1,l,my_N[2],my_n[2]; double tmp_y,r; nfft_plan p,cp; solver_plan_complex ip; double _Complex* cp_y; FILE* fp; int M_re=M-M_cv; /* initialise p for reconstruction */ my_N[0]=N; my_n[0]=X(next_power_of_2)(N); my_N[1]=N; my_n[1]=X(next_power_of_2)(N); nfft_init_guru(&p, 2, my_N, M_re, my_n, 6, PRE_PHI_HUT| PRE_FULL_PSI| MALLOC_X| MALLOC_F_HAT| MALLOC_F| FFTW_INIT| FFT_OUT_OF_PLACE, FFTW_MEASURE| FFTW_DESTROY_INPUT); /* initialise ip, specific */ solver_init_advanced_complex(&ip,(nfft_mv_plan_complex*)(&p), solver_flags); /* initialise cp for validation */ cp_y = (double _Complex*) nfft_malloc(M*sizeof(double _Complex)); nfft_init_guru(&cp, 2, my_N, M, my_n, 6, PRE_PHI_HUT| PRE_FULL_PSI| MALLOC_X| MALLOC_F| FFTW_INIT| FFT_OUT_OF_PLACE, FFTW_MEASURE| FFTW_DESTROY_INPUT); cp.f_hat=ip.f_hat_iter; /* set up data in cp and cp_y */ fp=fopen("input_data.dat","r"); for(j=0;j<cp.M_total;j++) { fscanf(fp,"%le %le %le",&cp.x[2*j+0],&cp.x[2*j+1],&tmp_y); cp_y[j]=tmp_y; } fclose(fp); /* copy part of the data to p and ip */ for(j=0;j<p.M_total;j++) { p.x[2*j+0]=cp.x[2*j+0]; p.x[2*j+1]=cp.x[2*j+1]; ip.y[j]=tmp_y; } /* precompute psi */ if(p.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); /* precompute psi */ if(cp.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&cp); /* initialise damping factors */ if(ip.flags & PRECOMPUTE_DAMP) for(k0=0;k0<p.N[0];k0++) for(k1=0;k1<p.N[1];k1++) ip.w_hat[k0*p.N[1]+k1]= my_weight(((double)(k0-p.N[0]/2))/p.N[0],0.5,3,0.001)* my_weight(((double)(k1-p.N[1]/2))/p.N[1],0.5,3,0.001); /* init some guess */ for(k=0;k<p.N_total;k++) ip.f_hat_iter[k]=0; /* inverse trafo */ solver_before_loop_complex(&ip); // fprintf(stderr,"iteration starts,\t"); for(l=0;l<40;l++) solver_loop_one_step_complex(&ip); //fprintf(stderr,"r=%1.2e, ",sqrt(ip.dot_r_iter)/M_re); NFFT_SWAP_complex(p.f_hat,ip.f_hat_iter); nfft_trafo(&p); NFFT_SWAP_complex(p.f_hat,ip.f_hat_iter); nfft_upd_axpy_complex(p.f,-1,ip.y,M_re); r=sqrt(nfft_dot_complex(p.f,M_re)/nfft_dot_complex(cp_y,M)); fprintf(stderr,"r=%1.2e, ",r); printf("$%1.1e$ & ",r); nfft_trafo(&cp); nfft_upd_axpy_complex(&cp.f[M_re],-1,&cp_y[M_re],M_cv); r=sqrt(nfft_dot_complex(&cp.f[M_re],M_cv)/nfft_dot_complex(cp_y,M)); fprintf(stderr,"r_1=%1.2e\t",r); printf("$%1.1e$ & ",r); nfft_finalize(&cp); solver_finalize_complex(&ip); nfft_finalize(&p); }
static void simple_test_nfft_2d(void) { int K,N[2],n[2],M; double t; ticks t0, t1; nfft_plan p; N[0]=32; n[0]=64; N[1]=14; n[1]=32; M=N[0]*N[1]; K=16; t0 = getticks(); /** init a two dimensional plan */ nfft_init_guru(&p, 2, N, M, n, 7, PRE_PHI_HUT| PRE_FULL_PSI| MALLOC_F_HAT| MALLOC_X| MALLOC_F | FFTW_INIT| FFT_OUT_OF_PLACE, FFTW_ESTIMATE| FFTW_DESTROY_INPUT); /** init pseudo random nodes */ nfft_vrand_shifted_unit_double(p.x,p.d*p.M_total); /** precompute psi, the entries of the matrix B */ if(p.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); /** init pseudo random Fourier coefficients and show them */ nfft_vrand_unit_complex(p.f_hat,p.N_total); t1 = getticks(); t = nfft_elapsed_seconds(t1,t0); nfft_vpr_complex(p.f_hat,K, "given Fourier coefficients, vector f_hat (first few entries)"); printf(" ... initialisation took %e seconds.\n",t); /** direct trafo and show the result */ t0 = getticks(); nfft_trafo_direct(&p); t1 = getticks(); t = nfft_elapsed_seconds(t1,t0); nfft_vpr_complex(p.f,K,"ndft, vector f (first few entries)"); printf(" took %e seconds.\n",t); /** approx. trafo and show the result */ t0 = getticks(); nfft_trafo(&p); t1 = getticks(); t = nfft_elapsed_seconds(t1,t0); nfft_vpr_complex(p.f,K,"nfft, vector f (first few entries)"); printf(" took %e seconds.\n",t); /** direct adjoint and show the result */ t0 = getticks(); nfft_adjoint_direct(&p); t1 = getticks(); t = nfft_elapsed_seconds(t1,t0); nfft_vpr_complex(p.f_hat,K,"adjoint ndft, vector f_hat (first few entries)"); printf(" took %e seconds.\n",t); /** approx. adjoint and show the result */ t0 = getticks(); nfft_adjoint(&p); t1 = getticks(); t = nfft_elapsed_seconds(t1,t0); nfft_vpr_complex(p.f_hat,K,"adjoint nfft, vector f_hat (first few entries)"); printf(" took %e seconds.\n",t); /** finalise the two dimensional plan */ nfft_finalize(&p); }
static PyObject *nfft(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *in_obj, *coord_obj; static char *kwlist[] = {"real_space", "coordinates", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &in_obj, &coord_obj)) { return NULL; } PyObject *coord_array = PyArray_FROM_OTF(coord_obj, NPY_DOUBLE, NPY_IN_ARRAY); PyObject *in_array = PyArray_FROM_OTF(in_obj, NPY_COMPLEX128, NPY_IN_ARRAY); if (coord_array == NULL || in_array == NULL) { Py_XDECREF(coord_array); Py_XDECREF(in_array); return NULL; } int ndim = PyArray_NDIM(in_array); if (ndim <= 0) { PyErr_SetString(PyExc_ValueError, "Input array can't be 0 dimensional\n"); return NULL; } if ((PyArray_NDIM(coord_array) != 2 || PyArray_DIM(coord_array, 1) != ndim) && (ndim != 1 || PyArray_NDIM(coord_array) != 1)) { PyErr_SetString(PyExc_ValueError, "Coordinates must be given as array of dimensions [NUMBER_OF_POINTS, NUMBER_OF_DIMENSIONS] of [NUMBER_OF_POINTS for 1D transforms.\n"); Py_XDECREF(coord_array); Py_XDECREF(in_array); return NULL; } int number_of_points = (int) PyArray_DIM(coord_array, 0); nfft_plan my_plan; int total_number_of_pixels = 1; int dims[ndim]; int dim; for (dim = 0; dim < ndim; ++dim) { dims[dim] = (int)PyArray_DIM(in_array, dim); total_number_of_pixels *= dims[dim]; } #if defined(ENABLE_THREADS) printf("OMP_NUM_THREADS=%s\n",getenv("OMP_NUM_THREADS")); printf("nthreads = %d\n", nfft_get_num_threads()); fftw_init_threads(); #endif nfft_init(&my_plan, ndim, dims, number_of_points); memcpy(my_plan.f_hat, PyArray_DATA(in_array), total_number_of_pixels*sizeof(fftw_complex)); memcpy(my_plan.x, PyArray_DATA(coord_array), ndim*number_of_points*sizeof(double)); if (my_plan.nfft_flags &PRE_PSI) { nfft_precompute_one_psi(&my_plan); } nfft_trafo(&my_plan); int out_dim[] = {number_of_points}; PyObject *out_array = (PyObject *)PyArray_FromDims(1, out_dim, NPY_COMPLEX128); memcpy(PyArray_DATA(out_array), my_plan.f, number_of_points*sizeof(fftw_complex)); // Clean up memory nfft_finalize(&my_plan); #if defined(ENABLE_THREADS) fftw_cleanup_threads(); #endif Py_XDECREF(coord_array); Py_XDECREF(in_array); return out_array; }
void bench_openmp(FILE *infile, int m, int psi_flag) { nfft_plan p; int *N; int *n; int M, d, trafo_adjoint; int t, j; double re,im; ticks t0, t1; double tt_total, tt_preonepsi; fscanf(infile, "%d %d", &d, &trafo_adjoint); N = malloc(d*sizeof(int)); n = malloc(d*sizeof(int)); for (t=0; t<d; t++) fscanf(infile, "%d", N+t); for (t=0; t<d; t++) fscanf(infile, "%d", n+t); fscanf(infile, "%d", &M); #ifdef _OPENMP fftw_import_wisdom_from_filename("nfft_benchomp_detail_threads.plan"); #else fftw_import_wisdom_from_filename("nfft_benchomp_detail_single.plan"); #endif /** init an d-dimensional plan */ nfft_init_guru(&p, d, N, M, n, m, PRE_PHI_HUT| psi_flag | MALLOC_X | MALLOC_F_HAT| MALLOC_F| FFTW_INIT | FFT_OUT_OF_PLACE, FFTW_MEASURE| FFTW_DESTROY_INPUT); #ifdef _OPENMP fftw_export_wisdom_to_filename("nfft_benchomp_detail_threads.plan"); #else fftw_export_wisdom_to_filename("nfft_benchomp_detail_single.plan"); #endif for (j=0; j < p.M_total; j++) { for (t=0; t < p.d; t++) fscanf(infile, "%lg", p.x+p.d*j+t); } if (trafo_adjoint==0) { for (j=0; j < p.N_total; j++) { fscanf(infile, "%lg %lg", &re, &im); p.f_hat[j] = re + _Complex_I * im; } } else { for (j=0; j < p.M_total; j++) { fscanf(infile, "%lg %lg", &re, &im); p.f[j] = re + _Complex_I * im; } } t0 = getticks(); /** precompute psi, the entries of the matrix B */ if(p.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); t1 = getticks(); tt_preonepsi = nfft_elapsed_seconds(t1,t0); if (trafo_adjoint==0) nfft_trafo(&p); else nfft_adjoint(&p); t1 = getticks(); tt_total = nfft_elapsed_seconds(t1,t0); #ifndef MEASURE_TIME p.MEASURE_TIME_t[0] = 0.0; p.MEASURE_TIME_t[2] = 0.0; #endif #ifndef MEASURE_TIME_FFTW p.MEASURE_TIME_t[1] = 0.0; #endif printf("%.6e %.6e %6e %.6e %.6e %.6e\n", tt_preonepsi, p.MEASURE_TIME_t[0], p.MEASURE_TIME_t[1], p.MEASURE_TIME_t[2], tt_total-tt_preonepsi-p.MEASURE_TIME_t[0]-p.MEASURE_TIME_t[1]-p.MEASURE_TIME_t[2], tt_total); // printf("%.6e\n", tt); free(N); free(n); /** finalise the one dimensional plan */ nfft_finalize(&p); }