/** * Copy the parameter values to a GSLVector. * @param params :: A vector to copy the parameters to */ void CostFuncLeastSquares::getParameters(GSLVector ¶ms) const { if (params.size() != nParams()) { params.resize(nParams()); } for (size_t i = 0; i < nParams(); ++i) { params.set(i, getParameter(i)); } }
/// Calculate the eigensystem of a symmetric matrix /// @param eigenValues :: Output variable that receives the eigenvalues of this /// matrix. /// @param eigenVectors :: Output variable that receives the eigenvectors of /// this matrix. void GSLMatrix::eigenSystem(GSLVector &eigenValues, GSLMatrix &eigenVectors) { size_t n = size1(); if (n != size2()) { throw std::runtime_error("Matrix eigenSystem: the matrix must be square."); } eigenValues.resize(n); eigenVectors.resize(n, n); auto workspace = gsl_eigen_symmv_alloc(n); gsl_eigen_symmv(gsl(), eigenValues.gsl(), eigenVectors.gsl(), workspace); gsl_eigen_symmv_free(workspace); }
/** * Improve the solution by using obtained functions as a basis for diagonalization. * * @param hamiltonian :: The Hamiltonian. * @param basis :: The basis functions. * @param n :: The size of the basis to use. * @param eigv :: Output eigenvalues. * @param eigf :: Output eigenvectors (functions). This method creates a new ChebfunVector instance and returns it. */ void Schrodinger1D::improve(ChebOperator *hamiltonian, ChebfunVector *basis, GSLVector &eigv, ChebfunVector **eigf) const { size_t n = basis->size(); GSLMatrix H(n,n); for(size_t i = 0; i < n; ++i) { const chebfun &f1 = basis->cfun(i).cfun(0).getUnscaled(); chebfun d1(f1); hamiltonian->apply(f1, d1); chebfun dd = d1; dd *= f1; double me = dd.integr(); H.set( i, i, me ); //std::cerr << "e=" << me << std::endl; for(size_t j = i+1; j < n; ++j) { const chebfun &f2 = basis->cfun(j).cfun(0).getUnscaled(); chebfun d2(f2); hamiltonian->apply(f2, d2); d2 *= f1; double me = d2.integr(); //std::cerr << "o=" << me << std::endl; H.set( i, j, me ); H.set( j, i, me ); } } //std::cerr << H << std::endl; GSLVector en; GSLMatrix v; H.diag(en,v); std::vector<size_t> indx; getSortedIndex( en, indx ); if ( indx.empty() ) { throw std::runtime_error("Schrodinger1D failed to find solution."); } eigv.resize( indx.size() ); *eigf = new ChebfunVector; ChebfunVector &funs = **eigf; funs.fromLinearCombinations( *basis, v ); funs.sort( indx ); for(size_t i = 0; i < indx.size(); ++i) { std::cerr << i << ' ' << en[indx[i]] << std::endl; eigv.set( i, en[indx[i]] ); } }
/// Solve system of linear equations M*x == rhs, M is this matrix /// This matrix is destroyed. /// @param rhs :: The right-hand-side vector /// @param x :: The solution vector void GSLMatrix::solve(const GSLVector &rhs, GSLVector &x) { if (size1() != size2()) { throw std::runtime_error( "System of linear equations: the matrix must be square."); } size_t n = size1(); if (rhs.size() != n) { throw std::runtime_error( "System of linear equations: right-hand side vector has wrong size."); } x.resize(n); int s; gsl_permutation *p = gsl_permutation_alloc(n); gsl_linalg_LU_decomp(gsl(), p, &s); // matrix is modified at this moment gsl_linalg_LU_solve(gsl(), p, rhs.gsl(), x.gsl()); gsl_permutation_free(p); }
/// Solve system of linear equations M*x == rhs, M is this matrix /// This matrix is destroyed. /// @param rhs :: The right-hand-side vector /// @param x :: The solution vector /// @throws std::invalid_argument if the input vectors have wrong sizes. /// @throws std::runtime_error if the GSL fails to solve the equations. void GSLMatrix::solve(const GSLVector &rhs, GSLVector &x) { if (size1() != size2()) { throw std::invalid_argument( "System of linear equations: the matrix must be square."); } size_t n = size1(); if (rhs.size() != n) { throw std::invalid_argument( "System of linear equations: right-hand side vector has wrong size."); } x.resize(n); int s; gsl_permutation *p = gsl_permutation_alloc(n); gsl_linalg_LU_decomp(gsl(), p, &s); // matrix is modified at this moment int res = gsl_linalg_LU_solve(gsl(), p, rhs.gsl(), x.gsl()); gsl_permutation_free(p); if (res != GSL_SUCCESS) { std::string message = "Failed to solve system of linear equations.\n" "Error message returned by the GSL:\n" + std::string(gsl_strerror(res)); throw std::runtime_error(message); } }