/// Subtract a vector /// @param v :: The other vector GSLVector &GSLVector::operator-=(const GSLVector &v) { if (size() != v.size()) { throw std::runtime_error("GSLVectors have different sizes."); } gsl_vector_sub(gsl(), v.gsl()); return *this; }
/// Copy a column into a GSLVector /// @param i :: A column index. GSLVector GSLMatrix::copyColumn(size_t i) const { if (i >= size2()) { throw std::out_of_range("GSLMatrix column index is out of range."); } auto columnView = gsl_matrix_const_column(gsl(), i); return GSLVector(&columnView.vector); }
/// Assign this matrix to a product of three other matrices /// @param mult3 :: Matrix multiplication helper object. GSLMatrix& GSLMatrix::operator=(const GSLMatrixMult3& mult3) { // sizes of the result matrix size_t n1 = mult3.tr1 ? mult3.m_1.size2() : mult3.m_1.size1(); size_t n2 = mult3.tr3 ? mult3.m_3.size1() : mult3.m_3.size2(); this->resize(n1,n2); // intermediate matrix GSLMatrix AB( n1, mult3.m_2.size2() ); CBLAS_TRANSPOSE tr1 = mult3.tr1? CblasTrans : CblasNoTrans; CBLAS_TRANSPOSE tr2 = mult3.tr2? CblasTrans : CblasNoTrans; CBLAS_TRANSPOSE tr3 = mult3.tr3? CblasTrans : CblasNoTrans; // AB = m_1 * m_2 gsl_blas_dgemm (tr1, tr2, 1.0, mult3.m_1.gsl(), mult3.m_2.gsl(), 0.0, AB.gsl()); // this = AB * m_3 gsl_blas_dgemm (CblasNoTrans, tr3, 1.0, AB.gsl(), mult3.m_3.gsl(), 0.0, gsl()); return *this; }
/// Add a vector /// @param v :: The other vector ComplexVector &ComplexVector::operator+=(const ComplexVector &v) { if (size() != v.size()) { throw std::runtime_error("ComplexVectors have different sizes."); } gsl_vector_complex_add(gsl(), v.gsl()); return *this; }
/// Copy a row into a GSLVector /// @param i :: A row index. GSLVector GSLMatrix::copyRow(size_t i) const { if (i >= size1()) { throw std::out_of_range("GSLMatrix row index is out of range."); } auto rowView = gsl_matrix_const_row(gsl(), i); return GSLVector(&rowView.vector); }
/// 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); } }
/// Assign this matrix to a product of two other matrices /// @param mult2 :: Matrix multiplication helper object. GSLMatrix &GSLMatrix::operator=(const GSLMatrixMult2 &mult2) { // sizes of the result matrix size_t n1 = mult2.tr1 ? mult2.m_1.size2() : mult2.m_1.size1(); size_t n2 = mult2.tr2 ? mult2.m_2.size1() : mult2.m_2.size2(); this->resize(n1, n2); CBLAS_TRANSPOSE tr1 = mult2.tr1 ? CblasTrans : CblasNoTrans; CBLAS_TRANSPOSE tr2 = mult2.tr2 ? CblasTrans : CblasNoTrans; // this = m_1 * m_2 gsl_blas_dgemm(tr1, tr2, 1.0, mult2.m_1.gsl(), mult2.m_2.gsl(), 0.0, gsl()); return *this; }
/// 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; }
int SM_problem::solve_with_GSLists(int linearization){ GSLists gsl(NUM_INDIVIDUALS,men,women,linearization); int nprops=gsl.solve_GS(this->men_matches); print_arr(men_matches,NUM_INDIVIDUALS); return nprops; }
/// Multiply by a number /// @param d :: The number GSLVector &GSLVector::operator*=(const double d) { gsl_vector_scale(gsl(), d); return *this; }
/// Multiply by a number /// @param d :: The number ComplexVector &ComplexVector::operator*=(const ComplexType d) { gsl_vector_complex_scale(gsl(), gsl_complex{{d.real(), d.imag()}}); return *this; }