gsl_complex theta4(gsl_complex z, gsl_complex q) { int n=0; gsl_complex accum = gsl_complex_rect(0.5,0.0); gsl_complex q2 = gsl_complex_mul(q,q); gsl_complex nextm = gsl_complex_negative(gsl_complex_mul(q,q2)); gsl_complex qpower = gsl_complex_negative(q); gsl_complex term = gsl_complex_rect(1.0,0.0); while ((gsl_complex_abs(qpower) > 2.0*GSL_DBL_EPSILON) && (n < THETA_ITER_MAX)) { term = gsl_complex_mul(qpower, gsl_complex_cos(gsl_complex_mul_real(z,2*(n+1)))); accum = gsl_complex_add(accum, term); qpower = gsl_complex_mul(qpower, nextm); nextm = gsl_complex_mul(nextm, q2); n++; } if (n >= THETA_ITER_MAX) return(gsl_complex_rect(0.0,0.0)); return gsl_complex_mul_real(accum,2.0); }
gsl_complex theta2(gsl_complex z, gsl_complex q, gsl_complex q14) { int n=0; gsl_complex accum = gsl_complex_rect(0.0,0.0); gsl_complex q2 = gsl_complex_mul(q,q); gsl_complex nextm = q2; gsl_complex qpower = gsl_complex_rect(1.0,0.0); gsl_complex term = gsl_complex_rect(1.0,0.0); while ((gsl_complex_abs(term) > 2.0*GSL_DBL_EPSILON) && (n < THETA_ITER_MAX)) { term = gsl_complex_mul(qpower, gsl_complex_cos(gsl_complex_mul_real(z,2*n+1))); accum = gsl_complex_add(accum, term); qpower = gsl_complex_mul(qpower, nextm); nextm = gsl_complex_mul(nextm, q2); n++; } if (n >= THETA_ITER_MAX) return(gsl_complex_rect(0.0,0.0)); return gsl_complex_mul_real(gsl_complex_mul(q14,accum),2.0); }
/* The Lattes map */ gsl_complex P_doubler(gsl_complex p, const gsl_complex *g) { gsl_complex p2, p3; gsl_complex num; gsl_complex denom; gsl_complex term; p2 = gsl_complex_mul(p,p); p3 = gsl_complex_mul(p2,p); /* denom = 4p^3 - g2p - g3 */ denom = gsl_complex_sub(gsl_complex_mul_real(p3,4.0), gsl_complex_add(gsl_complex_mul(p,g[0]),g[1])); /* num = (p^2 + g2/4)^2 + 2g3p */ term = gsl_complex_add(p2,gsl_complex_mul_real(g[0],0.25)); num = gsl_complex_add(gsl_complex_mul(p,gsl_complex_mul_real(g[1],2.0)), gsl_complex_mul(term,term)); return gsl_complex_div(num,denom); }
int print_Lcurve(const char *filename, poltor_workspace *w) { int s = 0; FILE *fp; const size_t p = w->p; double rnorm, Lnorm; gsl_vector_complex_view v = gsl_vector_complex_subvector(w->rhs, 0, p); size_t i; fp = fopen(filename, "a"); if (!fp) { fprintf(stderr, "print_Lcurve: unable to open %s: %s\n", filename, strerror(errno)); return -1; } /* construct A and b, and calculate chi^2 = ||b - A c||^2 */ poltor_build_ls(0, w); rnorm = sqrt(w->chisq); /* compute v = L c; L is stored in w->L by poltor_solve() */ for (i = 0; i < p; ++i) { gsl_complex ci = gsl_vector_complex_get(w->c, i); double li = gsl_vector_get(w->L, i); gsl_complex val = gsl_complex_mul_real(ci, li); gsl_vector_complex_set(&v.vector, i, val); } /* compute || L c || */ Lnorm = gsl_blas_dznrm2(&v.vector); fprintf(fp, "%.12e %.12e %.6e %.6e %.6e\n", log(rnorm), log(Lnorm), w->alpha_int, w->alpha_sh, w->alpha_tor); printcv_octave(w->residuals, "r"); printcv_octave(w->c, "c"); printv_octave(w->L, "L"); fclose(fp); return s; } /* print_Lcurve() */
double line_segment_integrand_wrapper(double t, void *data) { const LineSegmentParams *params = (const LineSegmentParams *)data; gsl_complex p = gsl_complex_add(params->p0, gsl_complex_mul_real(params->k, t)); gsl_complex v = f_envelope(p, params->params); double v_part = (params->part == REAL) ? GSL_REAL(v) : GSL_IMAG(v); double damped = exp( - params->damping * t) * v_part; return damped; }
/* NOTE: Assumes z is in fundamental parallelogram */ gsl_complex wP(gsl_complex z, gsl_complex tau, const gsl_complex *g) { int N = 6; int i; gsl_complex z0; gsl_complex z02; gsl_complex p; z = near_origin(z,tau); z0 = gsl_complex_div_real(z,(double)(1 << N)); z02 = gsl_complex_mul(z0,z0); /* Laurent expansion: P \approx 1/z^2 + (g2/20)z^2 + (g3/28) z^4 */ p = gsl_complex_add(gsl_complex_inverse(z02), gsl_complex_add(gsl_complex_mul(z02,gsl_complex_mul_real(g[0],0.05)), gsl_complex_mul(gsl_complex_mul(z02,z02),gsl_complex_mul_real(g[1],_CONST_1_28)))); for (i=0;i<N;i++) { p = P_doubler(p,g); } return p; }
gsl_complex f_envelope(gsl_complex p, const Params *params) { double m = params->m; gsl_complex env = gsl_complex_div( p, gsl_complex_sqrt(gsl_complex_add_real(gsl_complex_mul(p,p), m*m))); if (params->smear) { gsl_complex sp = gsl_complex_mul_real(p, params->sigma); env = gsl_complex_mul(env, gsl_complex_exp(gsl_complex_negative(gsl_complex_mul(sp, sp)))); } return env; }
gsl_complex theta30(gsl_complex q) { int n=0; gsl_complex accum = gsl_complex_rect(0.5,0.0); gsl_complex q2 = gsl_complex_mul(q,q); gsl_complex nextm = gsl_complex_mul(q,q2); gsl_complex qpower = q; while ((gsl_complex_abs(qpower) > 2.0*GSL_DBL_EPSILON) && (n < THETA_ITER_MAX)) { accum = gsl_complex_add(accum, qpower); qpower = gsl_complex_mul(qpower, nextm); nextm = gsl_complex_mul(nextm, q2); n++; } if (n >= THETA_ITER_MAX) return(gsl_complex_rect(0.0,0.0)); return gsl_complex_mul_real(accum,2.0); }
void CModel::FacetHarmonics(int fh, int bw, double r, gsl_complex *coeff){ int i, j, sign; gsl_complex err; Triangle_3 tr; tr = Triangle_3(plist[flist[fh*3+0]],plist[flist[fh*3+1]],plist[flist[fh*3+2]]); Tetrahedron_3 tetr; tetr = Tetrahedron_3(Point_3(0.0, 0.0, 0.0),plist[flist[fh*3+0]],plist[flist[fh*3+1]],plist[flist[fh*3+2]]); if(tetr.is_degenerate()) return; sign = (tetr.volume()<0 ? -1 : 1); for(i=0; i<bw; i++){ for(j=0; j<=i; j++){ Integrate(i, j, r, tetr, &coeff[i*bw+j], &err); coeff[i*bw+j] = gsl_complex_mul_real(coeff[i*bw+j], (double)sign); } } }
void MCPMPCoeffs::GeoUpdate(double seconds) { for (int i=0;i<2*M();i++) { gsl_complex v = gsl_vector_complex_get(geoVelocities,i); // expressed in deltalon/s,deltalat/s gsl_complex p = gsl_vector_complex_get(geoPositions,i); // expressed in lon,lat gsl_complex np = gsl_complex_add(p,gsl_complex_mul_real(v, seconds)); gsl_vector_complex_set(geoPositions,i,np); // cout << "node " << i << " position = " << GSL_IMAG(np) << ", " << GSL_REAL(np) << endl; } }
void tabulate(FILE *os, ComplexFunction fun, void *params, gsl_complex z0, gsl_complex z1, int n) { gsl_complex k = gsl_complex_sub(z1, z0); for (int i = 0; i < n; ++i) { double t = (double)i / (n - 1); gsl_complex z = gsl_complex_add(z0, gsl_complex_mul_real(k, t)); gsl_complex f = fun(z, params); double abs = gsl_complex_abs(f); fprintf(os, "%g %g %g %g %g %g %g\n", t, GSL_REAL(z), GSL_IMAG(z), GSL_REAL(f), GSL_IMAG(f), abs, -abs); } }
//go through all sets of Bethe rapidities and calculate g1 for all identical sets. return value is sum of all these terms. gsl_complex exact_integrationDE(double orteins, double ortzwei, double** kEp_plusminus, int anzahl_sets, double** coeffoverlap) { //variables to make loop easily readable, could delete from final version double c, Energie, Energieprime, normierung, normierungprime; double k[N]; double kprime[N];//corresponds to primed Bethe rapidity set in papers gsl_complex overlap, overlapprime, integral; GSL_SET_COMPLEX(&integral, 0.0, 0.0);//sum of all values, technically no needed but good for quick check of initial shape of g1 int zaehler_integrale = 0;//counter of total sets of integrals double Nminusone_fak = 1.0;//(N-1) factorial, see definition of integrals on restricted spatial domain for(int j=1; j<=(N-1); j++) Nminusone_fak = Nminusone_fak * ((double) j); for(int zaehler_eigenstate = 0 ; zaehler_eigenstate < anzahl_sets; zaehler_eigenstate++){//loop over all Bethe rapidity sets c = kEp_plusminus[zaehler_eigenstate][0];//interaction strength for(int bb=0; bb<N; bb++) k[bb]=kEp_plusminus[zaehler_eigenstate][bb+1];//Bethe rapidities Energie = kEp_plusminus[zaehler_eigenstate][N+1];//energy normierung=kEp_plusminus[zaehler_eigenstate][N+6];//norm GSL_SET_COMPLEX(&overlap, coeffoverlap[zaehler_eigenstate][0], coeffoverlap[zaehler_eigenstate][1]);//overlap of set with initial state //calculate g1_DE for this Bethe set gsl_complex integralwert = integraleigenfunction(k, k, c, normierung, normierung, orteins, ortzwei); integralwert = gsl_complex_mul_real(integralwert, (Nminusone_fak*Laenge));//integral evaluated in Rp only -> missing factor of (N-1)!. Laenge (=system length): definition of g1 has prefactor of N!/(n*(N-1)!) = Laenge integral = gsl_complex_add(integral, gsl_complex_mul(gsl_complex_mul(overlap, gsl_complex_conjugate(overlap)), integralwert)); }//end for loop zaehler_eigenstate return integral; };
/* NOTE: Assumes z is in fundamental parallelogram */ void wP_and_prime(gsl_complex z, gsl_complex tau, const gsl_complex *g, gsl_complex *p, gsl_complex *pp) { int N = 6; /* Enough iterations for good P, not so good P' */ int i; gsl_complex z0; gsl_complex z02; gsl_complex pout, ppout; gsl_complex ppsolve; z = near_origin(z,tau); z0 = gsl_complex_div_real(z,(double)(1 << N)); z02 = gsl_complex_mul(z0,z0); /* Laurent expansion: P \approx 1/z^2 + (g2/20)z^2 + (g3/28) z^4 */ pout = gsl_complex_add(gsl_complex_inverse(z02), gsl_complex_add(gsl_complex_mul(z02,gsl_complex_mul_real(g[0],0.05)), gsl_complex_mul(gsl_complex_mul(z02,z02),gsl_complex_mul_real(g[1],_CONST_1_28)))); /* Laurent expansion: P' \approx -2/z^3 + g2/10z + g3/7 z^3 */ ppout = gsl_complex_add(gsl_complex_mul_real(gsl_complex_inverse(gsl_complex_mul(z0,z02)),-2.0), gsl_complex_add(gsl_complex_mul(z0,gsl_complex_mul_real(g[0],0.1)), gsl_complex_mul(gsl_complex_mul(z0,z02),gsl_complex_mul_real(g[1],_CONST_1_7)))); for (i=0;i<N;i++) { P_and_Pprime_doubler(&pout, &ppout, g); } /* At this point ppout is a decent but not great approximation of P'(z) */ /* Instead of using it directly, we use it as a guide for which square root of */ /* (4P^3 - g2 P - g3) should be selected. */ ppsolve = gsl_complex_sqrt( gsl_complex_sub( gsl_complex_mul_real(gsl_complex_mul(pout,gsl_complex_mul(pout,pout)),4.0), gsl_complex_add(gsl_complex_mul(g[0],pout),g[1]) ) ); *p = pout; if (gsl_complex_abs(gsl_complex_sub(ppsolve,ppout)) < gsl_complex_abs(gsl_complex_add(ppsolve,ppout))) *pp = ppsolve; else *pp = gsl_complex_negative(ppsolve); }
/* computes the svd of a complex matrix. Missing in gsl. */ int svd(gsl_matrix_complex *A, gsl_matrix_complex *V, gsl_vector *S) { int n = A->size1; gsl_eigen_hermv_workspace *gsl_work = gsl_eigen_hermv_alloc(n); gsl_matrix_complex *Asq = gsl_matrix_complex_alloc(n, n); gsl_complex zero = gsl_complex_rect(0., 0.); gsl_complex one = gsl_complex_rect(1., 0.); gsl_vector *e = gsl_vector_alloc(n); gsl_matrix_complex *U = gsl_matrix_complex_alloc(n, n); gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, A, A, zero, Asq); gsl_eigen_hermv(Asq, e, U, gsl_work); gsl_eigen_hermv_sort(e, U, GSL_EIGEN_SORT_VAL_DESC); gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, A, A, zero, Asq); gsl_eigen_hermv(Asq, e, V, gsl_work); gsl_eigen_hermv_sort(e, V, GSL_EIGEN_SORT_VAL_DESC); gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, A, V, zero, Asq); gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, U, Asq, zero, A); for(int i=0; i<n; i++){ gsl_complex x = gsl_matrix_complex_get(A, i, i); double phase = gsl_complex_arg(gsl_complex_mul_real(x, 1./sqrt(e->data[i]))); gsl_vector_complex_view U_col = gsl_matrix_complex_column(U, i); gsl_vector_complex_scale(&U_col.vector, gsl_complex_polar(1., phase)); gsl_vector_set(S, i, sqrt(gsl_vector_get(e, i))); } gsl_matrix_complex_memcpy(A, U); gsl_vector_free(e); gsl_matrix_complex_free(U); gsl_matrix_complex_free(Asq); gsl_eigen_hermv_free(gsl_work); return 0; }
/****************************************************************************** * calc_A() * This function calcs the A's for a given theta. * * Parameters * --------- * * Returns * ------- * * Notes * ----- * This function assumes that the X[j] and g[j] values have already * been calculated (see calc_X()) * * Note: X[j] = Ar[j]/Ai[j] * And we can derive: * * Ai[j] = phase*Ai[j+1]*t[j+1] / ( 1 + phase^2 * X[j] * r[j+1]) * Ar[j] = Ai[j]*X[j] * * where Ar[j] and Ai[j] are the field amplitudes within layer j at * the j/j-1 interface. * * For the top layer Ai[nlayer-1] = 1. ie everything is referenced to * unit intensity (Io=|Ai|^2) within the top layer. Therefore Ar[0] = X[0]. * * Given the known values for the top layer we can procede to calculate each Ai and Ar * value starting at the top. * * For the base layer X[0] = 0, ie Ar[0] = 0 * * The values of r[j+1] and t[j+1] are the reflection and transmission coefficients * for the j+1/j interface, respectively, and calculated from: * * r[j+1] = (g[j+1]-g[j])/(g[j+1]+g[j]) * t[j+1] = 2*g[j+1]/(g[j+1] + g[j]) = 1 + r[j+1] * * This function also includes an interfacial roughness term mult into * the reflection coefficient for the j+1/j interface: * * r[j+1] = r[j+1]*exp(-1.0(q*sig[j+1])^2) * * Note we include roughness in the t calc using the below: * t[j+1] = 1 + r[j+1]*exp(-1.0(q*sig[j+1])^2) * * Therefore as r-> 0, t-> 1. This is only done if calc_params[10] > 0. * Otherwise t is calc explicitley from the g's * * The phase term accounts for the phase shift and attentuation of the field * traversing the j layer (ie from the j+1/j interface to the j/j-1 interface), * ie the Ai[j] and Ar[j] are the field amplitudes at the j/j-1 interface: * * phase = exp( -i*k*d[j] * g[j]) * * Note if j == 0 then the phase for layer j is 0.0, and X[0] = 0 * ie in the infinitley thick base layer we assumer the is no reflected * field (Ar[0] = 0.0) and we are calculating the the field amplitude at the * top of layer 0 rather than the bottom of layer 0. * * * Note: double check how doing the phase calc below, is that the best way?? * e.g. could we use: * phase = gsl_complex_exp( gsl_complex_mul_real(g1,-1.0*k*d[j])); * instead of * phase = gsl_complex_exp( gsl_complex_mul(phase,g1)); * * ******************************************************************************/ int calc_A(double theta, ref_model *ref, angle_calc *ang_c, layer_calc *lay_c){ int i, j, idx; double cos_sqr_thet, k, q, dw; double *d, *sig; gsl_complex g1, g2, num, den, r, t, Ai_2, Ar_2, Ai_1, Ar_1, X1, phase, phase_sqr; //gsl_complex n1, n2; // convenience vars cos_sqr_thet = square(cos(theta*M_PI/180.)); k = ref->k; q = 2.0*k*sin((theta*M_PI/180.)); d = ref->d; sig = ref->sigma; // start at top idx = ref->nlayer - 1; // get g for upper layer, ie air/vaccum slab // ie del ~ bet ~ 0. // n = 1 - del -i*bet ~ 1 // g2 = sqrt( n^2 - cos(theta)^2 ) //GSL_REAL(n2) = 1.0 - lay_c->del[idx]; //GSL_IMAG(n2) = -1.0*lay_c->bet[idx]; //g2 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n2, n2), cos_sqr_thet) ); GSL_SET_COMPLEX(&g2,ang_c->Re_g[idx],ang_c->Im_g[idx]); // for the top (j=nlayer-1) layer, Ai =1.0 // therefore Ar = Ai*X = X // store these in A arrays ang_c->Re_Ai[idx] = GSL_REAL(Ai_2) = 1.0; ang_c->Im_Ai[idx] = GSL_IMAG(Ai_2) = 0.0; ang_c->Re_Ar[idx] = GSL_REAL(Ar_2) = ang_c->Re_X[idx]; ang_c->Im_Ar[idx] = GSL_IMAG(Ar_2) = ang_c->Im_X[idx]; // loop over all layers, start at top - 1 // ie loop from j = nlayer-2 --> j = 0 // note j is lower layer in the r and t calcs // therefore we are considering the j+1/j interface // i is the interface number, ie which interface // are the r's and t's calc for i = idx - 1; for ( j = idx - 1; j > -1 ; j--){ // calc g and phase for lower layer // n = 1 - del -i*bet // g1 = sqrt( n^2 - cos(theta)^2 ) //GSL_REAL(n1) = 1.0 - xpar->del[j]; //GSL_IMAG(n1) = -1.0 * xpar->bet[j]; //g1 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n1, n1), cos_sqr_thet) ); GSL_SET_COMPLEX(&g1,ang_c->Re_g[j],ang_c->Im_g[j]); //calc phase and attenuation // phase = exp( -i*k*d[j] * g1) // phase_sqr = (phase)^2 if (j == 0){ GSL_REAL(phase) = 1.0; GSL_IMAG(phase) = 0.0; GSL_REAL(phase_sqr) = 1.0; GSL_IMAG(phase_sqr) = 0.0; } else { GSL_REAL(phase) = 0.0; GSL_IMAG(phase) = -1.0*k*d[j]; phase = gsl_complex_exp( gsl_complex_mul(phase,g1)); GSL_REAL(phase_sqr) = 0.0; GSL_IMAG(phase_sqr) = -2.0*k*d[j]; phase_sqr = gsl_complex_exp( gsl_complex_mul(phase_sqr,g1)); } // calc r for upper layer // r = (g2-g1)/(g2+g1) GSL_SET_COMPLEX(&num,0.0,0.0); GSL_SET_COMPLEX(&den,0.0,0.0); num = gsl_complex_sub(g2,g1); den = gsl_complex_add(g2,g1); r = gsl_complex_div(num,den); // include simple dw type roughness // r = r*exp(-1.0(q*sig)^2) if (ref->sigma[j+1] > 0.0){ //dw = exp(-1.0*square(q*ref->sigma[j+1])); dw = exp(-1.0*square(q*ref->sigma[i])); r = gsl_complex_mul_real(r,dw); } // calc t for upper layer // t = 2*g2/(g2 + g1) if (ref->calc_params[10] == 0.0){ GSL_SET_COMPLEX(&num,0.0,0.0); num = gsl_complex_mul_real(g2, 2.0); t = gsl_complex_div(num,den); } else { // note as as r->0, t->1 // ie t = 1+r, so we could just calc t from r? t = gsl_complex_add_real(r,1.0); } // calc Ai_1 and Ar_1 // these are field mag in the lower slab (layer j) // at the bottom of the slab, relative to Ai in the top layer (j=nlayer-1) // Ai_1 = phase*Ai_2*t / ( 1 + phase^2 * X1 * r) // Ar_1 = Ai_1*X1 GSL_REAL(X1) = ang_c->Re_X[j]; GSL_IMAG(X1) = ang_c->Im_X[j]; GSL_SET_COMPLEX(&num,0.0,0.0); GSL_SET_COMPLEX(&den,0.0,0.0); num = gsl_complex_mul(t,gsl_complex_mul(Ai_2,phase)); den = gsl_complex_add_real(gsl_complex_mul(phase_sqr,gsl_complex_mul(X1,r)),1.0); Ai_1 = gsl_complex_div(num,den); if (fabs(GSL_REAL(Ai_1)) < 1.0e-12){ GSL_REAL(Ai_1) = 0.0; } if (fabs(GSL_IMAG(Ai_1)) < 1.0e-12){ GSL_IMAG(Ai_1) = 0.0; } Ar_1 = gsl_complex_mul(Ai_1,X1); //store results ang_c->Re_Ai[j] = GSL_REAL(Ai_1); ang_c->Im_Ai[j] = GSL_IMAG(Ai_1); ang_c->Re_Ar[j] = GSL_REAL(Ar_1); ang_c->Im_Ar[j] = GSL_IMAG(Ar_1); // this is the field intensity at the bottom of layer j // except for layer j = 0, this is the intensity at the top // of the base layer (bc of how phase is calc above) // use bottom layer as top for next time through GSL_REAL(Ai_2) = GSL_REAL(Ai_1); GSL_IMAG(Ai_2) = GSL_IMAG(Ai_1); GSL_REAL(Ar_2) = GSL_REAL(Ar_1); GSL_IMAG(Ar_2) = GSL_IMAG(Ar_1); // do the same for g's GSL_REAL(g2) = GSL_REAL(g1); GSL_IMAG(g2) = GSL_IMAG(g1); // increment interface number i--; } return (SUCCESS); }
double Calculator::getIntensity(double Q) { std::complex<double> cppf1, cppf2; gsl_complex alpha, beta; gsl_complex gslf1, gslf2; int s; double avFactor; cppf1 = m_sf1->F(0.0, 0.0, Q, m_energy); cppf2 = m_sf2->F(0.0, 0.0, Q, m_energy); gslf1 = gsl_complex_rect(cppf1.real(), cppf1.imag()); gslf2 = gsl_complex_rect(cppf2.real(), cppf2.imag()); avFactor = exp(-2.0 / m_N); alpha = gsl_complex_rect (1.0, 0.0); beta = gsl_complex_rect (0.0, 0.0); /*set vector F (scattering factors)*/ gsl_vector_complex_set(F, 0, gslf1); gsl_vector_complex_set(F, 1, gslf2); /*set vector conj(F) (scattering factors)*/ gsl_vector_complex_set(Fconj, 0, gsl_complex_conjugate(gslf1)); gsl_vector_complex_set(Fconj, 1, gsl_complex_conjugate(gslf2)); /*set exp matrix*/ setMatrixExp(m_Exp, Q); /*find W = P * Exp * Ps * conj(F) vector:*/ /* (1) W = alpha * Ps * conj(F) + beta * W */ gsl_blas_zgemv (CblasNoTrans, alpha, m_Ps, Fconj, beta, W); /*printf("W(1):\n"); gsl_vector_complex_fprintf (stdout, W, "%g");*/ /* (2) W = alpha * Exp * tmp_vec + beta * W */ gsl_blas_zgemv (CblasNoTrans, alpha, m_Exp, W, beta, tmp_vec); /*printf("W(2):\n"); gsl_vector_complex_fprintf (stdout, tmp_vec, "%g");*/ /* (3) W = alpha * P * tmp_vec + beta * W */ gsl_blas_zgemv (CblasNoTrans, alpha, m_P, tmp_vec, beta, W); /*Find J0 = F.(Ps * conj(F)) */ gsl_blas_zgemv (CblasNoTrans, alpha, m_Ps, Fconj, beta, tmp_vec); gsl_blas_zdotu (F, tmp_vec, &J0); /*alpha = exp(-2 / N)*/ alpha = gsl_complex_rect (avFactor, 0.0); beta = gsl_complex_rect (0.0, 0.0); /*find T matrix: T = alpha * P * exp + beta * T*/ gsl_blas_zgemm (CblasNoTrans, CblasNoTrans, alpha, m_P, m_Exp, beta, T); /*printf("T:\n"); gsl_matrix_complex_fprintf (stdout, T, "%g");*/ /*Find Jns = F. (G * W) */ /*tmp_mat = I */ gsl_matrix_complex_set_identity (tmp_mat); /*tmp_mat = I - T */ gsl_matrix_complex_sub (tmp_mat, T); /*LU decomposition*/ gsl_linalg_complex_LU_decomp(tmp_mat, perm, &s); /*calculate product G * W = (I - T)^(-1) W directly using LU decomposition*/ gsl_linalg_complex_LU_solve (tmp_mat, perm, W, tmp_vec); /*calculate F.(G * W)*/ gsl_blas_zdotu (F, tmp_vec, &Jns); /*Find Js = F.(G^2 * (I - T^N) * W) however, this term should be negligible*/ /*result = N *(2 * Jns + J0) - Js */ alpha = gsl_complex_mul_real (Jns, 2.0 * avFactor); alpha = gsl_complex_add (alpha, J0); return m_N * m_I0 * GSL_REAL(alpha) * getPLGfactor(getTheta(Q)) + m_Ibg; }
gsl_complex gsl_complex_log10(gsl_complex a) { /* z = log10(a) */ return gsl_complex_mul_real(gsl_complex_log(a), 1 / log(10.)); }
void distribuzione_luce(grano* g){ int i; double eta, h, fi, C, S; tilacoide* tilacoide_figlio; gsl_matrix* L_1 = gsl_matrix_alloc(2, 2); gsl_matrix* L_2 = gsl_matrix_alloc(2, 2); gsl_matrix* L_3 = gsl_matrix_alloc(2, 2); gsl_matrix* L = gsl_matrix_alloc(2, 2); // calcolo della matrice L // itero sui tilacoidi // primo stroma // carico dati nella matrice L_1 tilacoide_figlio = g->tilacoidi_figli;//[0]; eta = in.n_st * in.k_onda; h = tilacoide_figlio->st_succ->dim; fi = in.n_me * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L_1, 0, 0, C); gsl_matrix_set(L_1, 0, 1, -S/eta); gsl_matrix_set(L_1, 1, 0, eta*S); gsl_matrix_set(L_1, 1, 1, C); // itero dal secondo strato in poi for(i = 0; i < g->N; i++) { tilacoide_figlio = g->tilacoidi_figli +i;// [i]; // MEMEBRANA eta = in.n_me * in.k_onda; h = in.D_me; fi = in.n_me * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L_2, 0, 0, C); gsl_matrix_set(L_2, 0, 1, -S/eta); gsl_matrix_set(L_2, 1, 0, eta*S); gsl_matrix_set(L_2, 1, 1, C); // prodotto L_3 <- L_1 x L_2 gsl_matrix_set(L_3, 0, 0, gsl_matrix_get(L_1, 0, 0) * gsl_matrix_get(L_2, 0, 0) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 0)); gsl_matrix_set(L_3, 0, 1, gsl_matrix_get(L_1, 0, 0) * gsl_matrix_get(L_2, 0, 1) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 1)); gsl_matrix_set(L_3, 1, 0, gsl_matrix_get(L_1, 1, 0) * gsl_matrix_get(L_2, 0, 0) + gsl_matrix_get(L_1, 1, 1) * gsl_matrix_get(L_2, 1, 0)); gsl_matrix_set(L_3, 1, 1, gsl_matrix_get(L_1, 1, 0) * gsl_matrix_get(L_2, 0, 1) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 1)); // L_1 <- L_3 gsl_matrix_memcpy (L_1, L_3); // LUMEN eta = in.n_lu * in.k_onda; h = tilacoide_figlio->lu->dim; fi = in.n_lu * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L_2, 0, 0, C); gsl_matrix_set(L_2, 0, 1, -S/eta); gsl_matrix_set(L_2, 1, 0, eta*S); gsl_matrix_set(L_2, 1, 1, C); // prodotto L_3 <- L_1 x L_2 gsl_matrix_set(L_3, 0, 0, gsl_matrix_get(L_1, 0, 0) * gsl_matrix_get(L_2, 0, 0) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 0)); gsl_matrix_set(L_3, 0, 1, gsl_matrix_get(L_1, 0, 0) * gsl_matrix_get(L_2, 0, 1) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 1)); gsl_matrix_set(L_3, 1, 0, gsl_matrix_get(L_1, 1, 0) * gsl_matrix_get(L_2, 0, 0) + gsl_matrix_get(L_1, 1, 1) * gsl_matrix_get(L_2, 1, 0)); gsl_matrix_set(L_3, 1, 1, gsl_matrix_get(L_1, 1, 0) * gsl_matrix_get(L_2, 0, 1) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 1)); // L_1 <- L_3 gsl_matrix_memcpy (L_1, L_3); // MEMEBRANA eta = in.n_me * in.k_onda; h = in.D_me; fi = in.n_me * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L_2, 0, 0, C); gsl_matrix_set(L_2, 0, 1, -S/eta); gsl_matrix_set(L_2, 1, 0, eta*S); gsl_matrix_set(L_2, 1, 1, C); // prodotto L_3 <- L_1 x L_2 gsl_matrix_set(L_3, 0, 0, gsl_matrix_get(L_1, 0, 0) * gsl_matrix_get(L_2, 0, 0) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 0)); gsl_matrix_set(L_3, 0, 1, gsl_matrix_get(L_1, 0, 0) * gsl_matrix_get(L_2, 0, 1) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 1)); gsl_matrix_set(L_3, 1, 0, gsl_matrix_get(L_1, 1, 0) * gsl_matrix_get(L_2, 0, 0) + gsl_matrix_get(L_1, 1, 1) * gsl_matrix_get(L_2, 1, 0)); gsl_matrix_set(L_3, 1, 1, gsl_matrix_get(L_1, 1, 0) * gsl_matrix_get(L_2, 0, 1) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 1)); // L_1 <- L_3 gsl_matrix_memcpy (L_1, L_3); // stroma eta = in.n_st * in.k_onda; h = tilacoide_figlio->st_succ->dim; fi = in.n_me * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L_2, 0, 0, C); gsl_matrix_set(L_2, 0, 1, -S/eta); gsl_matrix_set(L_2, 1, 0, eta*S); gsl_matrix_set(L_2, 1, 1, C); // prodotto L_3 <- L_1 x L_2 gsl_matrix_set(L_3, 0, 0, gsl_matrix_get(L_1, 0, 0) * gsl_matrix_get(L_2, 0, 0) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 0)); gsl_matrix_set(L_3, 0, 1, gsl_matrix_get(L_1, 0, 0) * gsl_matrix_get(L_2, 0, 1) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 1)); gsl_matrix_set(L_3, 1, 0, gsl_matrix_get(L_1, 1, 0) * gsl_matrix_get(L_2, 0, 0) + gsl_matrix_get(L_1, 1, 1) * gsl_matrix_get(L_2, 1, 0)); gsl_matrix_set(L_3, 1, 1, gsl_matrix_get(L_1, 1, 0) * gsl_matrix_get(L_2, 0, 1) + gsl_matrix_get(L_1, 0, 1) * gsl_matrix_get(L_2, 1, 1)); // L_1 <- L_3 gsl_matrix_memcpy (L_1, L_3); } // L <- L_3 - L CALCOLATA gsl_matrix_memcpy (L, L_3); // calcolo di A_n ampiezza del campo rifratto nell'ultimo mezzo double eta_1, eta_n; eta_1 = eta_n = in.n_st*in.k_onda; double c11 = gsl_matrix_get(L, 0, 0); double c12 = gsl_matrix_get(L, 0, 1); double c21 = gsl_matrix_get(L, 1, 0); double c22 = gsl_matrix_get(L, 1, 1); //gsl_complex A_n = gsl_complex_rect(0, 0); gsl_complex A_n = gsl_complex_div(gsl_complex_rect(2* eta_1 * in.A_1, 0), gsl_complex_rect(eta_1 * c11+ eta_n * c22, eta_1 * eta_n * c12 - c21)); // output - cacolo intensita nelle membrane (a ritroso) gsl_complex v_2[2]; gsl_complex v_1[2]; // primo passo, calcolo v_n, corrisponde allo stroma v_2[0] = A_n; v_2[1] = gsl_complex_mul_real(A_n, eta_n); // calcolo v_{n-1}, corrisponde alla membrana v_1[0] = v_2[0]; v_1[1] = v_2[1]; gsl_complex P, Q; P = v_1[0]; Q = v_1[1]; gsl_complex A, B; // ampiezze del campo ottico eta = in.n_me * in.k_onda; A = gsl_complex_div_real(gsl_complex_add(P, gsl_complex_div_real(Q, -eta)), 2); B = gsl_complex_div_real(gsl_complex_add(P, gsl_complex_div_real(Q, eta)), 2); // A e B determinano il campo // calcolo dell'intensita media g->tilacoidi_figli[(g->N-1)].me2->I_luce = intensita(A, B); v_2[0] = v_1[0]; v_2[1] = v_1[1]; // calcolo ultimo lumen eta = in.n_lu * in.k_onda; //h = g->tilacoidi_figli[(g->N-1)]->lu->dim; h = g->tilacoidi_figli[(g->N-1)].lu->dim; fi = in.n_lu * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L, 0, 0, C); gsl_matrix_set(L, 0, 1, -S/eta); gsl_matrix_set(L, 1, 0, eta*S); gsl_matrix_set(L, 1, 1, C); // prodotto v_1 <- L x v_2 v_1[0] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 0, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 0, 1))); v_1[1] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 1, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 1, 1))); v_2[0] = v_1[0]; v_2[1] = v_1[1]; // penultima membrana eta = in.n_me * in.k_onda; h = in.D_me; fi = in.n_me * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L_2, 0, 0, C); gsl_matrix_set(L_2, 0, 1, -S/eta); gsl_matrix_set(L_2, 1, 0, eta*S); gsl_matrix_set(L_2, 1, 1, C); // prodotto v_1 <- L x v_2 v_1[0] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 0, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 0, 1))); v_1[1] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 1, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 1, 1))); //gsl_complex P, Q; P = v_1[0]; Q = v_1[1]; //gsl_complex A, B; // ampiezze del campo ottico eta = in.n_me * in.k_onda; A = gsl_complex_div_real(gsl_complex_add(P, gsl_complex_div_real(Q, -eta)), 2); B = gsl_complex_div_real(gsl_complex_add(P, gsl_complex_div_real(Q, eta)), 2); // A e B determinano il campo // calcolo dell'intensita media //g->tilacoidi_figli[(g->N-1)]->me1->I_luce = intensita(A, B); g->tilacoidi_figli[(g->N-1)].me1->I_luce = intensita(A, B); v_2[0] = v_1[0]; v_2[1] = v_1[1]; // su tutti i tilacoidi for(i = g->N-2; i >= 0; i--) { tilacoide_figlio = g->tilacoidi_figli+i;//[i]; // stroma eta = in.n_st * in.k_onda; h = tilacoide_figlio->st_succ->dim; fi = in.n_me * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L, 0, 0, C); gsl_matrix_set(L, 0, 1, -S/eta); gsl_matrix_set(L, 1, 0, eta*S); gsl_matrix_set(L, 1, 1, C); // prodotto v_1 <- L x v_2 v_1[0] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 0, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 0, 1))); v_1[1] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 1, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 1, 1))); v_2[0] = v_1[0]; v_2[1] = v_1[1]; //gsl_complex P, Q; P = v_1[0]; Q = v_1[1]; //gsl_complex A, B; // ampiezze del campo ottico eta = in.n_me * in.k_onda; A = gsl_complex_div_real(gsl_complex_add(P, gsl_complex_div_real(Q, -eta)), 2); B = gsl_complex_div_real(gsl_complex_add(P, gsl_complex_div_real(Q, eta)), 2); // A e B determinano il campo // calcolo dell'intensita media tilacoide_figlio->me2->I_luce = intensita(A, B); v_2[0] = v_1[0]; v_2[1] = v_1[1]; // calcolo ultimo lumen eta = in.n_lu * in.k_onda; h = tilacoide_figlio->lu->dim; fi = in.n_lu * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L, 0, 0, C); gsl_matrix_set(L, 0, 1, -S/eta); gsl_matrix_set(L, 1, 0, eta*S); gsl_matrix_set(L, 1, 1, C); // prodotto v_1 <- L x v_2 v_1[0] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 0, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 0, 1))); v_1[1] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 1, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 1, 1))); v_2[0] = v_1[0]; v_2[1] = v_1[1]; // penultima membrana eta = in.n_me * in.k_onda; h = in.D_me; fi = in.n_me * in.k_onda * h; C = cos(fi); S = sin(fi); gsl_matrix_set(L_2, 0, 0, C); gsl_matrix_set(L_2, 0, 1, -S/eta); gsl_matrix_set(L_2, 1, 0, eta*S); gsl_matrix_set(L_2, 1, 1, C); // prodotto v_1 <- L x v_2 v_1[0] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 0, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 0, 1))); v_1[1] = gsl_complex_add(gsl_complex_mul_real(v_2[0], gsl_matrix_get(L, 1, 0)), gsl_complex_mul_real(v_2[1], gsl_matrix_get(L_1, 1, 1))); //gsl_complex P, Q; P = v_1[0]; Q = v_1[1]; //gsl_complex A, B; // ampiezze del campo ottico eta = in.n_me * in.k_onda; A = gsl_complex_div_real(gsl_complex_add(P, gsl_complex_div_real(Q, -eta)), 2); B = gsl_complex_div_real(gsl_complex_add(P, gsl_complex_div_real(Q, eta)), 2); // A e B determinano il campo // calcolo dell'intensita media tilacoide_figlio->me1->I_luce = intensita(A, B); v_2[0] = v_1[0]; v_2[1] = v_1[1]; } // libera memoria matrici gsl_matrix_free(L_1); gsl_matrix_free(L_2); gsl_matrix_free(L_3); gsl_matrix_free(L); }
complex& complex::operator*=(const double& a) { _complex = gsl_complex_mul_real(_complex,a); return *this; }
complex complex::operator*(const double& a) const { gsl_complex rl = gsl_complex_mul_real(_complex,a); return complex(rl); }
void Spectrometer::countAmplitudes_bulk_B(Medium &Osrodek, QString DataName, QProgressBar *Progress, QTextBrowser *Browser, double kx, double ky, double w, int polarisation, double x_lenght, double y_lenght, double precision) { double a=Osrodek.itsBasis.getLatticeConstant(); int RecVec=itsRecVectors; int dimension=3*(2*RecVec+1)*(2*RecVec+1); std::ofstream plik; DataName="results/amplitudes/"+ DataName + ".dat"; QByteArray bytes = DataName.toAscii(); const char * CDataName = bytes.data(); plik.open(CDataName); //inicjalizacje wektorów i macierzy gsl_matrix *gamma=gsl_matrix_calloc(dimension, dimension); gsl_matrix *V=gsl_matrix_calloc(dimension, dimension); gsl_vector *S=gsl_vector_calloc(dimension); gsl_vector *work=gsl_vector_calloc(dimension); //gamma dla Podłoża /* S - numeruje transformaty tensora sprężystoci i gestosci i - numeruje wiersze macierzy j - numeruje kolumny macierzy */ for(int Nx=-RecVec, i=0, S=0; Nx<=RecVec; Nx++) { for(int Ny=-RecVec; Ny<=RecVec; Ny++, i=i+3) { for(int Nx_prim=-RecVec, j=0; Nx_prim<=RecVec; Nx_prim++) { for(int Ny_prim=-RecVec; Ny_prim<=RecVec; Ny_prim++, j=j+3, S++) { double Elasticity[6][6]; itsRecBasisSubstance[S].getElasticity(Elasticity); double Density=itsRecBasisSubstance[S].getDensity(); double gx=2*M_PI*Nx/a; double gy=2*M_PI*Ny/a; double gx_prim=2*M_PI*Nx_prim/a; double gy_prim=2*M_PI*Ny_prim/a; gsl_matrix_set(gamma, i, j, Elasticity[0][0]*(kx+gx)*(kx+gx_prim)+Elasticity[3][3]*(ky+gy)*(ky+gy_prim)-Density*w*w); gsl_matrix_set(gamma, i+1, j, Elasticity[0][1]*(kx+gx_prim)*(ky+gy)+Elasticity[3][3]*(ky+gy_prim)*(kx+gx)); gsl_matrix_set(gamma, i, j+1, Elasticity[0][1]*(ky+gy_prim)*(kx+gx)+Elasticity[3][3]*(kx+gx_prim)*(ky+gy)); gsl_matrix_set(gamma, i+1, j+1, Elasticity[0][0]*(ky+gy_prim)*(ky+gy)+Elasticity[3][3]*(kx+gx_prim)*(kx+gx)-Density*w*w); gsl_matrix_set(gamma, i+2, j+2, Elasticity[3][3]*(ky+gy_prim)*(ky+gy)+Elasticity[3][3]*(kx+gx_prim)*(kx+gx)-Density*w*w); } } } } //rozwiązanie układu równań gsl_linalg_SV_decomp(gamma, V, S, work); gsl_complex u; double Gx, Gy; if (polarisation==3) { gsl_complex ux, uy, uz; for(double x=0; x < x_lenght; x=x+precision) { for(double y=0; y < y_lenght; y=y+precision) { ux = gsl_complex_rect(0, 0); uy = gsl_complex_rect(0, 0); uz = gsl_complex_rect(0, 0); //pasek postepu int postep=int(100*x/x_lenght); Progress->setValue(postep); Progress->update(); QApplication::processEvents(); for (int Nx=-RecVec, i=0; Nx <= RecVec; Nx++) { for (int Ny=-RecVec; Ny <= RecVec; Ny++, i=i+3) { Gx=2*M_PI*Nx/a; Gy=2*M_PI*Ny/a; double Ax = gsl_matrix_get(V, i, dimension-1); double Ay = gsl_matrix_get(V, i+1, dimension-1); double Az = gsl_matrix_get(V, i+2, dimension-1); gsl_complex expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y); gsl_complex exp1 = gsl_complex_exp(expin1); gsl_complex multiply = gsl_complex_mul_real(exp1, Ax); ux = gsl_complex_add(ux, multiply); expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y); exp1 = gsl_complex_exp(expin1); multiply = gsl_complex_mul_real(exp1, Ay); uy = gsl_complex_add(uy, multiply); expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y); exp1 = gsl_complex_exp(expin1); multiply = gsl_complex_mul_real(exp1, Az); uz = gsl_complex_add(uz, multiply); } } double U = sqrt(gsl_complex_abs(ux)*gsl_complex_abs(ux)+gsl_complex_abs(uy)*gsl_complex_abs(uy)+gsl_complex_abs(uz)*gsl_complex_abs(uz)); //zapisanie wartości do pliku QString nazwa = Osrodek.itsBasis.getFillingSubstance().getName(); if(nazwa=="Air") { double rad=Osrodek.itsBasis.getRadius(); if(sqrt(x*x+y*y) > rad && sqrt((a-x)*(a-x)+y*y) > rad && sqrt((a-x)*(a-x)+(a-y)*(a-y)) > rad && sqrt((a-y)*(a-y)+x*x) > rad) { plik << x << "\t" << y << "\t" << U << "\n"; } } else { plik << x << "\t" << y << "\t" << U << "\n"; } } plik << "\n"; } } else if (polarisation==4) { gsl_complex uxx, uxy, uxz, uyx, uyy, uyz, uzx, uzy, uzz; double Uxx, Uxy, Uxz, Uyx, Uyy, Uyz, Uzx, Uzy, Uzz; for(double x=0; x < x_lenght; x=x+precision) { for(double y=0; y < y_lenght; y=y+precision) { uxx = gsl_complex_rect(0, 0); uxy = gsl_complex_rect(0, 0); uxz = gsl_complex_rect(0, 0); uyx = gsl_complex_rect(0, 0); uyy = gsl_complex_rect(0, 0); uyz = gsl_complex_rect(0, 0); uzx = gsl_complex_rect(0, 0); uzy = gsl_complex_rect(0, 0); uzz = gsl_complex_rect(0, 0); double rad=Osrodek.itsBasis.getRadius(); double Ela[6][6]; if(sqrt(x*x+y*y) > rad && sqrt((a-x)*(a-x)+y*y) > rad && sqrt((a-x)*(a-x)+(a-y)*(a-y)) > rad && sqrt((a-y)*(a-y)+x*x) > rad) { Osrodek.itsBasis.getSubstance().getElasticity(Ela); } else { Osrodek.itsBasis.getFillingSubstance().getElasticity(Ela); } //pasek postepu int postep=int(100*x/x_lenght); Progress->setValue(postep); Progress->update(); QApplication::processEvents(); for (int Nx=-RecVec, i=0; Nx <= RecVec; Nx++) { for (int Ny=-RecVec; Ny <= RecVec; Ny++, i=i+3) { Gx=2*M_PI*Nx/a; Gy=2*M_PI*Ny/a; double Ax = gsl_matrix_get(V, i, dimension-1); double Ay = gsl_matrix_get(V, i+1, dimension-1); double Az = gsl_matrix_get(V, i+2, dimension-1); gsl_complex expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y); gsl_complex exp1 = gsl_complex_exp(expin1); gsl_complex multiply = gsl_complex_mul_real(exp1, Ax); //uxx gsl_complex multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), kx+Gx)); uxx = gsl_complex_add(uxx, multidiff); //uxy multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), ky+Gy)); uxy = gsl_complex_add(uxy, multidiff); expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y); exp1 = gsl_complex_exp(expin1); //uy multiply = gsl_complex_mul_real(exp1, Ay); //uyx multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), kx+Gx)); uyx = gsl_complex_add(uyx, multidiff); //uyy multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), ky+Gy)); uyy = gsl_complex_add(uyy, multidiff); expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y); exp1 = gsl_complex_exp(expin1); multiply = gsl_complex_mul_real(exp1, Az); //uzx multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), kx+Gx)); uzx = gsl_complex_add(uzx, multidiff); //uzy multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), ky+Gy)); uzy = gsl_complex_add(uzy, multidiff); } } Uxx=gsl_complex_abs(uxx); Uxy=gsl_complex_abs(uxy); Uxz=gsl_complex_abs(uxz); Uyx=gsl_complex_abs(uyx); Uyy=gsl_complex_abs(uyy); Uyz=gsl_complex_abs(uyz); Uzx=gsl_complex_abs(uzx); Uzy=gsl_complex_abs(uzy); Uzz=gsl_complex_abs(uzz); double U = Ela[0][0]*(Uxx*Uxx+Uyy*Uyy+Uzz*Uzz)+2*Ela[0][1]*(Uxx*Uyy+Uxx*Uzz+Uyy*Uzz)+0.25*Ela[3][3]*((Uyz+Uzy)*(Uyz+Uzy)+(Uxz+Uzx)*(Uxz+Uzx)+(Uxy+Uyx)*(Uxy+Uyx)); //zapisanie wartości do pliku QString nazwa = Osrodek.itsBasis.getFillingSubstance().getName(); if(nazwa=="Air") { double rad=Osrodek.itsBasis.getRadius(); if(sqrt(x*x+y*y) > rad && sqrt((a-x)*(a-x)+y*y) > rad && sqrt((a-x)*(a-x)+(a-y)*(a-y)) > rad && sqrt((a-y)*(a-y)+x*x) > rad) { plik << x << "\t" << y << "\t" << U << "\n"; } } else { plik << x << "\t" << y << "\t" << U << "\n"; } } plik << "\n"; } } else { for(double x=0; x < x_lenght; x=x+precision) { for(double y=0; y < y_lenght; y=y+precision) { u = gsl_complex_rect(0, 0); //pasek postepu int postep=int(100*x/x_lenght); Progress->setValue(postep); Progress->update(); QApplication::processEvents(); for (int Nx=-RecVec, i=0; Nx <= RecVec; Nx++) { for (int Ny=-RecVec; Ny <= RecVec; Ny++, i=i+3) { Gx=2*M_PI*Nx/a; Gy=2*M_PI*Ny/a; double A = gsl_matrix_get(V, i+polarisation, dimension-1); gsl_complex expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y); gsl_complex exp1 = gsl_complex_exp(expin1); gsl_complex multiply = gsl_complex_mul_real(exp1, A); u = gsl_complex_add(u, multiply); } } double U = gsl_complex_abs(u); //zapisanie wartości do pliku plik << x << "\t" << y << "\t" << U << "\n"; } plik << "\n"; } } plik.close(); gsl_matrix_free(gamma); gsl_matrix_free(V); gsl_vector_free(S); gsl_vector_free(work); }
void Spectrometer::countDispersion_BS(Medium &Osrodek, QString DataName, QProgressBar *Progress, int factor) { //lsfgerhla double a=Osrodek.itsBasis.getLatticeConstant(); double thickness=Osrodek.itsStructure.getThickness(); int RecVec=itsRecVectors; int k_prec=itsK_Precision; double wi=itsFrequencies[0]; double w_prec=itsFrequencies[1]; double wf=itsFrequencies[2]; int half=3*(2*RecVec+1)*(2*RecVec+1); int dimension=6*(2*RecVec+1)*(2*RecVec+1); int EigValStrNumber=6*(2*RecVec+1)*(2*RecVec+1); int EigValNumber=9*(2*RecVec+1)*(2*RecVec+1); std::ofstream plik; DataName="results/"+ DataName + ".dat"; QByteArray bytes = DataName.toAscii(); const char * CDataName = bytes.data(); plik.open(CDataName); //inicjalizacje wektorów i macierzy gsl_matrix *gammaA=gsl_matrix_calloc(dimension, dimension); gsl_matrix *gammaB=gsl_matrix_calloc(dimension, dimension); gsl_matrix *gammaC=gsl_matrix_calloc(dimension, dimension); gsl_matrix *gammaD=gsl_matrix_calloc(dimension, dimension); gsl_eigen_genv_workspace *wspce=gsl_eigen_genv_alloc(dimension); gsl_eigen_genv_workspace *wspce2=gsl_eigen_genv_alloc(dimension); gsl_vector_complex *StrAlpha =gsl_vector_complex_alloc(dimension); gsl_vector *StrBeta = gsl_vector_alloc(dimension); gsl_matrix_complex *StrEigenVec=gsl_matrix_complex_calloc(dimension, dimension); gsl_vector_complex *BAlpha =gsl_vector_complex_alloc(dimension); gsl_vector *BBeta = gsl_vector_alloc(dimension); gsl_matrix_complex *BasisEigenVec=gsl_matrix_complex_calloc(dimension, dimension); gsl_matrix_complex *ChosenVectors = gsl_matrix_complex_calloc(half, EigValNumber); gsl_vector_complex *ChosenValues = gsl_vector_complex_calloc(EigValNumber); gsl_matrix_complex *Boundaries=gsl_matrix_complex_calloc(EigValNumber, EigValNumber); double kx, ky, krokx, kroky, boundary_x, boundary_y; double k_zred, k_zred0; double krok = M_PI/(k_prec*a); for (int droga=0; droga<3; droga++) { //int droga = 1; if (droga==0) //droga M->Gamma { kx=-M_PI/a; krokx=krok; boundary_x=0; ky=-M_PI/a; kroky=krok; boundary_y=0; k_zred0=-1*sqrt(pow(kx/(2*M_PI/a), 2)+pow(ky/(2*M_PI/a), 2)); } else if (droga==1) { kx=0; //droga Gamma->X krokx=krok; boundary_x=M_PI/a; ky=0; kroky=0; boundary_y=0; k_zred0=sqrt(2)/2; //k_zred0=0; } else if (droga==2) { kx=M_PI/a; //Droga X->M krokx=0; boundary_x=M_PI/a; ky=0; kroky=krok; boundary_y=M_PI/a; k_zred0=sqrt(2)/2; } //petla dla wektorów falowych for (; kx <= boundary_x && ky <= boundary_y; kx=kx+krokx, ky=ky+kroky) { if (droga==0) { k_zred = abs(k_zred0 + sqrt( pow(kx/(2*M_PI/a), 2)+pow(ky/(2*M_PI/a), 2))); } else { k_zred = k_zred0 + kx/(2*M_PI/a) + ky/(2*M_PI/a); } int postep=int(100*k_zred/1.7); Progress->setValue(postep); Progress->update(); QApplication::processEvents(); //pętla dla częstości w for (double w=wi; w<wf; w=w+w_prec) { gsl_matrix_complex_set_all(Boundaries, gsl_complex_rect (0,0)); //ustawienie wartosci wyznacznika na 0 gsl_matrix_set_all(gammaA, 0); gsl_matrix_set_all(gammaB, 0); gsl_matrix_set_all(gammaC, 0); gsl_matrix_set_all(gammaD, 0); gsl_vector_complex_set_all(StrAlpha, gsl_complex_rect (0,0)); gsl_vector_set_all(BBeta, 0); gsl_vector_complex_set_all(BAlpha, gsl_complex_rect (0,0)); gsl_vector_set_all(StrBeta, 0); gsl_matrix_complex_set_all(BasisEigenVec, gsl_complex_rect (0,0)); gsl_matrix_complex_set_all(StrEigenVec, gsl_complex_rect (0,0)); gsl_matrix_complex_set_all(ChosenVectors, gsl_complex_rect (0,0)); gsl_vector_complex_set_all(ChosenValues, gsl_complex_rect (0,0)); //gammaA,B dla struktury //gammaA,B dla struktury /* S - numeruje transformaty tensora sprężystoci i gestosci i - numeruje wiersze macierzy j - numeruje kolumny macierzy half - druga polowa macierzy */ for(int Nx=-RecVec, i=0, S=0; Nx<=RecVec; Nx++) { for(int Ny=-RecVec; Ny<=RecVec; Ny++, i=i+3) { for(int Nx_prim=-RecVec, j=0; Nx_prim<=RecVec; Nx_prim++) { for(int Ny_prim=-RecVec; Ny_prim<=RecVec; Ny_prim++, j=j+3, S++) { double Elasticity[6][6]; itsRecStructureSubstance[S].getElasticity(Elasticity); double Density=itsRecStructureSubstance[S].getDensity(); double gx=2*M_PI*Nx/a; double gy=2*M_PI*Ny/a; double gx_prim=2*M_PI*Nx_prim/a; double gy_prim=2*M_PI*Ny_prim/a; gsl_matrix_set(gammaA, i, j, Elasticity[3][3]); gsl_matrix_set(gammaA, i+1, j+1, Elasticity[3][3]); gsl_matrix_set(gammaA, i+2, j+2, Elasticity[0][0]); gsl_matrix_set(gammaB, i+2, j, -Elasticity[0][1]*(kx+gx_prim)-Elasticity[3][3]*(kx+gx)); gsl_matrix_set(gammaB, i+2, j+1, -Elasticity[0][1]*(ky+gy_prim)-Elasticity[3][3]*(ky+gy)); gsl_matrix_set(gammaB, i, j+2, -Elasticity[0][1]*(kx+gx)-Elasticity[3][3]*(kx+gx_prim)); gsl_matrix_set(gammaB, i+1, j+2, -Elasticity[0][1]*(ky+gy)-Elasticity[3][3]*(ky+gy_prim)); gsl_matrix_set(gammaB, i, j+half, -Elasticity[0][0]*(kx+gx)*(kx+gx_prim)-Elasticity[3][3]*(ky+gy)*(ky+gy_prim)+Density*w*w); gsl_matrix_set(gammaB, i+1, j+half, -Elasticity[0][1]*(kx+gx_prim)*(ky+gy)-Elasticity[3][3]*(ky+gy_prim)*(kx+gx)); gsl_matrix_set(gammaB, i, j+half+1, -Elasticity[0][1]*(ky+gy_prim)*(kx+gx)-Elasticity[3][3]*(kx+gx_prim)*(ky+gy)); gsl_matrix_set(gammaB, i+1, j+half+1, -Elasticity[0][0]*(ky+gy_prim)*(ky+gy)-Elasticity[3][3]*(kx+gx_prim)*(kx+gx)+Density*w*w); gsl_matrix_set(gammaB, i+2, j+half+2, -Elasticity[3][3]*(ky+gy_prim)*(ky+gy)-Elasticity[3][3]*(kx+gx_prim)*(kx+gx)+Density*w*w); if (i==j) { gsl_matrix_set(gammaA, i+half, j+half, 1); gsl_matrix_set(gammaA, i+half+1, j+half+1, 1); gsl_matrix_set(gammaA, i+half+2, j+half+2, 1); gsl_matrix_set(gammaB, i+half, j, 1); gsl_matrix_set(gammaB, i+half+1, j+1, 1); gsl_matrix_set(gammaB, i+half+2, j+2, 1); } } } } } //rozwiazanie zagadnienienia własnego gsl_eigen_genv(gammaB, gammaA, StrAlpha, StrBeta, StrEigenVec, wspce); //gammaC,D dla Podłoża for(int Nx=-RecVec, i=0, S=0; Nx<=RecVec; Nx++) { for(int Ny=-RecVec; Ny<=RecVec; Ny++, i=i+3) { for(int Nx_prim=-RecVec, j=0; Nx_prim<=RecVec; Nx_prim++) { for(int Ny_prim=-RecVec; Ny_prim<=RecVec; Ny_prim++, j=j+3, S++) { double Elasticity[6][6]; itsRecBasisSubstance[S].getElasticity(Elasticity); double Density=itsRecBasisSubstance[S].getDensity(); double gx=2*M_PI*Nx/a; double gy=2*M_PI*Ny/a; double gx_prim=2*M_PI*Nx_prim/a; double gy_prim=2*M_PI*Ny_prim/a; gsl_matrix_set(gammaC, i, j, Elasticity[3][3]); gsl_matrix_set(gammaC, i+1, j+1, Elasticity[3][3]); gsl_matrix_set(gammaC, i+2, j+2, Elasticity[0][0]); gsl_matrix_set(gammaD, i+2, j, -Elasticity[0][1]*(kx+gx_prim)-Elasticity[3][3]*(kx+gx)); gsl_matrix_set(gammaD, i+2, j+1, -Elasticity[0][1]*(ky+gy_prim)-Elasticity[3][3]*(ky+gy)); gsl_matrix_set(gammaD, i, j+2, -Elasticity[0][1]*(kx+gx)-Elasticity[3][3]*(kx+gx_prim)); gsl_matrix_set(gammaD, i+1, j+2, -Elasticity[0][1]*(ky+gy)-Elasticity[3][3]*(ky+gy_prim)); gsl_matrix_set(gammaD, i, j+half, -Elasticity[0][0]*(kx+gx)*(kx+gx_prim)-Elasticity[3][3]*(ky+gy)*(ky+gy_prim)+Density*w*w); gsl_matrix_set(gammaD, i+1, j+half, -Elasticity[0][1]*(kx+gx_prim)*(ky+gy)-Elasticity[3][3]*(ky+gy_prim)*(kx+gx)); gsl_matrix_set(gammaD, i, j+half+1, -Elasticity[0][1]*(ky+gy_prim)*(kx+gx)-Elasticity[3][3]*(kx+gx_prim)*(ky+gy)); gsl_matrix_set(gammaD, i+1, j+half+1, -Elasticity[0][0]*(ky+gy_prim)*(ky+gy)-Elasticity[3][3]*(kx+gx_prim)*(kx+gx)+Density*w*w); gsl_matrix_set(gammaD, i+2, j+half+2, -Elasticity[3][3]*(ky+gy_prim)*(ky+gy)-Elasticity[3][3]*(kx+gx_prim)*(kx+gx)+Density*w*w); if (i==j) { gsl_matrix_set(gammaC, i+half, j+half, 1); gsl_matrix_set(gammaC, i+half+1, j+half+1, 1); gsl_matrix_set(gammaC, i+half+2, j+half+2, 1); gsl_matrix_set(gammaD, i+half, j, 1); gsl_matrix_set(gammaD, i+half+1, j+1, 1); gsl_matrix_set(gammaD, i+half+2, j+2, 1); } } } } } //rozwiazanie zagadnienienia własnego gsl_eigen_genv(gammaD, gammaC, BAlpha, BBeta, BasisEigenVec, wspce2); double imagL, realL; //części Re i Im wartości własnych int n=0; for (int i = 0; i<dimension; i++) { //przepisanie wartości i wektorów własnych struktury do macierzy Chosen* gsl_complex StrValue; StrValue= gsl_complex_div_real(gsl_vector_complex_get(StrAlpha, i), gsl_vector_get(StrBeta,i)); gsl_vector_complex_set(ChosenValues, i, StrValue); for (int j = half, m=0; j < dimension; j++, m++) { gsl_matrix_complex_set(ChosenVectors, m, i, gsl_matrix_complex_get(StrEigenVec, j, i)); } //wybieranie odpowiednich wartości i wektorów własnych dla podłoża i przepisanie do macierzy Chosen* gsl_complex BValue; BValue= gsl_complex_div_real(gsl_vector_complex_get(BAlpha, i), gsl_vector_get(BBeta,i)); imagL=GSL_IMAG(BValue); realL=GSL_REAL(BValue); if (imagL > 0.00001 && n+EigValStrNumber<EigValNumber) //warunek na wartości własne && żeby nie było ich więcej niż połowa { gsl_vector_complex_set(ChosenValues, n+EigValStrNumber, BValue); //wybranie wartości własnej for (int j = half, m=0; j < dimension; j++, m++) { gsl_matrix_complex_set(ChosenVectors, m, n+EigValStrNumber, gsl_complex_mul_real(gsl_matrix_complex_get(BasisEigenVec, j, i), -1)); //wybranie drugiej połowy wektora własnego } n++; } } if (n+EigValStrNumber<EigValNumber) { for (int i = 0; i<dimension; i++) { gsl_complex BValue; BValue= gsl_complex_div_real(gsl_vector_complex_get(BAlpha, i), gsl_vector_get(BBeta,i)); imagL=GSL_IMAG(BValue); realL=GSL_REAL(BValue); if (imagL < 0.00001 && imagL > -0.00001 && realL < -0.00001 && n+EigValStrNumber<EigValNumber) //warunek na wartości własne && żeby nie było ich więcej niż połowa { gsl_vector_complex_set(ChosenValues, n+EigValStrNumber, BValue); //wybranie wartości własnej for (int j = half, m=0; j < dimension; j++, m++) { gsl_matrix_complex_set(ChosenVectors, m, n+EigValStrNumber, gsl_complex_mul_real(gsl_matrix_complex_get(BasisEigenVec, j, i), -1)); //wybranie drugiej połowy wektora własnego } n++; } } } //wyznacznik warunków brzegowych - konstrukcja /* S, S' - numerujš transformaty tensora sprężystoci i - numeruje wektory własne A w pętli dla G j - numeruje warunki brzegowe dla kolejnych wektorow odwrotnych G k - numeruje wektory własne A w pętli dla G' L - numeruje wartoci własne */ for (int Nx=-RecVec, S=0, S_prim=0, i=0, j=0; Nx <= RecVec; Nx++) { for (int Ny=-RecVec; Ny <= RecVec; Ny++, j=j+9, i=i+3) { for (int L=0; L < EigValNumber; L++) { S_prim = S; for (int Nx_prim=-RecVec, k=0; Nx_prim <= RecVec; Nx_prim++) { for (int Ny_prim=-RecVec; Ny_prim <= RecVec; Ny_prim++, S_prim++, k=k+3) { double StrElasticity[6][6]; itsRecStructureSubstance[S_prim].getElasticity(StrElasticity); double BasisElasticity[6][6]; itsRecBasisSubstance[S_prim].getElasticity(BasisElasticity); double gx_prim=2*M_PI*Nx_prim/a; double gy_prim=2*M_PI*Ny_prim/a; if (L < EigValStrNumber) { //eksponens gsl_complex exponent = gsl_complex_polar(exp(GSL_IMAG(gsl_vector_complex_get(ChosenValues, L))*thickness), -1*GSL_REAL(gsl_vector_complex_get(ChosenValues, L))*thickness); //warunki zerowania się naprężenia na powierzchni gsl_complex w1 = gsl_complex_mul_real(exponent, StrElasticity[3][3]); gsl_complex w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (kx+gx_prim)); gsl_complex w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k, L)); gsl_complex BCjL = gsl_complex_add(gsl_complex_mul(gsl_complex_add(w2, w3), w1), gsl_matrix_complex_get(Boundaries, j, L)); gsl_matrix_complex_set(Boundaries, j, L, BCjL); w1 = gsl_complex_mul_real(exponent, StrElasticity[3][3]); w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (ky+gy_prim)); w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+1, L)); BCjL = gsl_complex_add(gsl_complex_mul(gsl_complex_add(w2, w3), w1), gsl_matrix_complex_get(Boundaries, j+1, L)); gsl_matrix_complex_set(Boundaries, j+1, L, BCjL); w1 = gsl_complex_mul_real(exponent, StrElasticity[0][0]); gsl_complex w11 = gsl_complex_mul_real(exponent, StrElasticity[0][1]); w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k, L), (kx+gx_prim)); gsl_complex w22 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+1, L), (ky+gy_prim)); w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+2, L)); gsl_complex w4 = gsl_complex_add(gsl_complex_mul(gsl_complex_add(w2, w22), w11), gsl_complex_mul(w3, w1)); BCjL = gsl_complex_add(w4, gsl_matrix_complex_get(Boundaries, j+2, L)); gsl_matrix_complex_set(Boundaries, j+2, L, BCjL); //warunki równości naprężeń na granicy ośrodków - część dla struktury w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (kx+gx_prim)); w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k, L)); BCjL = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w3), StrElasticity[3][3]), gsl_matrix_complex_get(Boundaries, j+3, L)); gsl_matrix_complex_set(Boundaries, j+3, L, BCjL); w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (ky+gy_prim)); w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+1, L)); BCjL = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w3), StrElasticity[3][3]), gsl_matrix_complex_get(Boundaries, j+4, L)); gsl_matrix_complex_set(Boundaries, j+4, L, BCjL); w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k, L), (kx+gx_prim)); w22 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+1, L), (ky+gy_prim)); w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+2, L)); w4 = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w22), StrElasticity[0][1]), gsl_complex_mul_real(w3, StrElasticity[0][0])); BCjL = gsl_complex_add(w4, gsl_matrix_complex_get(Boundaries, j+5, L)); gsl_matrix_complex_set(Boundaries, j+5, L, BCjL); } else { //warunki równości naprężeń na granicy ośrodków - część dla podłoża gsl_complex w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (kx+gx_prim)); gsl_complex w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k, L)); gsl_complex BCjL = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w3), BasisElasticity[3][3]), gsl_matrix_complex_get(Boundaries, j+3, L)); gsl_matrix_complex_set(Boundaries, j+3, L, BCjL); w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (ky+gy_prim)); w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+1, L)); BCjL = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w3), BasisElasticity[3][3]), gsl_matrix_complex_get(Boundaries, j+4, L)); gsl_matrix_complex_set(Boundaries, j+4, L, BCjL); w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k, L), (kx+gx_prim)); gsl_complex w22 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+1, L), (ky+gy_prim)); w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+2, L)); gsl_complex w4 = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w22), BasisElasticity[0][1]), gsl_complex_mul_real(w3, BasisElasticity[0][0])); BCjL = gsl_complex_add(w4, gsl_matrix_complex_get(Boundaries, j+5, L)); gsl_matrix_complex_set(Boundaries, j+5, L, BCjL); } } } // warunek równości wychyleń na granicy ośrodków gsl_matrix_complex_set(Boundaries, j+6, L, gsl_matrix_complex_get(ChosenVectors, i, L)); gsl_matrix_complex_set(Boundaries, j+7, L, gsl_matrix_complex_get(ChosenVectors, i+1, L)); gsl_matrix_complex_set(Boundaries, j+8, L, gsl_matrix_complex_get(ChosenVectors, i+2, L)); } S=S_prim; } } //skalowanie macierzy Boundaries gsl_complex scale=gsl_complex_rect(pow(10, factor), 0); gsl_matrix_complex_scale(Boundaries, scale); //obliczenie wyznacznika z Boundaries gsl_permutation *Bpermutation = gsl_permutation_alloc(EigValNumber); int Bsignum; gsl_linalg_complex_LU_decomp(Boundaries, Bpermutation, &Bsignum); double DetVal = gsl_linalg_complex_LU_lndet(Boundaries); //usuwanie NaN if(DetVal != DetVal) DetVal = 0; //zapisanie wartości do pliku plik << k_zred << "\t" << w << "\t" << DetVal << "\n"; } plik << "\n"; } } plik.close(); gsl_matrix_free(gammaA); gsl_matrix_free(gammaB); gsl_vector_free(BBeta); gsl_vector_free(StrBeta); gsl_matrix_free(gammaC); gsl_matrix_free(gammaD); gsl_vector_complex_free(StrAlpha); gsl_vector_complex_free(BAlpha); gsl_eigen_genv_free(wspce); gsl_eigen_genv_free(wspce2); gsl_matrix_complex_free(Boundaries); gsl_matrix_complex_free(ChosenVectors); gsl_vector_complex_free(ChosenValues); }
void smf_filter_mce( smfFilter *filt, int noinverse, int *status ) { /* Filter parameters */ double B_1_1; double B_1_2; double B_2_1; double B_2_2; double CLOCK_PERIOD; double ROW_DWELL; double NUM_ROWS=41; double DELTA_TIME; double SRATE; double datechange; /* UTC MJD for change in MCE filter parameters */ AstTimeFrame *tf=NULL; /* time frame for date conversion */ size_t i; /* Loop counter */ if( *status != SAI__OK ) return; if( !filt ) { *status = SAI__ERROR; errRep( FUNC_NAME, "NULL smfFilter supplied.", status ); return; } if( filt->ndims != 1 ) { *status = SAI__ERROR; errRep( "", FUNC_NAME ": function only generates filters for time-series", status ); return; } if( !filt->fdims[0] ) { *status = SAI__ERROR; errRep( "", FUNC_NAME ": 0-length smfFilter supplied.", status ); return; } if( filt->dateobs == VAL__BADD ) { *status = SAI__ERROR; errRep( "", FUNC_NAME ": dateobs (date of data to which filter will be " "applied) is not set - can't determine correct MCE filter " "parameters.", status ); return; } /* If filt->real is NULL, create a complex identity filter first. Similarly, if the filter is currently only real-valued, add an imaginary part. */ if( !filt->real ) { smf_filter_ident( filt, 1, status ); if( *status != SAI__OK ) return; } else if( !filt->imag ) { filt->imag = astCalloc( filt->fdims[0], sizeof(*filt->imag) ); if( *status != SAI__OK ) return; filt->isComplex = 1; } /* Set up filter parameters */ tf = astTimeFrame( " " ); astSet( tf, "TimeScale=UTC" ); astSet( tf, "TimeOrigin=%s", "2011-06-03T00:00:00" ); datechange = astGetD( tf, "TimeOrigin" ); tf = astAnnul( tf ); if( filt->dateobs > datechange ) { /* Data taken after 20110603 */ B_1_1 = -1.9712524; /* -2.*32297./2.^15. */ B_1_2 = 0.97253418; /* 2.*15934./2.^15. */ B_2_1 = -1.9337769; /* -2.*31683./2.^15. */ B_2_2 = 0.93505859; /* 2.*15320./2.^15. */ ROW_DWELL = 94.; /* time to dwell at each row (in clocks) */ msgOutiff(MSG__DEBUG, "", FUNC_NAME ": filter for data UTC MJD %lf after %lf", status, filt->dateobs, datechange ); } else { /* Older data */ B_1_1 = -1.9587402; /* -2.*32092./2.^15. */ B_1_2 = 0.96130371; /* 2.*15750./2.^15. */ B_2_1 = -1.9066162; /* -2.*31238./2.^15. */ B_2_2 = 0.90911865; /* 2.*14895./2.^15. */ ROW_DWELL = 128.; /* time to dwell at each row (in clocks) */ msgOutiff(MSG__DEBUG, "", FUNC_NAME ": filter for data UTC MJD %lf before %lf", status, filt->dateobs, datechange ); } CLOCK_PERIOD = 20E-9; /* 50 MHz clock */ NUM_ROWS = 41.; /* number of rows addressed */ DELTA_TIME = (CLOCK_PERIOD*ROW_DWELL*NUM_ROWS); /* sample length */ SRATE = (1./DELTA_TIME); /* sample rate */ /* Loop over all frequencies in the filter */ for( i=0; i<filt->fdims[0]; i++ ) { double cos_m_o; double sin_m_o; double cos_m_2o; double sin_m_2o; double f; gsl_complex den; gsl_complex h1_omega; gsl_complex h2_omega; gsl_complex h_omega; gsl_complex num; gsl_complex temp; double omega; f = filt->df[0]*i; /* Frequency at this step */ omega = (f / SRATE)*2*AST__DPI; /* Angular frequency */ cos_m_o = cos(-omega); sin_m_o = sin(-omega); cos_m_2o = cos(-2*omega); sin_m_2o = sin(-2*omega); /* h1_omega=(1 + 2*complex(cos_m_o,sin_m_o) + complex(cos_m_2o,sin_m_2o)) / (1 + b_1_1*complex(cos_m_o,sin_m_o) + b_1_2 * complex(cos_m_2o,sin_m_2o)) */ /* numerator */ GSL_SET_COMPLEX(&num, 1, 0); GSL_SET_COMPLEX(&temp, cos_m_o, sin_m_o); num = gsl_complex_add( num, gsl_complex_mul_real(temp, 2) ); GSL_SET_COMPLEX(&temp, cos_m_2o, sin_m_2o); num = gsl_complex_add( num, temp ); /* denominator */ GSL_SET_COMPLEX(&den, 1, 0); GSL_SET_COMPLEX(&temp, cos_m_o, sin_m_o); den = gsl_complex_add( den, gsl_complex_mul_real(temp,B_1_1) ); GSL_SET_COMPLEX(&temp, cos_m_2o, sin_m_2o); den = gsl_complex_add( den, gsl_complex_mul_real(temp,B_1_2) ); /* quotient */ h1_omega = gsl_complex_div( num, den ); /* h2_omega=(1 + 2*complex(cos_m_o,sin_m_o) + complex(cos_m_2o,sin_m_2o)) / (1 + b_2_1*complex(cos_m_o,sin_m_o) + b_2_2*complex(cos_m_2o,sin_m_2o)) note: we can re-use numerator from above */ /* denominator */ GSL_SET_COMPLEX(&den, 1, 0); GSL_SET_COMPLEX(&temp, cos_m_o, sin_m_o); den = gsl_complex_add( den, gsl_complex_mul_real(temp,B_2_1) ); GSL_SET_COMPLEX(&temp, cos_m_2o, sin_m_2o); den = gsl_complex_add( den, gsl_complex_mul_real(temp,B_2_2) ); /* quotient */ h2_omega = gsl_complex_div( num, den ); /* And finally... h_omega=h1_omega*h2_omega/2048. */ h_omega = gsl_complex_mul( h1_omega, gsl_complex_div_real(h2_omega,2048.) ); /* Normally we are applying the inverse of the filter to remove its effect from the time-series. */ if( !noinverse ) { h_omega = gsl_complex_inverse( h_omega ); } /* Then apply this factor to the filter. */ GSL_SET_COMPLEX( &temp, filt->real[i], filt->imag[i] ); temp = gsl_complex_mul( temp, h_omega ); filt->real[i] = GSL_REAL( temp ); filt->imag[i] = GSL_IMAG( temp ); } }
void AbsArg(param_ param, abs_info_ *abs_info, gsl_complex *W, double *absW, double *argW, gsl_complex *complex_rot) { /* * In this function, we calculate the abs and arg * values for every point on the lattice. We also * find the total and max values for the abs across * the entire lattice. */ int i, j, tmp_int; gsl_complex complex_I; double *max_array, tmp; int max_num_threads; int L=param.L; GSL_SET_COMPLEX(&complex_I,0.,1.); tmp = 0.; tmp_int = 0; (*abs_info).max=0.; #pragma omp parallel { /* * The optimization here creates an array once in the * main thread, of length equal to the total number * of threads, and then updates local maxima along * the individual threads, storing them in the newly * created array. At the end, the local maxima are * compared. */ #pragma omp master { max_num_threads = omp_get_num_threads(); max_array = (double *)calloc(max_num_threads,sizeof(double)); } int num; num=omp_get_thread_num(); #pragma omp barrier //this barrier ensures the array //is visible to all threads #pragma omp for reduction(+:tmp) for(i=0; i<L*L; i++) { absW[i]=gsl_complex_abs(W[i]); tmp += absW[i]; if(absW[i] > max_array[num]) max_array[num]=absW[i]; argW[i] = gsl_complex_arg(W[i]); complex_rot[i] = gsl_complex_exp(gsl_complex_mul_real(\ complex_I,(-0.5)*argW[i])); } #pragma omp barrier #pragma omp master { for(i=0; i<max_num_threads; i++) if(max_array[i] > (*abs_info).max) (*abs_info).max = max_array[i]; free(max_array); } } //end parallel construct (*abs_info).total = tmp; /* * Here, we find the total number of * points considered active according to * param.p_thresh. */ for(j=0; j<param.pr_range; j++) { tmp_int = 0; #pragma omp parallel for reduction(+:tmp_int) for(i=0; i<L*L; i++) if(absW[i] >= param.pr_thresh[j]*(*abs_info).max) tmp_int++; (*abs_info).int_total[j] = tmp_int; } }
void SumProduct::accumulateEigenCounts (vguard<vguard<double> >& rootCounts, vguard<vguard<vguard<gsl_complex> > >& eigenCounts, double weight) const { LogThisAt(8,"Accumulating eigencounts, column " << join(gappedCol,"") << ", weight " << weight << endl); accumulateRootCounts (rootCounts, weight); const auto rootNode = columnRoot(); const int A = model.alphabetSize(); vguard<double> U (A), D (A); vguard<gsl_complex> Ubasis (A), Dbasis (A); vguard<double> U0 (A), D0 (A); for (auto node : ungappedRows) if (node != rootNode) { LogThisAt(9,"Accumulating eigencounts, column " << join(gappedCol,"") << " node " << tree.seqName(node) << endl); const TreeNodeIndex parent = tree.parentNode(node); const TreeNodeIndex sibling = tree.getSibling(node); for (int cpt = 0; cpt < components(); ++cpt) { LogThisAt(9,"Accumulating eigencounts, column " << join(gappedCol,"") << " node " << tree.seqName(node) << " component #" << cpt << endl); const vguard<double>& U0 = F[cpt][node]; for (AlphTok i = 0; i < A; ++i) D0[i] = G[cpt][parent][i] * E[cpt][sibling][i]; const double maxU0 = *max_element (U0.begin(), U0.end()); const double maxD0 = *max_element (D0.begin(), D0.end()); const double norm = exp (colLogLike - logCptWeight[cpt] - logF[cpt][node] - logG[cpt][parent] - logE[cpt][sibling]) / (maxU0 * maxD0); // U[b] = U0[b] / maxU0; Ubasis[l] = sum_b U[b] * evecInv[l][b] for (AlphTok b = 0; b < A; ++b) U[b] = U0[b] / maxU0; for (AlphTok l = 0; l < A; ++l) { Ubasis[l] = gsl_complex_rect (0, 0); for (AlphTok b = 0; b < A; ++b) Ubasis[l] = gsl_complex_add (Ubasis[l], gsl_complex_mul_real (gsl_matrix_complex_get (eigen.evecInv[cpt], l, b), U[b])); } // D[a] = D0[a] / maxD0; Dbasis[k] = sum_a D[a] * evec[a][k] for (AlphTok a = 0; a < A; ++a) D[a] = D0[a] / maxD0; for (AlphTok k = 0; k < A; ++k) { Dbasis[k] = gsl_complex_rect (0, 0); for (AlphTok a = 0; a < A; ++a) Dbasis[k] = gsl_complex_add (Dbasis[k], gsl_complex_mul_real (gsl_matrix_complex_get (eigen.evec[cpt], a, k), D[a])); } // R = evec * evals * evecInv // exp(RT) = evec * exp(evals T) * evecInv // count(i,j|a,b,T) = Q / exp(RT)_ab // where... // Q = \sum_a \sum_b \int_{t=0}^T D_a exp(Rt)_ai R_ij exp(R(T-t))_jb U_b dt // = \sum_a \sum_b \int_{t=0}^T D_a (\sum_k evec_ak exp(eval_k t) evecInv_ki) R_ij (\sum_l evec_jl exp(eval_l (T-t)) evecInv_lb) U_b dt // = \sum_a \sum_b D_a \sum_k evec_ak evecInv_ki R_ij \sum_l evec_jl evecInv_lb U_b \int_{t=0}^T exp(eval_k t) exp(eval_l (T-t)) dt // = \sum_a \sum_b D_a \sum_k evec_ak evecInv_ki R_ij \sum_l evec_jl evecInv_lb U_b eigenSubCount(k,l,T) // = R_ij \sum_k evecInv_ki \sum_l evec_jl (\sum_a D_a evec_ak) (\sum_b U_b evecInv_lb) eigenSubCount(k,l,T) // = R_ij \sum_k evecInv_ki \sum_l evec_jl Dbasis_k Ubasis_l eigenSubCount(k,l,T) // eigenCounts[k][l] += Dbasis[k] * eigenSub[k][l] * Ubasis[l] / norm for (AlphTok k = 0; k < A; ++k) for (AlphTok l = 0; l < A; ++l) eigenCounts[cpt][k][l] = gsl_complex_add (eigenCounts[cpt][k][l], gsl_complex_mul_real (gsl_complex_mul (Dbasis[k], gsl_complex_mul (gsl_matrix_complex_get (branchEigenSubCount[cpt][node], k, l), Ubasis[l])), weight / norm)); // LogThisAt(9,"colLogLike=" << colLogLike << " logF[cpt][node]=" << logF[cpt][node] << " logG[cpt][parent]=" << logG[cpt][parent] << " logE[cpt][sibling]=" << logE[cpt][sibling] << " maxU0=" << maxU0 << " maxD0=" << maxD0 << endl); // LogThisAt(8,"Component #" << cpt << " eigencounts matrix (norm=" << norm << "):" << endl << complexMatrixToString(eigenCounts[cpt]) << endl); } } }
int gsl_eigen_hermv (gsl_matrix_complex * A, gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_hermv_workspace * w) { if (A->size1 != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != A->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (evec->size1 != A->size1 || evec->size2 != A->size1) { GSL_ERROR ("eigenvector matrix must match matrix size", GSL_EBADLEN); } else { const size_t N = A->size1; double *const d = w->d; double *const sd = w->sd; size_t a, b; /* handle special case */ if (N == 1) { gsl_complex A00 = gsl_matrix_complex_get (A, 0, 0); gsl_vector_set (eval, 0, GSL_REAL(A00)); gsl_matrix_complex_set (evec, 0, 0, GSL_COMPLEX_ONE); return GSL_SUCCESS; } /* Transform the matrix into a symmetric tridiagonal form */ { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_view sd_vec = gsl_vector_view_array (sd, N - 1); gsl_vector_complex_view tau_vec = gsl_vector_complex_view_array (w->tau, N-1); gsl_linalg_hermtd_decomp (A, &tau_vec.vector); gsl_linalg_hermtd_unpack (A, &tau_vec.vector, evec, &d_vec.vector, &sd_vec.vector); } /* Make an initial pass through the tridiagonal decomposition to remove off-diagonal elements which are effectively zero */ chop_small_elements (N, d, sd); /* Progressively reduce the matrix until it is diagonal */ b = N - 1; while (b > 0) { if (sd[b - 1] == 0.0 || isnan(sd[b - 1])) { b--; continue; } /* Find the largest unreduced block (a,b) starting from b and working backwards */ a = b - 1; while (a > 0) { if (sd[a - 1] == 0.0) { break; } a--; } { size_t i; const size_t n_block = b - a + 1; double *d_block = d + a; double *sd_block = sd + a; double * const gc = w->gc; double * const gs = w->gs; /* apply QR reduction with implicit deflation to the unreduced block */ qrstep (n_block, d_block, sd_block, gc, gs); /* Apply Givens rotation Gij(c,s) to matrix Q, Q <- Q G */ for (i = 0; i < n_block - 1; i++) { const double c = gc[i], s = gs[i]; size_t k; for (k = 0; k < N; k++) { gsl_complex qki = gsl_matrix_complex_get (evec, k, a + i); gsl_complex qkj = gsl_matrix_complex_get (evec, k, a + i + 1); /* qki <= qki * c - qkj * s */ /* qkj <= qki * s + qkj * c */ gsl_complex x1 = gsl_complex_mul_real(qki, c); gsl_complex y1 = gsl_complex_mul_real(qkj, -s); gsl_complex x2 = gsl_complex_mul_real(qki, s); gsl_complex y2 = gsl_complex_mul_real(qkj, c); gsl_complex qqki = gsl_complex_add(x1, y1); gsl_complex qqkj = gsl_complex_add(x2, y2); gsl_matrix_complex_set (evec, k, a + i, qqki); gsl_matrix_complex_set (evec, k, a + i + 1, qqkj); } } /* remove any small off-diagonal elements */ chop_small_elements (n_block, d_block, sd_block); } } { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_memcpy (eval, &d_vec.vector); } return GSL_SUCCESS; } }
int lls_complex_stdform(gsl_matrix_complex *A, gsl_vector_complex *b, const gsl_vector *wts, const gsl_vector *L, lls_complex_workspace *w) { const size_t n = A->size1; const size_t p = A->size2; if (p != w->p) { fprintf(stderr, "lls_complex_stdform: A has wrong size2\n"); return GSL_EBADLEN; } else if (n != b->size) { fprintf(stderr, "lls_complex_stdform: b has wrong size\n"); return GSL_EBADLEN; } else if (wts != NULL && n != wts->size) { fprintf(stderr, "lls_complex_stdform: wts has wrong size\n"); return GSL_EBADLEN; } else if (L != NULL && p != L->size) { fprintf(stderr, "lls_complex_stdform: L has wrong size\n"); return GSL_EBADLEN; } else { int s = 0; size_t i; if (wts != NULL) { for (i = 0; i < n; ++i) { gsl_vector_complex_view rv = gsl_matrix_complex_row(A, i); gsl_complex bi = gsl_vector_complex_get(b, i); double wi = gsl_vector_get(wts, i); double sqrtwi = sqrt(wi); gsl_complex val; GSL_SET_COMPLEX(&val, sqrtwi, 0.0); /* A <- sqrt(W) A */ gsl_vector_complex_scale(&rv.vector, val); /* b <- sqrt(W) b */ val = gsl_complex_mul_real(bi, sqrtwi); gsl_vector_complex_set(b, i, val); } } if (L != NULL) { /* A <- sqrt(W) A L^{-1} */ for (i = 0; i < p; ++i) { gsl_vector_complex_view cv = gsl_matrix_complex_column(A, i); double Li = gsl_vector_get(L, i); gsl_complex val; if (Li == 0.0) { GSL_ERROR("L matrix is singular", GSL_ESING); } GSL_SET_COMPLEX(&val, 1.0 / Li, 0.0); gsl_vector_complex_scale(&cv.vector, val); } } return s; } } /* lls_complex_stdform() */
double OneSim(param_ param, FILE *pipe, arr_info_ arr_info_0, lattice_point_ **nghb, gsl_complex **K, gsl_complex *W, gsl_complex *CW, gsl_complex *dW, gsl_complex *complex_rot, double *argW, double *absW, double *rec, double *prec, pr_max_ *pr_max){ int i; double t = 0.; double *p_levl, *r_levl; abs_info_ abs_info; arr_info_ arr_info; pr_ *rW = NULL, *pW = NULL, *eW = NULL; /* * Zero-ing the pr_max array */ for(i=0;i<param.pr_range;i++){ pr_max[i].rec = 0.; pr_max[i].prec = 0.; } /* * Need to allocate the int_total array * of abs_info. */ abs_info.int_total = (int *)malloc(param.pr_range*sizeof(int)); arr_info.nghb_N = arr_info_0.nghb_N; arr_info.r_N = 0; arr_info.p_N = 0; arr_info.e_N = 0; /* * Clutter needs to be started first */ InitZeros(param, CW); InitAmoeba(param, &arr_info, CW, &rW, &pW, &eW); InitClutter(param, CW); /* * Reset the important arrays before * generating the real amoeba. */ free(rW); rW = NULL; free(pW); pW = NULL; free(eW); eW = NULL; arr_info.r_N = 0; arr_info.p_N = 0; arr_info.e_N = 0; InitZeros(param, W); InitAmoeba(param, &arr_info, W, &rW, &pW, &eW); /* * Reserve memory of the levl arrays */ p_levl = (double *)malloc(arr_info.p_N*sizeof(double)); r_levl = (double *)malloc(arr_info.r_N*sizeof(double)); /* * Check the exclusion zone */ ChckExcl(param, arr_info, CW, eW); /* * Time to add the clutter to the amoeba */ for(i=0;i<param.L*param.L;i++) if(gsl_complex_abs2(W[i]) < EPS) W[i] = CW[i]; AbsArg(param, &abs_info, W, absW, argW, complex_rot); while(t<param.T){ t+=param.dt; Quiver(param,pipe,absW,argW,abs_info.max,t); FieldUpdate(param, arr_info, K, W, dW, absW, complex_rot, nghb); #pragma omp parallel for for(i=0;i<param.L*param.L;i++) W[i]=gsl_complex_add(W[i],gsl_complex_mul_real(dW[i],param.dt)); AbsArg(param, &abs_info, W, absW, argW, complex_rot); FieldRedux(param, W, absW, abs_info); CalculateRecall(param, rec, arr_info, absW, argW, rW, r_levl); CalculatePrecision(param, prec, abs_info, arr_info, absW, argW, pW, p_levl); /* * Time to calculate max precision * and recall for all threshold values. * We use that to evaluate the performance * of the current choice of parameters. */ for(i=0;i<param.pr_range;i++) if(rec[i]+prec[i] > pr_max[i].rec + pr_max[i].prec){ pr_max[i].rec = rec[i]; pr_max[i].prec = prec[i]; } } free(rW); free(pW); free(eW); free(p_levl); free(r_levl); free(abs_info.int_total); return t; }
void LALInferenceTemplateROQ(LALInferenceModel *model) { double m1,m2,mc,eta,q,iota=0; /* Prefer m1 and m2 if available (i.e. for injection template) */ if(LALInferenceCheckVariable(model->params,"mass1")&&LALInferenceCheckVariable(model->params,"mass2")) { m1=*(REAL8 *)LALInferenceGetVariable(model->params,"mass1"); m2=*(REAL8 *)LALInferenceGetVariable(model->params,"mass2"); eta=m1*m2/((m1+m2)*(m1+m2)); mc=pow(eta , 0.6)*(m1+m2); } else { if (LALInferenceCheckVariable(model->params,"q")) { q = *(REAL8 *)LALInferenceGetVariable(model->params,"q"); q2eta(q, &eta); } else eta = *(REAL8*) LALInferenceGetVariable(model->params, "eta"); mc = *(REAL8*) LALInferenceGetVariable(model->params, "chirpmass"); mc2masses(mc, eta, &m1, &m2); } iota = acos(LALInferenceGetREAL8Variable(model->params, "costheta_jn")); /* zenith angle between J and N in radians */ double cosiota = cos(iota); double plusCoef = 0.5 * (1.0 + cosiota*cosiota); double crossCoef = cosiota; /* external: SI; internal: solar masses */ const REAL8 m = m1 + m2; const REAL8 m_sec = m * LAL_MTSUN_SI; /* total mass in seconds */ const REAL8 etap2 = eta * eta; const REAL8 etap3 = etap2 * eta; const REAL8 piM = LAL_PI * m_sec; const REAL8 mSevenBySix = -7./6.; const REAL8 phic = *(REAL8 *)LALInferenceGetVariable(model->params,"phase"); const REAL8 r = 1e6*LAL_PC_SI; REAL8 logv0 = log(1.); //the standard tf2 definition is log(v0), but I've changed it to reflect Scott's convention REAL8 shft, amp0;//, f_max; REAL8 psiNewt, psi2, psi3, psi4, psi5, psi6, psi6L, psi7, psi3S, psi4S, psi5S; REAL8 eta_fac = -113. + 76. * eta; REAL8 chi=0; //NOTE: chi isn't used here yet, so we just set it to zero gsl_complex h_i; /* extrinsic parameters */ amp0 = -pow(m_sec, 5./6.) * sqrt(5.*eta / 24.) / (Pi_p2by3 * r / LAL_C_SI); shft = 0;//LAL_TWOPI * (tStart.gpsSeconds + 1e-9 * tStart.gpsNanoSeconds); /* spin terms in the amplitude and phase (in terms of the reduced * spin parameter */ psi3S = 113.*chi/3.; psi4S = 63845.*(-81. + 4.*eta)*chi*chi/(8. * eta_fac * eta_fac); psi5S = -565.*(-146597. + 135856.*eta + 17136.*etap2)*chi/(2268.*eta_fac); /* coefficients of the phase at PN orders from 0 to 3.5PN */ psiNewt = 3./(128.*eta); psi2 = 3715./756. + 55.*eta/9.; psi3 = psi3S - 16.*LAL_PI; psi4 = 15293365./508032. + 27145.*eta/504. + 3085.*eta*eta/72. + psi4S; psi5 = (38645.*LAL_PI/756. - 65.*LAL_PI*eta/9. + psi5S); psi6 = 11583231236531./4694215680. - (640.*Pi_p2)/3. - (6848.*LAL_GAMMA)/21. + (-5162.983708047263 + 2255.*Pi_p2/12.)*eta + (76055.*etap2)/1728. - (127825.*etap3)/1296.; psi6L = -6848./21.; psi7 = (77096675.*LAL_PI)/254016. + (378515.*LAL_PI*eta)/1512. - (74045.*LAL_PI*eta*eta)/756.; for (unsigned int i = 0; i < model->roq->frequencyNodes->size; i++) { /* fourier frequency corresponding to this bin */ const REAL8 f = gsl_vector_get(model->roq->frequencyNodes, i); const REAL8 v3 = piM*f; /* PN expansion parameter */ REAL8 v, v2, v4, v5, v6, v7, logv, Psi, amp; v = cbrt(v3); v2 = v*v; v4 = v3*v; v5 = v4*v; v6 = v3*v3; v7 = v6*v; logv = log(v); /* compute the phase and amplitude */ Psi = psiNewt / v5 * (1. + psi2 * v2 + psi3 * v3 + psi4 * v4 + psi5 * v5 * (1. + 3. * (logv - logv0)) + (psi6 + psi6L * (log4 + logv)) * v6 + psi7 * v7); amp = amp0 * pow(f, mSevenBySix); GSL_SET_COMPLEX(&h_i, amp * cos(Psi + shft * f - 2.*phic - LAL_PI_4), - amp * sin(Psi + shft * f - 2.*phic - LAL_PI_4)); gsl_vector_complex_set(model->roq->hplus, i, gsl_complex_mul_real(h_i,plusCoef)); gsl_vector_complex_set(model->roq->hcross, i, gsl_complex_mul_real(gsl_complex_mul_imag(h_i,-1.0),crossCoef)); } return; }
/****************************************************************************** * calc_X() * This function calcs the X's and g's for a given theta. * * Parameters * --------- * * Returns * ------- * * Notes * ----- * This function computes * X[j] = Ar[j]/Ai[j] * where Ar[j] and Ai[j] are the field amplitdues within layer j at * the j/j-1 interface. For the base layer X[0] = 0, * ie there is no reflected field in the substrate. While * X[nlayers-1] is the field intensity at the top of the multilayer, * therefore |X[nlayers-1]|^2 = R * * The X's are calculated using the optical recursion formlua, starting at the bottom * where X[0] = 0 and calc X[1], and proceding to calc of X[nlayer-1]: * * X[j] = ( r[j] + X[j-1]*phase) / (1 + r[j]*X[j-1]*phase) * * The r[j] values are the reflection coefficients for the j/j-1 interface, * and calculated from: * * r[j] = (g[j]-g[j-1])/(g[j]+g[j-1]) * * This function also includes an interfacial roughness term mult into * the reflection coefficient for the j/j-1 interface: * * r[j] = r[j]*exp(-1.0(q*sig[j])^2) * * The phase term accounts for the phase shift and attentuation of the field * traversing the j-1 layer (ie from the j-1/j-2 interface to the j/j-1 interface) * * phase = exp( -i* 2*k*d[j-1] * g[j-1]) * * Note if j == 1 then the phase for layer j-1 is 0.0, * ie infinitley thick base layer * * Note: g[j] = sqrt( n[j]^2 - cos(theta)^2 ) * where n[j] is the layers index of refraction: n[j] = 1-del[j]-i*bet[j] * Hence, each layer has a unique g value. We assume here * that the del[j] and bet[j] have already been calculated * (see calc_del_bet(), this should be called before this function). * * * Note: double check how doing the phase calc below, is that the best way?? * e.g. could we use: * phase = gsl_complex_exp( gsl_complex_mul_real(g1,-1.0*k*d[j])); * instead of * phase = gsl_complex_exp( gsl_complex_mul(phase,g1)); * * Note we should move the g and r calc to a new function, possibly calc the * t values as well and store these so we dont have to recalc in calc_A() (???) * ******************************************************************************/ int calc_X(double theta, ref_model *ref, angle_calc *ang_c, layer_calc *lay_c){ int i, j; double cos_sqr_thet, k, q, dw; double *d, *sig; gsl_complex g1, g2, num, den, r, X2, X1, n1, n2, phase; // convenience vars cos_sqr_thet = square(cos(theta*M_PI/180.)); k = ref->k; q = 2.0*k*sin((theta*M_PI/180.)); d = ref->d; sig = ref->sigma; // start at bottom // ie interface 0 ang_c->Re_X[0] = GSL_REAL(X1) = 0.0; ang_c->Im_X[0] = GSL_IMAG(X1) = 0.0; // calc g for base layer (g[0]) // n = 1 - del -i*bet // g = sqrt( n^2 - cos(theta)^2 ) GSL_REAL(n1) = 1.0 - lay_c->del[0]; GSL_IMAG(n1) = -1.0*lay_c->bet[0]; g1 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n1, n1), cos_sqr_thet) ); // store g for base layer ang_c->Re_g[0] = GSL_REAL(g1); ang_c->Im_g[0] = GSL_IMAG(g1); // loop over all layers // note j is upper layer and i is the interface number // the loop starts considering the first interface (i=0) // which is the interface between the base layer (j=0) // and the first layer (j=1) ie the 1/0 interface // note there are nlayer-1 interfaces... i = 0; for ( j = 1; j < ref->nlayer; j++){ // calc g for upper layer // n = 1 - del -i*bet // g2 = sqrt( n^2 - cos(theta)^2 ) GSL_REAL(n2) = 1.0 - lay_c->del[j]; GSL_IMAG(n2) = -1.0 * lay_c->bet[j]; g2 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n2, n2), cos_sqr_thet) ); // store g for layer j ang_c->Re_g[j] = GSL_REAL(g2); ang_c->Im_g[j] = GSL_IMAG(g2); // calculate r for the j/j-1 interface // r_j = (g2-g1)/(g2+g1) //GSL_SET_COMPLEX(&num,0.0,0.0); //GSL_SET_COMPLEX(&den,0.0,0.0); //GSL_SET_COMPLEX(&r,0.0,0.0); num = gsl_complex_sub(g2,g1); den = gsl_complex_add(g2,g1); r = gsl_complex_div(num,den); // calc r including roughness // simple dw roughness model // r = r*exp(-1.0(q*sig)^2) // sigma[i] if (ref->sigma[j] > 0.0){ //dw = exp(-1.0*square(q*ref->sigma[j])); dw = exp(-1.0*square(q*ref->sigma[i])); r = gsl_complex_mul_real(r,dw); } //calc phase shift and attentuation for //field traversing the j-1 layer //phase = exp( -i* 2*k*d[j-1] * g1) // if j == 1 then the phase for layer j-1 // is 0.0, ie infinitley thick base layer if (j == 1){ GSL_REAL(phase) = 0.0; GSL_IMAG(phase) = 0.0; } else { // check here GSL_REAL(phase) = 0.0; GSL_IMAG(phase) = -2.0*k*d[j-1]; phase = gsl_complex_exp( gsl_complex_mul(phase,g1)); } // calc Xj // X2 = ( r + X1*phase) / (1 + r*X1*phase) //GSL_SET_COMPLEX(&num,0.0,0.0); //GSL_SET_COMPLEX(&den,0.0,0.0); num = gsl_complex_add(r,gsl_complex_mul(X1,phase)); den = gsl_complex_add_real(gsl_complex_mul(r,gsl_complex_mul(X1,phase)), 1.0); X2 = gsl_complex_div(num,den); if (fabs(GSL_REAL(X2)) < 1e-10){ GSL_REAL(X2) = 0.0; } if (fabs(GSL_IMAG(X2)) < 1e-10){ GSL_IMAG(X2) = 0.0; } // store values of Xj ang_c->Re_X[j] = GSL_REAL(X2); ang_c->Im_X[j] = GSL_IMAG(X2); // use top layer as bottom for next time through GSL_REAL(X1) = GSL_REAL(X2); GSL_IMAG(X1) = GSL_IMAG(X2); // do the same for g's GSL_REAL(g1) = GSL_REAL(g2); GSL_IMAG(g1) = GSL_IMAG(g2); //increment the interface number i++; } return (SUCCESS); }