/// Calculate the dot product /// @param v :: The other vector. double GSLVector::dot(const GSLVector &v) const { if (size() != v.size()) { throw std::runtime_error("Vectors have different sizes in dot product."); } double res = 0.0; gsl_blas_ddot(gsl(), v.gsl(), &res); return res; }
/// 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); }
/// 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); }
/// 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); } }
/// Matrix by vector multiplication /// @param v :: A vector to multiply by. Must have the same size as size2(). /// @returns A vector - the result of the multiplication. Size of the returned /// vector equals size1(). /// @throws std::invalid_argument if the input vector has a wrong size. /// @throws std::runtime_error if the underlying GSL routine fails. GSLVector GSLMatrix::operator*(const GSLVector &v) const { if (v.size() != size2()) { throw std::invalid_argument( "Matrix by vector multiplication: wrong size of vector."); } GSLVector res(size1()); auto status = gsl_blas_dgemv(CblasNoTrans, 1.0, gsl(), v.gsl(), 0.0, res.gsl()); if (status != GSL_SUCCESS) { std::string message = "Failed to multiply matrix by a vector.\n" "Error message returned by the GSL:\n" + std::string(gsl_strerror(status)); throw std::runtime_error(message); } return res; }
/** * Recalculate the B-spline knots */ void BSpline::resetKnots() { bool isUniform = getAttribute("Uniform").asBool(); std::vector<double> breakPoints; if ( isUniform ) { // create uniform knots in the interval [StartX, EndX] double startX = getAttribute("StartX").asDouble(); double endX = getAttribute("EndX").asDouble(); gsl_bspline_knots_uniform( startX, endX, m_bsplineWorkspace.get() ); getGSLBreakPoints( breakPoints ); storeAttributeValue( "BreakPoints", Attribute(breakPoints) ); } else { // set the break points from BreakPoints vector attribute, update other attributes breakPoints = getAttribute( "BreakPoints" ).asVector(); // check that points are in ascending order double prev = breakPoints[0]; for(size_t i = 1; i < breakPoints.size(); ++i) { double next = breakPoints[i]; if ( next <= prev ) { throw std::invalid_argument("BreakPoints must be in ascending order."); } prev = next; } int nbreaks = getAttribute( "NBreak" ).asInt(); // if number of break points change do necessary updates if ( static_cast<size_t>(nbreaks) != breakPoints.size() ) { storeAttributeValue("NBreak", Attribute(static_cast<int>(breakPoints.size())) ); resetGSLObjects(); resetParameters(); } GSLVector bp = breakPoints; gsl_bspline_knots( bp.gsl(), m_bsplineWorkspace.get() ); storeAttributeValue( "StartX", Attribute(breakPoints.front()) ); storeAttributeValue( "EndX", Attribute(breakPoints.back()) ); } }
GSLVector::GSLVector(const GSLVector& v) { m_vector = gsl_vector_alloc(v.size()); gsl_vector_memcpy(m_vector, v.gsl()); }