int lls_complex_btransform(const gsl_vector *L, gsl_vector_complex *c, lls_complex_workspace *w) { size_t p = c->size; if (L->size != p) { GSL_ERROR("L and c vectors have different sizes", GSL_EBADLEN); } else { size_t i; for (i = 0; i < p; ++i) { gsl_complex ci = gsl_vector_complex_get(c, i); double Li = gsl_vector_get(L, i); if (Li == 0.0) { GSL_ERROR("L matrix is singular", GSL_ESING); } gsl_vector_complex_set(c, i, gsl_complex_div_real(ci, Li)); } return GSL_SUCCESS; } } /* lls_complex_btransform() */
gsl_complex gsl_linalg_complex_LU_sgndet (gsl_matrix_complex * LU, int signum) { size_t i, n = LU->size1; gsl_complex phase = gsl_complex_rect((double) signum, 0.0); for (i = 0; i < n; i++) { gsl_complex z = gsl_matrix_complex_get (LU, i, i); double r = gsl_complex_abs(z); if (r == 0) { phase = gsl_complex_rect(0.0, 0.0); break; } else { z = gsl_complex_div_real(z, r); phase = gsl_complex_mul(phase, z); } } return phase; }
/* 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); }
/* 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; }
/** * Returns the symmetry axis for the given matrix * * According to ITA, 11.2 the axis of a symmetry operation can be determined by * solving the Eigenvalue problem \f$Wu = u\f$ for rotations or \f$Wu = -u\f$ * for rotoinversions. This is implemented using the general real non-symmetric * eigen-problem solver provided by the GSL. * * @param matrix :: Matrix of a SymmetryOperation * @return Axis of symmetry element. */ V3R SymmetryElementWithAxisGenerator::determineAxis( const Kernel::IntMatrix &matrix) const { gsl_matrix *eigenMatrix = getGSLMatrix(matrix); gsl_matrix *identityMatrix = getGSLIdentityMatrix(matrix.numRows(), matrix.numCols()); gsl_eigen_genv_workspace *eigenWs = gsl_eigen_genv_alloc(matrix.numRows()); gsl_vector_complex *alpha = gsl_vector_complex_alloc(3); gsl_vector *beta = gsl_vector_alloc(3); gsl_matrix_complex *eigenVectors = gsl_matrix_complex_alloc(3, 3); gsl_eigen_genv(eigenMatrix, identityMatrix, alpha, beta, eigenVectors, eigenWs); gsl_eigen_genv_sort(alpha, beta, eigenVectors, GSL_EIGEN_SORT_ABS_DESC); double determinant = matrix.determinant(); Kernel::V3D eigenVector; for (size_t i = 0; i < matrix.numCols(); ++i) { double eigenValue = GSL_REAL(gsl_complex_div_real( gsl_vector_complex_get(alpha, i), gsl_vector_get(beta, i))); if (fabs(eigenValue - determinant) < 1e-9) { for (size_t j = 0; j < matrix.numRows(); ++j) { double element = GSL_REAL(gsl_matrix_complex_get(eigenVectors, j, i)); eigenVector[j] = element; } } } eigenVector *= determinant; double sumOfElements = eigenVector.X() + eigenVector.Y() + eigenVector.Z(); if (sumOfElements < 0) { eigenVector *= -1.0; } gsl_matrix_free(eigenMatrix); gsl_matrix_free(identityMatrix); gsl_eigen_genv_free(eigenWs); gsl_vector_complex_free(alpha); gsl_vector_free(beta); gsl_matrix_complex_free(eigenVectors); double min = 1.0; for (size_t i = 0; i < 3; ++i) { double absoluteValue = fabs(eigenVector[i]); if (absoluteValue != 0.0 && (eigenVector[i] < min && (absoluteValue - fabs(min)) < 1e-9)) { min = eigenVector[i]; } } V3R axis; for (size_t i = 0; i < 3; ++i) { axis[i] = static_cast<int>(boost::math::round(eigenVector[i] / min)); } return axis; }
complex& complex::operator/=(const double& a) { _complex = gsl_complex_div_real(_complex,a); return *this; }
complex complex::operator/(const double& a) const { gsl_complex rl = gsl_complex_div_real(_complex,a); return complex(rl); }
int gsl_eigen_genv_sort (gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type) { if (evec->size1 != evec->size2) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (alpha->size != evec->size1 || beta->size != evec->size1) { GSL_ERROR ("eigenvalues must match eigenvector matrix", GSL_EBADLEN); } else { const size_t N = alpha->size; size_t i; for (i = 0; i < N - 1; i++) { size_t j; size_t k = i; gsl_complex ak = gsl_vector_complex_get (alpha, i); double bk = gsl_vector_get(beta, i); gsl_complex ek; if (bk < GSL_DBL_EPSILON) { GSL_SET_COMPLEX(&ek, GSL_SIGN(GSL_REAL(ak)) ? GSL_POSINF : GSL_NEGINF, GSL_SIGN(GSL_IMAG(ak)) ? GSL_POSINF : GSL_NEGINF); } else ek = gsl_complex_div_real(ak, bk); /* search for something to swap */ for (j = i + 1; j < N; j++) { int test; const gsl_complex aj = gsl_vector_complex_get (alpha, j); double bj = gsl_vector_get(beta, j); gsl_complex ej; if (bj < GSL_DBL_EPSILON) { GSL_SET_COMPLEX(&ej, GSL_SIGN(GSL_REAL(aj)) ? GSL_POSINF : GSL_NEGINF, GSL_SIGN(GSL_IMAG(aj)) ? GSL_POSINF : GSL_NEGINF); } else ej = gsl_complex_div_real(aj, bj); switch (sort_type) { case GSL_EIGEN_SORT_ABS_ASC: test = (gsl_complex_abs (ej) < gsl_complex_abs (ek)); break; case GSL_EIGEN_SORT_ABS_DESC: test = (gsl_complex_abs (ej) > gsl_complex_abs (ek)); break; case GSL_EIGEN_SORT_VAL_ASC: case GSL_EIGEN_SORT_VAL_DESC: default: GSL_ERROR ("invalid sort type", GSL_EINVAL); } if (test) { k = j; ek = ej; } } if (k != i) { /* swap eigenvalues */ gsl_vector_complex_swap_elements (alpha, i, k); gsl_vector_swap_elements (beta, i, k); /* swap eigenvectors */ gsl_matrix_complex_swap_columns (evec, i, k); } } return GSL_SUCCESS; } }
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 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); }
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); }
int main(int argc, char *argv[]) { gen_workspace *gen_workspace_p; lapack_workspace *lapack_workspace_p; size_t N; int c; int lower; int upper; int incremental; size_t nmat; gsl_matrix *A, *B; gsl_rng *r; int s; int compute_schur; size_t i; gsl_ieee_env_setup(); gsl_rng_env_setup(); N = 30; lower = -10; upper = 10; incremental = 0; nmat = 0; compute_schur = 0; while ((c = getopt(argc, argv, "ic:n:l:u:z")) != (-1)) { switch (c) { case 'i': incremental = 1; break; case 'n': N = strtol(optarg, NULL, 0); break; case 'l': lower = strtol(optarg, NULL, 0); break; case 'u': upper = strtol(optarg, NULL, 0); break; case 'c': nmat = strtoul(optarg, NULL, 0); break; case 'z': compute_schur = 1; break; case '?': default: printf("usage: %s [-i] [-z] [-n size] [-l lower-bound] [-u upper-bound] [-c num]\n", argv[0]); exit(1); break; } /* switch (c) */ } A = gsl_matrix_alloc(N, N); B = gsl_matrix_alloc(N, N); gen_workspace_p = gen_alloc(N, compute_schur); lapack_workspace_p = lapack_alloc(N); r = gsl_rng_alloc(gsl_rng_default); if (incremental) { make_start_matrix(A, lower); /* we need B to be non-singular */ make_random_integer_matrix(B, r, lower, upper); } fprintf(stderr, "testing N = %d", N); if (incremental) fprintf(stderr, " incrementally"); else fprintf(stderr, " randomly"); fprintf(stderr, " on element range [%d, %d]", lower, upper); if (compute_schur) fprintf(stderr, ", with Schur vectors"); fprintf(stderr, "\n"); while (1) { if (nmat && (count >= nmat)) break; ++count; if (!incremental) { make_random_matrix(A, r, lower, upper); make_random_matrix(B, r, lower, upper); } else { s = inc_matrix(A, lower, upper); if (s) break; /* all done */ make_random_integer_matrix(B, r, lower, upper); } /*if (count != 89120) continue;*/ /* make copies of matrices */ gsl_matrix_memcpy(gen_workspace_p->A, A); gsl_matrix_memcpy(gen_workspace_p->B, B); gsl_matrix_transpose_memcpy(lapack_workspace_p->A, A); gsl_matrix_transpose_memcpy(lapack_workspace_p->B, B); /* compute eigenvalues with LAPACK */ s = lapack_proc(lapack_workspace_p); if (s != GSL_SUCCESS) { printf("LAPACK failed, case %lu\n", count); exit(1); } #if 0 print_matrix(A, "A"); print_matrix(B, "B"); gsl_matrix_transpose(lapack_workspace_p->A); gsl_matrix_transpose(lapack_workspace_p->B); print_matrix(lapack_workspace_p->A, "S_lapack"); print_matrix(lapack_workspace_p->B, "T_lapack"); #endif /* compute eigenvalues with GSL */ s = gen_proc(gen_workspace_p); if (s != GSL_SUCCESS) { printf("=========== CASE %lu ============\n", count); printf("Failed to converge: found %u eigenvalues\n", gen_workspace_p->n_evals); print_matrix(A, "A"); print_matrix(B, "B"); print_matrix(gen_workspace_p->A, "Af"); print_matrix(gen_workspace_p->B, "Bf"); print_matrix(lapack_workspace_p->A, "Ae"); print_matrix(lapack_workspace_p->B, "Be"); exit(1); } #if 0 print_matrix(gen_workspace_p->A, "S_gsl"); print_matrix(gen_workspace_p->B, "T_gsl"); #endif /* compute alpha / beta vectors */ for (i = 0; i < N; ++i) { double beta; gsl_complex alpha, z; beta = gsl_vector_get(gen_workspace_p->beta, i); if (beta == 0.0) GSL_SET_COMPLEX(&z, GSL_POSINF, GSL_POSINF); else { alpha = gsl_vector_complex_get(gen_workspace_p->alpha, i); z = gsl_complex_div_real(alpha, beta); } gsl_vector_complex_set(gen_workspace_p->evals, i, z); beta = gsl_vector_get(lapack_workspace_p->beta, i); GSL_SET_COMPLEX(&alpha, lapack_workspace_p->alphar[i], lapack_workspace_p->alphai[i]); if (beta == 0.0) GSL_SET_COMPLEX(&z, GSL_POSINF, GSL_POSINF); else z = gsl_complex_div_real(alpha, beta); gsl_vector_complex_set(lapack_workspace_p->evals, i, z); gsl_vector_complex_set(lapack_workspace_p->alpha, i, alpha); } #if 0 gsl_sort_vector(gen_workspace_p->beta); gsl_sort_vector(lapack_workspace_p->beta); sort_complex_vector(gen_workspace_p->alpha); sort_complex_vector(lapack_workspace_p->alpha); s = test_alpha(gen_workspace_p->alpha, lapack_workspace_p->alpha, A, B, "gen", "lapack"); s = test_beta(gen_workspace_p->beta, lapack_workspace_p->beta, A, B, "gen", "lapack"); #endif #if 1 sort_complex_vector(gen_workspace_p->evals); sort_complex_vector(lapack_workspace_p->evals); s = test_evals(gen_workspace_p->evals, lapack_workspace_p->evals, A, B, "gen", "lapack"); #endif if (compute_schur) { test_schur(A, gen_workspace_p->A, gen_workspace_p->Q, gen_workspace_p->Z); test_schur(B, gen_workspace_p->B, gen_workspace_p->Q, gen_workspace_p->Z); } } gsl_matrix_free(A); gsl_matrix_free(B); gen_free(gen_workspace_p); lapack_free(lapack_workspace_p); if (r) gsl_rng_free(r); return 0; } /* main() */