/* * FUNCTION * Name: stationary * Description: Given the dissipator in Bloch form, reduce to a 3x3 problem and store * the stationary state in the 3x1 vector *X * * M X = 0 * * | 0 0 0 0 | | 1 | 0 * | M10 M11 M12 M13 | | X1 | 0 * | M20 M21 M22 M23 | | X2 | = 0 * | M30 M31 M32 M33 | | X3 | 0 * * * A x = b * * | M11 M12 M13 | | X1 | | -M10 | * | M21 M22 M23 | | X2 | = | -M20 | * | M31 M32 M33 | | X3 | | -M30 | */ int stationary ( const gsl_matrix* M, gsl_vector* stat_state ) { /* Store space for the stationary state */ gsl_vector* req = gsl_vector_calloc ( 4 ) ; gsl_vector_set ( req, 0, 1 ) ; /* Copy the dissipator matrix in a temporary local matrix m * (because the algorithm destroys it...) */ gsl_matrix* m = gsl_matrix_calloc ( 4, 4 ) ; gsl_matrix_memcpy ( m, M ) ; /* Create a view of the spatial part of vector req */ gsl_vector_view x = gsl_vector_subvector ( req, 1, 3 ) ; /* Create a submatrix view of the spatial part of m and a vector view * of the spatial part of the 0-th column, which goes into -b in the system * A x = b */ gsl_matrix_view A = gsl_matrix_submatrix ( m, 1, 1, 3, 3 ) ; gsl_vector_view b = gsl_matrix_subcolumn ( m, 0, 1, 3 ) ; int status1 = gsl_vector_scale ( &b.vector, -1.0 ) ; /* Solve the system A x = b using Householder transformations. * Changing the view x of req => also req is changed, in the spatial part */ int status2 = gsl_linalg_HH_solve ( &A.matrix, &b.vector, &x.vector ) ; /* Set the returning value for the state stat_state */ *stat_state = *req ; /* Free memory */ gsl_matrix_free(m) ; return status1 + status2 ; } /* ----- end of function stationary ----- */
void tGSLSolve::solveHouseholder(void) { gsl_matrix* tmp = gsl_matrix_calloc(N,N); gsl_matrix_memcpy(tmp, MATRIX); for (int i=0;i<RHS.count() && i<x.count(); i++){ gsl_linalg_HH_solve (tmp, RHS.at(i), x.at(i)); } }
/* Householder solver */ CAMLprim value ml_gsl_linalg_HH_solve(value A, value B, value X) { _DECLARE_MATRIX(A); _DECLARE_VECTOR2(B,X); _CONVERT_MATRIX(A); _CONVERT_VECTOR2(B,X); gsl_linalg_HH_solve(&m_A, &v_B, &v_X); return Val_unit; }
/* *data[0..nharmonics], *var[0..2*nharmonics] */ double calcChiReduction(int nharmonics, const float *cosdata, const float *sindata, const float *cosvar, const float *sinvar, gsl_matrix *alpha, gsl_vector *beta, gsl_vector *x) { double chisqred; calcAlphaBeta(nharmonics, cosdata, sindata, cosvar, sinvar, alpha, beta); /* alpha and beta are now fully set. Time to solve */ /* Stick in your thumb and pull out a plum: solve by Householder */ gsl_linalg_HH_solve(alpha, beta, x); /* x = alpha^-1 beta */ gsl_blas_ddot(x, beta, &chisqred); return chisqred; }
// ----------------------------------------------------------------- // Solve [ sqrt(y[m]) * P(c, y[m]) + (-1)^m u == 1. , {c, u} ] static void solvesystem(double *c, double *u, int n, double *y, double epsilon) { int i, m; double T[n + 1], z, sy, sign = 1.0, X; gsl_matrix *A = gsl_matrix_alloc(n + 2, n + 2); gsl_vector *b = gsl_vector_alloc(n + 2); gsl_vector *x = gsl_vector_alloc(n + 2); for (m = 0; m <= n + 1; m++) { z = (2.0 * y[m] - 1.0 - epsilon) / (1.0 - epsilon); sy = sqrt(y[m]); Chebyshev(T, n, z); for (i = 0; i <= n; i++) gsl_matrix_set(A, m, i, sy * T[i]); gsl_matrix_set(A, m, n + 1, sign); sign = -sign; gsl_vector_set(b, m, 1.0); } gsl_linalg_HH_solve(A, b, x); for (i = 0; i <= n; i++) c[i] = gsl_vector_get(x, i); *u = gsl_vector_get(x, n + 1); for (m = 0; m <= n + 1; m++) { z = (2.0 * y[m] - 1.0 - epsilon) / (1.0 - epsilon); sy = sqrt(y[m]); Chebyshev(T, n, z); X = 1.0; for (i = 0; i <= n; i++) X = X - c[i] * sy * T[i]; } }
/** * C++ version of gsl_linalg_HH_solve(). * @param A A matrix * @param b A vector * @param x A vector * @return Error code on failure */ inline int HH_solve( matrix& A, vector const& b, vector& x ){ return gsl_linalg_HH_solve( A.get(), b.get(), x.get() ); }
/* coefficients as well */ double singleChi(const double *sampletimes, const float *vals, const float *stderrs, long ndata, long nharmonics, double tstart, double frequency, float *harmoniccoeffs) { #define MAXHARM 17 int i, j, d; int result; double alpha[2*MAXHARM+1][2*MAXHARM+1]; double beta[2*MAXHARM+1]; double chisqred; gsl_matrix *alpha_gsl = gsl_matrix_alloc(2 * nharmonics + 1,2 * nharmonics + 1); gsl_vector *beta_gsl = gsl_vector_alloc(2 * nharmonics + 1); gsl_vector *x_gsl = gsl_vector_alloc(2 * nharmonics + 1); assert(nharmonics <= MAXHARM); for (i = 0 ; i < 2*nharmonics+1 ; i++) { beta[i] = 0; for (j = 0 ; j < 2*nharmonics+1 ; j++) alpha[i][j] = 0; } for (d = 0 ; d < ndata ; d++) { for (i = 0 ; i < 2*nharmonics+1 ; i++) { double invvar = 1/(stderrs[d] * stderrs[d]); beta[i] += vals[d] * invvar * Mfunc(i, (sampletimes[d] - tstart) * frequency * 2 * M_PI); for (j = 0 ; j < 2*nharmonics+1 ; j++) alpha[i][j] += invvar * Mfunc(i, (sampletimes[d] - tstart) * frequency * 2 * M_PI) * Mfunc(j, (sampletimes[d] - tstart) * frequency * 2 * M_PI); } } for (i = 0 ; i < 2*nharmonics+1 ; i++) { gsl_vector_set(beta_gsl, i, beta[i]); for (j = 0 ; j < 2*nharmonics+1 ; j++) gsl_matrix_set(alpha_gsl, i, j, alpha[i][j]); } result = gsl_linalg_HH_solve(alpha_gsl, beta_gsl, x_gsl); /* x = alpha^-1 beta */ assert(result == 0); gsl_blas_ddot(x_gsl, beta_gsl, &chisqred); if (harmoniccoeffs) { for (i = 0 ; i < 2*nharmonics+1 ; i++) { harmoniccoeffs[i] = gsl_vector_get(x_gsl, i); } } gsl_matrix_free(alpha_gsl); gsl_vector_free(beta_gsl); gsl_vector_free(x_gsl); return chisqred; }