gesv.hpp

Go to the documentation of this file.
00001 /*
00002  * 
00003  * Copyright (c) Toon Knapen & Kresimir Fresl 2003
00004  *
00005  * Distributed under the Boost Software License, Version 1.0.
00006  * (See accompanying file LICENSE_1_0.txt or copy at
00007  * http://www.boost.org/LICENSE_1_0.txt)
00008  *
00009  * KF acknowledges the support of the Faculty of Civil Engineering, 
00010  * University of Zagreb, Croatia.
00011  *
00012  */
00013 
00014 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GESV_HPP
00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_GESV_HPP
00016 
00017 #include <boost/numeric/bindings/traits/type_traits.hpp>
00018 #include <boost/numeric/bindings/traits/traits.hpp>
00019 #include <boost/numeric/bindings/lapack/lapack.h>
00020 #include <boost/numeric/bindings/traits/detail/array.hpp>
00021 
00022 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00023 #  include <boost/static_assert.hpp>
00024 #  include <boost/type_traits/is_same.hpp>
00025 #endif 
00026 
00027 #include <cassert>
00028 
00029 
00030 namespace boost { namespace numeric { namespace bindings { 
00031 
00032   namespace lapack {
00033 
00035     //
00036     // general system of linear equations A * X = B
00037     // 
00039 
00040     /* 
00041      * gesv() computes the solution to a system of linear equations 
00042      * A * X = B, where A is an N-by-N matrix and X and B are N-by-NRHS 
00043      * matrices.
00044      *
00045      * The LU decomposition with partial pivoting and row interchanges 
00046      * is used to factor A as A = P * L * U, where P is a permutation 
00047      * matrix, L is unit lower triangular, and U is upper triangular.   
00048      * The factored form of A is then used to solve the system of 
00049      * equations A * X = B.
00050      */ 
00051 
00052     namespace detail {
00053 
00054       inline 
00055       void gesv (int const n, int const nrhs,
00056                  float* a, int const lda, int* ipiv, 
00057                  float* b, int const ldb, int* info) 
00058       {
00059         LAPACK_SGESV (&n, &nrhs, a, &lda, ipiv, b, &ldb, info);
00060       }
00061 
00062       inline 
00063       void gesv (int const n, int const nrhs,
00064                  double* a, int const lda, int* ipiv, 
00065                  double* b, int const ldb, int* info) 
00066       {
00067         LAPACK_DGESV (&n, &nrhs, a, &lda, ipiv, b, &ldb, info);
00068       }
00069 
00070       inline 
00071       void gesv (int const n, int const nrhs,
00072                  traits::complex_f* a, int const lda, int* ipiv, 
00073                  traits::complex_f* b, int const ldb, int* info) 
00074       {
00075         LAPACK_CGESV (&n, &nrhs, 
00076                       traits::complex_ptr (a), &lda, ipiv, 
00077                       traits::complex_ptr (b), &ldb, info);
00078       }
00079       
00080       inline 
00081       void gesv (int const n, int const nrhs,
00082                  traits::complex_d* a, int const lda, int* ipiv, 
00083                  traits::complex_d* b, int const ldb, int* info) 
00084       {
00085         LAPACK_ZGESV (&n, &nrhs, 
00086                       traits::complex_ptr (a), &lda, ipiv, 
00087                       traits::complex_ptr (b), &ldb, info);
00088       }
00089 
00090     } 
00091 
00092     template <typename MatrA, typename MatrB, typename IVec>
00093     inline
00094     int gesv (MatrA& a, IVec& ipiv, MatrB& b) {
00095 
00096 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00097       BOOST_STATIC_ASSERT((boost::is_same<
00098         typename traits::matrix_traits<MatrA>::matrix_structure, 
00099         traits::general_t
00100       >::value)); 
00101       BOOST_STATIC_ASSERT((boost::is_same<
00102         typename traits::matrix_traits<MatrB>::matrix_structure, 
00103         traits::general_t
00104       >::value)); 
00105 #endif 
00106 
00107       int const n = traits::matrix_size1 (a);
00108       assert (n == traits::matrix_size2 (a)); 
00109       assert (n == traits::matrix_size1 (b)); 
00110       assert (n == traits::vector_size (ipiv)); 
00111 
00112       int info; 
00113       detail::gesv (n, traits::matrix_size2 (b), 
00114                     traits::matrix_storage (a), 
00115                     traits::leading_dimension (a),
00116                     traits::vector_storage (ipiv),  
00117                     traits::matrix_storage (b),
00118                     traits::leading_dimension (b),
00119                     &info);
00120       return info; 
00121     }
00122 
00123     template <typename MatrA, typename MatrB>
00124     inline
00125     int gesv (MatrA& a, MatrB& b) {
00126       // with 'internal' pivot vector 
00127       
00128       // gesv() errors: 
00129       //   if (info == 0), successful
00130       //   if (info < 0), the -info argument had an illegal value
00131       //   -- we will use -101 if allocation fails
00132       //   if (info > 0), U(i-1,i-1) is exactly zero 
00133       int info = -101; 
00134       traits::detail::array<int> ipiv (traits::matrix_size1 (a)); 
00135       if (ipiv.valid()) 
00136         info = gesv (a, ipiv, b); 
00137       return info; 
00138     }
00139 
00140 
00141     /* 
00142      * getrf() computes an LU factorization of a general M-by-N matrix A  
00143      * using partial pivoting with row interchanges. The factorization 
00144      * has the form A = P * L * U, where P is a permutation matrix, 
00145      * L is lower triangular with unit diagonal elements (lower
00146      * trapezoidal if M > N), and U is upper triangular (upper 
00147      * trapezoidal if M < N).
00148      */ 
00149 
00150     namespace detail {
00151 
00152       inline 
00153       void getrf (int const n, int const m,
00154                   float* a, int const lda, int* ipiv, int* info) 
00155       {
00156         LAPACK_SGETRF (&n, &m, a, &lda, ipiv, info);
00157       }
00158 
00159       inline 
00160       void getrf (int const n, int const m,
00161                   double* a, int const lda, int* ipiv, int* info) 
00162       {
00163         LAPACK_DGETRF (&n, &m, a, &lda, ipiv, info);
00164       }
00165 
00166       inline 
00167       void getrf (int const n, int const m,
00168                   traits::complex_f* a, int const 
00169                   lda, int* ipiv, int* info) 
00170       {
00171         LAPACK_CGETRF (&n, &m, traits::complex_ptr (a), &lda, ipiv, info);
00172       }
00173 
00174       inline 
00175       void getrf (int const n, int const m,
00176                   traits::complex_d* a, int const lda, 
00177                   int* ipiv, int* info) 
00178       {
00179         LAPACK_ZGETRF (&n, &m, traits::complex_ptr (a), &lda, ipiv, info);
00180       }
00181 
00182     }
00183 
00184     template <typename MatrA, typename IVec>
00185     inline
00186     int getrf (MatrA& a, IVec& ipiv) {
00187 
00188 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00189       BOOST_STATIC_ASSERT((boost::is_same<
00190         typename traits::matrix_traits<MatrA>::matrix_structure, 
00191         traits::general_t
00192       >::value)); 
00193 #endif 
00194 
00195       int const n = traits::matrix_size1 (a);
00196       int const m = traits::matrix_size2 (a); 
00197       assert (traits::vector_size (ipiv) == (m < n ? m : n));
00198 
00199       int info; 
00200       detail::getrf (n, m, 
00201                      traits::matrix_storage (a), 
00202                      traits::leading_dimension (a),
00203                      traits::vector_storage (ipiv),  
00204                      &info);
00205       return info; 
00206     }
00207 
00208 
00209     /*
00210      * getrs() solves a system of linear equations A * X = B 
00211      * or A^T * X = B with a general N-by-N matrix A using  
00212      * the LU factorization computed by getrf().
00213      */
00214 
00215     namespace detail {
00216 
00217       inline 
00218       void getrs (char const trans, int const n, int const nrhs,
00219                   float const* a, int const lda, int const* ipiv, 
00220                   float* b, int const ldb, int* info) 
00221       {
00222         LAPACK_SGETRS (&trans, &n, &nrhs, a, &lda, ipiv, b, &ldb, info);
00223       }
00224 
00225       inline 
00226       void getrs (char const trans, int const n, int const nrhs,
00227                   double const* a, int const lda, int const* ipiv, 
00228                   double* b, int const ldb, int* info) 
00229       {
00230         LAPACK_DGETRS (&trans, &n, &nrhs, a, &lda, ipiv, b, &ldb, info);
00231       }
00232 
00233       inline 
00234       void getrs (char const trans, int const n, int const nrhs,
00235                   traits::complex_f const* a, int const lda, 
00236                   int const* ipiv, 
00237                   traits::complex_f* b, int const ldb, int* info) 
00238       {
00239         LAPACK_CGETRS (&trans, &n, &nrhs, 
00240                        traits::complex_ptr (a), &lda, ipiv, 
00241                        traits::complex_ptr (b), &ldb, info);
00242       }
00243 
00244       inline 
00245       void getrs (char const trans, int const n, int const nrhs,
00246                   traits::complex_d const* a, int const lda, 
00247                   int const* ipiv, 
00248                   traits::complex_d* b, int const ldb, int* info) 
00249       {
00250         LAPACK_ZGETRS (&trans, &n, &nrhs, 
00251                        traits::complex_ptr (a), &lda, ipiv, 
00252                        traits::complex_ptr (b), &ldb, info);
00253       }
00254 
00255     }
00256 
00257     template <typename MatrA, typename MatrB, typename IVec>
00258     inline
00259     int getrs (char const trans, MatrA const& a, IVec const& ipiv, MatrB& b) 
00260     {
00261       assert (trans == 'N' || trans == 'T' || trans == 'C'); 
00262 
00263 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00264       BOOST_STATIC_ASSERT((boost::is_same<
00265         typename traits::matrix_traits<MatrA>::matrix_structure, 
00266         traits::general_t
00267       >::value)); 
00268       BOOST_STATIC_ASSERT((boost::is_same<
00269         typename traits::matrix_traits<MatrB>::matrix_structure, 
00270         traits::general_t
00271       >::value)); 
00272 #endif 
00273 
00274       int const n = traits::matrix_size1 (a);
00275       assert (n == traits::matrix_size2 (a)); 
00276       assert (n == traits::matrix_size1 (b)); 
00277       assert (n == traits::vector_size (ipiv)); 
00278 
00279       int info; 
00280       detail::getrs (trans, n, traits::matrix_size2 (b), 
00281 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
00282                      traits::matrix_storage (a), 
00283 #else
00284                      traits::matrix_storage_const (a), 
00285 #endif 
00286                      traits::leading_dimension (a),
00287 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
00288                      traits::vector_storage (ipiv),  
00289 #else
00290                      traits::vector_storage_const (ipiv),  
00291 #endif
00292                      traits::matrix_storage (b),
00293                      traits::leading_dimension (b),
00294                      &info);
00295       return info; 
00296     }
00297 
00298     template <typename MatrA, typename MatrB, typename IVec>
00299     inline
00300     int getrs (MatrA const& a, IVec const& ipiv, MatrB& b) {
00301       char const no_transpose = 'N'; 
00302       return getrs (no_transpose, a, ipiv, b); 
00303     }
00304 
00305     // TO DO: getri() 
00306 
00307   }
00308 
00309 }}}
00310 
00311 #endif 

Generated on Wed Nov 23 19:00:16 2011 for FreeCAD by  doxygen 1.6.1