예제 #1
0
/// 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;
}
예제 #2
0
/// 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);
}
예제 #3
0
/// 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);
}
예제 #4
0
/// 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);
  }
}
예제 #5
0
/// 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;
}
예제 #6
0
파일: BSpline.cpp 프로젝트: BigShows/mantid
    /**
     * 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()) );
        }
    }
예제 #7
0
 GSLVector::GSLVector(const GSLVector& v)
 {
   m_vector = gsl_vector_alloc(v.size());
   gsl_vector_memcpy(m_vector, v.gsl());
 }