Boost.uBLAS ã§ä¸è¬ä¿æ°è¡åã®ç·å½¢æ¹ç¨å¼ç³»(System of linear equations)ã®è§£ã®è¨ç® - lapackç
ä»åã¯前回の連立方程式の計算ã lapack ãç¨ãã¦å®è£
ãã¾ãï¼
lapack ã«ã¯ dgesv ã¨ããé¢æ°ãããï¼ãããå
é¨ã§ä¿æ°è¡åãLUå解ãã¦è§£ãè¨ç®ãã¦ããã¾ãï¼ç§ãã¡ãããã¹ããã¨ã¨ããã°ï¼ãã¤ãã®ããã« bindings.lapack.gesv ã«æ¸¡ã column_major ãªè¡åãæºåãããã¨ãããã§ãããï¼ä»¥ä¸ã«ç§ã®å®è£
ä¾ã示ãã¾ãï¼
math.hpp
#ifndef MATH_HPP_20081106 #define MATH_HPP_20081106 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include <boost/numeric/ublas/fwd.hpp> namespace math { void solve(const boost::numeric::ublas::matrix<double>& A, const boost::numeric::ublas::vector<double>& b, boost::numeric::ublas::vector<double>& x); void solve(const boost::numeric::ublas::matrix<double>& A, const boost::numeric::ublas::matrix<double>& B, boost::numeric::ublas::matrix<double>& X); } #endif
math.cpp
#include "math.hpp" #include <boost/numeric/ublas/matrix.hpp> #include <boost/numeric/ublas/matrix_proxy.hpp> #include <boost/numeric/ublas/vector.hpp> #define BOOST_NUMERIC_BINDINGS_USE_CLAPACK #include <boost/numeric/bindings/lapack/gesv.hpp> #include <boost/numeric/bindings/traits/ublas_matrix.hpp> #undef BOOST_NUMERIC_BINDINGS_USE_CLAPACK void math::solve(const boost::numeric::ublas::matrix<double>& A, const boost::numeric::ublas::vector<double>& b, boost::numeric::ublas::vector<double>& x) { BOOST_UBLAS_CHECK(A.size1() == A.size2(), boost::numeric::ublas::external_logic()); BOOST_UBLAS_CHECK(A.size1() == b.size(), boost::numeric::ublas::external_logic()); boost::numeric::ublas::matrix<double> B(b.size(), 1), X; boost::numeric::ublas::column(B, 0).assign(b); solve(A, B, X); x = boost::numeric::ublas::column(X, 0); } void math::solve(const boost::numeric::ublas::matrix<double>& A, const boost::numeric::ublas::matrix<double>& B, boost::numeric::ublas::matrix<double>& X) { namespace ublas = boost::numeric::ublas; BOOST_UBLAS_CHECK(A.size1() == A.size2(), ublas::external_logic()); BOOST_UBLAS_CHECK(A.size1() == B.size1(), ublas::external_logic()); ublas::matrix<double, ublas::column_major> CA(A), CX(B); int info; info = boost::numeric::bindings::lapack::gesv(CA, CX); BOOST_UBLAS_CHECK(info == 0, ublas::internal_logic()); #if BOOST_UBLAS_TYPE_CHECK BOOST_UBLAS_CHECK(ublas::detail::expression_type_check(ublas::prod(A, CX), B), ublas::internal_logic()); #endif X = CX; }
math.cpp ã«å®ä¸è¬ä¿æ°è¡åã®ç·å½¢æ¹ç¨å¼ç³»ã®è§£ãè¨ç®ããé¢æ° solve ãå®è£
ãã¾ããï¼ãããã°æã«ã¯å®éã«è¨ç®ãã X ãç¨ãã¦ï¼AX = B ã«ãªããã¨ã確èªããã³ã¼ãã追å ãã¦ãã¾ãï¼math.cpp ãããã¸ã§ã¯ãã«å ãï¼ä»ã®ã½ã¼ã¹ã³ã¼ãã¨ä¸ç·ã«ã³ã³ãã¤ã«ï¼ï¼math.hpp ã include ãããã¨ã«ãã solve ã使ç¨å¯è½ã«ãªãã¾ãï¼
solve 㯠AX = B ã®è§£è¡å X ããã㯠Ax = b ã®è§£ãã¯ãã« x ãè¨ç®ãã¾ãï¼ãã ãï¼A 㯠N 次æ£æ¹è¡åï¼X 㨠B 㯠N x NRHS è¡åï¼NRHS 㯠1 以ä¸ã®ä»»æã®æ°ï¼ï¼x 㨠b 㯠N 次å
ãã¯ãã«ã表ãã¾ãï¼
NRHS ã 1 ã®ã¨ãï¼X 㨠B 㯠N x 1 ã®è¡åã«ãªãã¾ããï¼ãã㯠N 次å
ãã¯ãã«ã«ä»ãªãã¾ããï¼NRHS ã 1 ã®ã¨ãã¯ï¼AX = B ã¨ããå¼ã¯ãã¯ãã«ãç¨ã㦠Ax = b ã«ãªãã®ã§ãï¼ï¼uBLAS ã§ã¯ãã¯ãã«ã表ãåãã¡ããã¨ç¨æããã¦ããããï¼å¼æ°ã«ãã¯ãã«ãåãé¢æ°(Ax = b ã解ãé¢æ°)ãå®è£
ãã¾ããï¼ã³ã¼ããè¦ãã¨åããã¾ããï¼ãã®é¢æ°ã¯ AX = B ã解ãé¢æ°ãå©ç¨ãã¦ããã ãã§ãï¼
以ä¸ã®ãã¹ãã³ã¼ã㧠solve ã®åä½ã確èªã§ãã¾ãï¼
test.cpp
#include "math.hpp" #include <boost/numeric/ublas/io.hpp> #include <boost/numeric/ublas/matrix.hpp> #include <boost/numeric/ublas/vector.hpp> #ifdef _MSC_VER # pragma comment(lib, "libf2c.lib") # pragma comment(lib, "BLAS.lib") # pragma comment(lib, "clapack.lib") #endif int main() { namespace ublas = boost::numeric::ublas; ublas::matrix<double> A(3, 3); ublas::vector<double> b(3), x; A(0, 0) = 3; A(0, 1) = 2; A(0, 2) = -1; A(1, 0) = 2; A(1, 1) = -2; A(1, 2) = 4; A(2, 0) = -1; A(2, 1) = 0.5; A(2, 2) = -1; b(0) = 1; b(1) = -2; b(2) = 0; math::solve(A, b, x); // 以ä¸çµæã®è¡¨ç¤º // è¨ç®çµæã http://en.wikipedia.org/wiki/System_of_linear_equations ã¨æ¯è¼ãã¦ã¿ã¾ããã std::cout << x << std::endl; return 0; }
- VC9
- g++ (GCC) 3.4.4 (cygming special)
ã§ã®ã³ã³ãã¤ã«ã確èªãã¦ãã¾ãï¼
å®è¡ãã¦ã¿ãã¨ï¼æ£ãã解ãè¨ç®ã§ãã¦ãããã¨ãåããã¾ãï¼
ã¨ã©ã¼ãåºã¦ã³ã³ãã¤ã«ã§ããªãå ´åã¯ï¼前回の記事ãè¦ã¦æ£ããã¤ã³ã¹ãã¼ã«ã§ãã¦ããã確èªãã¦ã¿ã¦ãã ããï¼
次åã¯å¯¾ç§°ä¿æ°è¡åã®ç·å½¢æ¹ç¨å¼ç³»ã®è§£ãè¨ç®ããé¢æ°ãå®è£
ããäºå®ã§ãï¼
ããã§ã¯ï¼