/** * * * @param X * @author Takahiro Misawa (The University of Tokyo) * @author Kazuyoshi Yoshimi (The University of Tokyo) */ void Lanczos_EigenVector(struct BindStruct *X){ printf("%s", cLogLanczos_EigenVectorStart); int i,j,i_max,iv; int k_exct; double beta1,alpha1,dnorm, dnorm_inv; double complex temp1,temp2; // for GC long unsigned int u_long_i; dsfmt_t dsfmt; k_exct = X->Def.k_exct; iv=X->Large.iv; i_max=X->Check.idim_max; //Eigenvectors by Lanczos method //initialization: initialization should be identical to that of Lanczos_EigenValue.c #pragma omp parallel for default(none) private(i) shared(v0, v1, vg) firstprivate(i_max) for(i=1;i<=i_max;i++){ v0[i]=0.0+0.0*I; v1[i]=0.0+0.0*I; vg[i]=0.0+0.0*I; } if(initial_mode == 0){ v1[iv]=1.0; vg[iv]=vec[k_exct][1]; }else if(initial_mode==1){ iv = X->Def.initial_iv; u_long_i = 123432 + abs(iv); dsfmt_init_gen_rand(&dsfmt, u_long_i); for(i = 1; i <= i_max; i++){ v1[i]=2.0*(dsfmt_genrand_close_open(&dsfmt)-0.5)+2.0*(dsfmt_genrand_close_open(&dsfmt)-0.5)*I; } dnorm=0; #pragma omp parallel for default(none) private(i) shared(v1, i_max) reduction(+: dnorm) for(i=1;i<=i_max;i++){ dnorm += conj(v1[i])*v1[i]; } dnorm=sqrt(dnorm); dnorm_inv=1.0/dnorm; #pragma omp parallel for default(none) private(i) shared(v1,vg,vec,k_exct) firstprivate(i_max, dnorm_inv) for(i=1;i<=i_max;i++){ v1[i] = v1[i]*dnorm_inv; vg[i] = v1[i]*vec[k_exct][1]; } } mltply(X, v0, v1); alpha1=alpha[1]; beta1=beta[1]; #pragma omp parallel for default(none) private(j) shared(vec, v0, v1, vg) firstprivate(alpha1, beta1, i_max, k_exct) for(j=1;j<=i_max;j++){ vg[j]+=vec[k_exct][2]*(v0[j]-alpha1*v1[j])/beta1; } //iteration for(i=2;i<=X->Large.itr-1;i++){ #pragma omp parallel for default(none) private(j, temp1, temp2) shared(v0, v1) firstprivate(i_max, alpha1, beta1) for(j=1;j<=i_max;j++){ temp1=v1[j]; temp2=(v0[j]-alpha1*v1[j])/beta1; v0[j]=-beta1*temp1; v1[j]=temp2; } mltply(X, v0, v1); alpha1 = alpha[i]; beta1 = beta[i]; #pragma omp parallel for default(none) private(j) shared(vec, v0, v1, vg) firstprivate(alpha1, beta1, i_max, k_exct, i) for(j=1;j<=i_max;j++){ vg[j] += vec[k_exct][i+1]*(v0[j]-alpha1*v1[j])/beta1; } } #pragma omp parallel for default(none) private(j) shared(v0, vg) firstprivate(i_max) for(j=1;j<=i_max;j++){ v0[j] = vg[j]; } //normalization dnorm=0.0; #pragma omp parallel for default(none) reduction(+:dnorm) private(j) shared(v0) firstprivate(i_max) for(j=1;j<=i_max;j++){ dnorm += conj(v0[j])*v0[j]; } dnorm=sqrt(dnorm); dnorm_inv=dnorm; #pragma omp parallel for default(none) private(j) shared(v0) firstprivate(i_max, dnorm_inv) for(j=1;j<=i_max;j++){ v0[j] = v0[j]*dnorm_inv; } TimeKeeper(X, cFileNameTimeKeep, cLanczos_EigenVectorFinish, "a"); printf("%s", cLogLanczos_EigenVectorEnd); }
/*! * Compute forward Fouier transform of real signal. A real-to-complex * FFT is used (for speed optimisation) but the complex output signal * is filled to its full size through conjugate symmetry. * * \param[out] out (complex double*) Forward Fourier transform of input signal. * \param[in] in (double*) Real input signal. * \param[in] data * - data[0] (fftw_plan*): The real-to-complex FFTW plan to use when * computing the Fourier transform (passed as an input so that the * FFTW can be FFTW_MEASUREd beforehand). * - data[1] (purify_image*): The image defining the size of the Fourier * transform. * * \authors <a href="http://www.jasonmcewen.org">Jason McEwen</a> */ void purify_measurement_fft_real(void *out, void *in, void **data) { fftw_plan *plan; int iu, iv, ind, ind_half; int iu_neg, iv_neg, ind_neg; double complex *y, *y_half; purify_image *img; // Cast intput pointers. y = (double complex*)out; plan = (fftw_plan*)data[0]; img = (purify_image*)data[1]; // Allocate space for output of real-to-complex FFT before compute // full plane through conjugate symmetry. y_half = (complex double*)malloc(img->nx*img->ny*sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(y_half); // Perform real-to-complex FFT. fftw_execute_dft_r2c(*plan, (double*)in, y_half); // Compute other half of complex plane through conjugate symmetry. for (iu = 0; iu < img->nx; iu++) { for (iv = 0; iv < img->ny/2+1; iv++) { ind_half = iu*(img->ny/2+1) + iv; purify_visibility_iuiv2ind(&ind, iu, iv, img->nx, img->ny); // Copy current data element. y[ind] = y_half[ind_half]; // Compute reflected data through conjugate symmetry if // necessary. if (iu == 0 && iv == 0) { // Do nothing for DC component. } else if (iu == 0) { // Reflect along line iu = 0. iv_neg = img->ny - iv; purify_visibility_iuiv2ind(&ind_neg, iu, iv_neg, img->nx, img->ny); if (ind != ind_neg) y[ind_neg] = conj(y_half[ind_half]); } else if (iv == 0) { // Reflect along line iu = 0. iu_neg = img->nx - iu; purify_visibility_iuiv2ind(&ind_neg, iu_neg, iv, img->nx, img->ny); if (ind != ind_neg) y[ind_neg] = conj(y_half[ind_half]); } else { // Reflect along diagonal. iv_neg = img->ny - iv; iu_neg = img->nx - iu; purify_visibility_iuiv2ind(&ind_neg, iu_neg, iv_neg, img->nx, img->ny); if (ind != ind_neg) y[ind_neg] = conj(y_half[ind_half]); } } } // Free temporary memory. free(y_half); }
DComplex kTable::kval(int i, int j) const { validCheck(); DComplex retval=scaleby*array[index(i,j)]; if (j<0) return conj(retval); else return retval; }