hesv.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_HESV_HPP
00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_HESV_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/lapack/ilaenv.hpp>
00021 #include <boost/numeric/bindings/traits/detail/array.hpp>
00022 
00023 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00024 #  include <boost/static_assert.hpp>
00025 #  include <boost/type_traits/is_same.hpp>
00026 #endif 
00027 
00028 #include <cassert>
00029 
00030 
00031 namespace boost { namespace numeric { namespace bindings { 
00032 
00033   namespace lapack {
00034 
00036     //
00037     // system of linear equations A * X = B
00038     // with A Hermitian indefinite matrix
00039     //
00041 
00042     namespace detail {
00043 
00044       inline 
00045       int hetrf_block (traits::complex_f, 
00046                        int const ispec, char const ul, int const n) 
00047       {
00048         char ul2[2] = "x"; ul2[0] = ul; 
00049         return ilaenv (ispec, "CHETRF", ul2, n); 
00050       }
00051       inline 
00052       int hetrf_block (traits::complex_d, 
00053                        int const ispec, char const ul, int const n) 
00054       {
00055         char ul2[2] = "x"; ul2[0] = ul; 
00056         return ilaenv (ispec, "ZHETRF", ul2, n); 
00057       }
00058 
00059     }
00060 
00061 
00062     template <typename HermA>
00063     inline
00064     int hetrf_block (char const q, char const ul, HermA const& a) {
00065 
00066 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00067       BOOST_STATIC_ASSERT((boost::is_same<
00068         typename traits::matrix_traits<HermA>::matrix_structure, 
00069         traits::general_t
00070       >::value));
00071 #endif
00072       assert (q == 'O' || q == 'M'); 
00073       assert (ul == 'U' || ul == 'L'); 
00074 
00075       int n = traits::matrix_size1 (a); 
00076       assert (n == traits::matrix_size2 (a)); 
00077 
00078 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00079       typedef typename traits::matrix_traits<HermA>::value_type val_t; 
00080 #else 
00081       typedef typename HermA::value_type val_t; 
00082 #endif 
00083       int ispec = (q == 'O' ? 1 : 2); 
00084       return detail::hetrf_block (val_t(), ispec, ul, n); 
00085     }
00086 
00087     template <typename HermA>
00088     inline
00089     int hetrf_block (char const q, HermA const& a) {
00090 
00091 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00092       BOOST_STATIC_ASSERT((boost::is_same<
00093         typename traits::matrix_traits<HermA>::matrix_structure, 
00094         traits::hermitian_t
00095       >::value));
00096 #endif
00097       assert (q == 'O' || q == 'M'); 
00098 
00099       char ul = traits::matrix_uplo_tag (a);
00100       int n = traits::matrix_size1 (a); 
00101       assert (n == traits::matrix_size2 (a)); 
00102 
00103 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00104       typedef typename traits::matrix_traits<HermA>::value_type val_t; 
00105 #else 
00106       typedef typename HermA::value_type val_t; 
00107 #endif 
00108       int ispec = (q == 'O' ? 1 : 2); 
00109       return detail::hetrf_block (val_t(), ispec, ul, n); 
00110     }
00111 
00112     template <typename HermA>
00113     inline
00114     int hetrf_work (char const q, char const ul, HermA const& a) {
00115 
00116 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00117       BOOST_STATIC_ASSERT((boost::is_same<
00118         typename traits::matrix_traits<HermA>::matrix_structure, 
00119         traits::general_t
00120       >::value));
00121 #endif
00122       assert (q == 'O' || q == 'M'); 
00123       assert (ul == 'U' || ul == 'L'); 
00124 
00125       int n = traits::matrix_size1 (a); 
00126       assert (n == traits::matrix_size2 (a)); 
00127 
00128 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00129       typedef typename traits::matrix_traits<HermA>::value_type val_t; 
00130 #else 
00131       typedef typename HermA::value_type val_t; 
00132 #endif 
00133       int lw = -13; 
00134       if (q == 'M') 
00135         lw = 1;
00136       if (q == 'O') 
00137         lw = n * detail::hetrf_block (val_t(), 1, ul, n); 
00138       return lw; 
00139     }
00140 
00141     template <typename HermA>
00142     inline
00143     int hetrf_work (char const q, HermA const& a) {
00144 
00145 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00146       BOOST_STATIC_ASSERT((boost::is_same<
00147         typename traits::matrix_traits<HermA>::matrix_structure, 
00148         traits::hermitian_t
00149       >::value));
00150 #endif
00151       assert (q == 'O' || q == 'M'); 
00152 
00153       char ul = traits::matrix_uplo_tag (a);
00154       int n = traits::matrix_size1 (a); 
00155       assert (n == traits::matrix_size2 (a)); 
00156 
00157 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00158       typedef typename traits::matrix_traits<HermA>::value_type val_t; 
00159 #else 
00160       typedef typename HermA::value_type val_t; 
00161 #endif 
00162       int lw = -13; 
00163       if (q == 'M') 
00164         lw = 1;
00165       if (q == 'O') 
00166         lw = n * detail::hetrf_block (val_t(), 1, ul, n); 
00167       return lw; 
00168     }
00169 
00170 
00171     template <typename HermA>
00172     inline
00173     int hesv_work (char const q, char const ul, HermA const& a) {
00174       return hetrf_work (q, ul, a); 
00175     }
00176 
00177     template <typename HermA>
00178     inline
00179     int hesv_work (char const q, HermA const& a) { return hetrf_work (q, a); }
00180 
00181 
00182     /*
00183      * hesv() computes the solution to a system of linear equations 
00184      * A * X = B, where A is an N-by-N Hermitian matrix and X and B 
00185      * are N-by-NRHS matrices.
00186      *
00187      * The diagonal pivoting method is used to factor A as
00188      *   A = U * D * U^H,  if UPLO = 'U', 
00189      *   A = L * D * L^H,  if UPLO = 'L',
00190      * where  U (or L) is a product of permutation and unit upper 
00191      * (lower) triangular matrices, and D is Hermitian and block 
00192      * diagonal with 1-by-1 and 2-by-2 diagonal blocks. The factored 
00193      * form of A is then used to solve the system of equations A * X = B.
00194      */
00195 
00196     namespace detail {
00197 
00198       inline 
00199       void hesv (char const uplo, int const n, int const nrhs,
00200                  traits::complex_f* a, int const lda, int* ipiv,  
00201                  traits::complex_f* b, int const ldb, 
00202                  traits::complex_f* w, int const lw, int* info) 
00203       {
00204         LAPACK_CHESV (&uplo, &n, &nrhs, 
00205                       traits::complex_ptr (a), &lda, ipiv, 
00206                       traits::complex_ptr (b), &ldb, 
00207                       traits::complex_ptr (w), &lw, info);
00208       }
00209 
00210       inline 
00211       void hesv (char const uplo, int const n, int const nrhs,
00212                  traits::complex_d* a, int const lda, int* ipiv, 
00213                  traits::complex_d* b, int const ldb, 
00214                  traits::complex_d* w, int const lw, int* info) 
00215       {
00216         LAPACK_ZHESV (&uplo, &n, &nrhs, 
00217                       traits::complex_ptr (a), &lda, ipiv, 
00218                       traits::complex_ptr (b), &ldb, 
00219                       traits::complex_ptr (w), &lw, info);
00220       }
00221 
00222       template <typename HermA, typename MatrB, typename IVec, typename Work>
00223       inline
00224       int hesv (char const ul, HermA& a, IVec& i, MatrB& b, Work& w) {
00225 
00226         int const n = traits::matrix_size1 (a);
00227         assert (n == traits::matrix_size2 (a)); 
00228         assert (n == traits::matrix_size1 (b)); 
00229         assert (n == traits::vector_size (i)); 
00230 
00231         int info; 
00232         hesv (ul, n, traits::matrix_size2 (b), 
00233               traits::matrix_storage (a), 
00234               traits::leading_dimension (a),
00235               traits::vector_storage (i),  
00236               traits::matrix_storage (b),
00237               traits::leading_dimension (b),
00238               traits::vector_storage (w), 
00239               traits::vector_size (w), 
00240               &info);
00241         return info; 
00242       }
00243 
00244     }
00245 
00246     template <typename HermA, typename MatrB, typename IVec, typename Work>
00247     inline
00248     int hesv (char const ul, HermA& a, IVec& i, MatrB& b, Work& w) {
00249 
00250       assert (ul == 'U' || ul == 'L'); 
00251 
00252 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00253       BOOST_STATIC_ASSERT((boost::is_same<
00254         typename traits::matrix_traits<HermA>::matrix_structure, 
00255         traits::general_t
00256       >::value));
00257       BOOST_STATIC_ASSERT((boost::is_same<
00258         typename traits::matrix_traits<MatrB>::matrix_structure, 
00259         traits::general_t
00260       >::value));
00261 #endif
00262 
00263       int const lw = traits::vector_size (w); 
00264       assert (lw >= 1); 
00265       return detail::hesv (ul, a, i, b, w); 
00266     }
00267 
00268     template <typename HermA, typename MatrB, typename IVec, typename Work>
00269     inline
00270     int hesv (HermA& a, IVec& i, MatrB& b, Work& w) {
00271 
00272 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00273       BOOST_STATIC_ASSERT((boost::is_same<
00274         typename traits::matrix_traits<HermA>::matrix_structure, 
00275         traits::hermitian_t
00276       >::value));
00277       BOOST_STATIC_ASSERT((boost::is_same<
00278         typename traits::matrix_traits<MatrB>::matrix_structure, 
00279         traits::general_t
00280       >::value));
00281 #endif
00282 
00283       int const lw = traits::vector_size (w); 
00284       assert (lw >= 1); 
00285       char uplo = traits::matrix_uplo_tag (a);
00286       return detail::hesv (uplo, a, i, b, w); 
00287     }
00288 
00289     template <typename HermA, typename MatrB>
00290     inline
00291     int hesv (char const ul, HermA& a, MatrB& b) {
00292       // with 'internal' pivot and work vectors 
00293 
00294       assert (ul == 'U' || ul == 'L'); 
00295 
00296 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00297       BOOST_STATIC_ASSERT((boost::is_same<
00298         typename traits::matrix_traits<HermA>::matrix_structure, 
00299         traits::general_t
00300       >::value));
00301       BOOST_STATIC_ASSERT((boost::is_same<
00302         typename traits::matrix_traits<MatrB>::matrix_structure, 
00303         traits::general_t
00304       >::value));
00305 #endif
00306 
00307       int const n = traits::matrix_size1 (a); 
00308       int info = -101; 
00309       traits::detail::array<int> i (n); 
00310 
00311       if (i.valid()) {
00312         info = -102; 
00313         int lw = hetrf_work ('O', ul, a); 
00314         assert (lw >= 1); // paranoia ? 
00315 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00316         typedef typename traits::matrix_traits<HermA>::value_type val_t; 
00317 #else 
00318         typedef typename HermA::value_type val_t; 
00319 #endif 
00320         traits::detail::array<val_t> w (lw); 
00321         if (w.valid()) 
00322           info = detail::hesv (ul, a, i, b, w); 
00323       }
00324       return info; 
00325     }
00326 
00327     template <typename HermA, typename MatrB>
00328     inline
00329     int hesv (HermA& a, MatrB& b) {
00330       // with 'internal' pivot and work vectors 
00331 
00332 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00333       BOOST_STATIC_ASSERT((boost::is_same<
00334         typename traits::matrix_traits<HermA>::matrix_structure, 
00335         traits::hermitian_t
00336       >::value));
00337       BOOST_STATIC_ASSERT((boost::is_same<
00338         typename traits::matrix_traits<MatrB>::matrix_structure, 
00339         traits::general_t
00340       >::value));
00341 #endif
00342 
00343       int const n = traits::matrix_size1 (a); 
00344       char uplo = traits::matrix_uplo_tag (a);
00345       int info = -101; 
00346       traits::detail::array<int> i (n); 
00347 
00348       if (i.valid()) {
00349         info = -102; 
00350         int lw = hetrf_work ('O', a); 
00351         assert (lw >= 1); // paranoia ? 
00352 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00353         typedef typename traits::matrix_traits<HermA>::value_type val_t; 
00354 #else 
00355         typedef typename HermA::value_type val_t; 
00356 #endif 
00357         traits::detail::array<val_t> w (lw); 
00358         w.resize (lw); 
00359         if (w.valid()) 
00360           info = detail::hesv (uplo, a, i, b, w); 
00361       }
00362       return info; 
00363     }
00364 
00365 
00366     /*
00367      * hetrf() computes the factorization of a Hermitian matrix A using
00368      * the  Bunch-Kaufman diagonal pivoting method. The form of the 
00369      * factorization is
00370      *    A = U * D * U^H  or  A = L * D * L^H
00371      * where U (or L) is a product of permutation and unit upper (lower)  
00372      * triangular matrices, and D is Hermitian and block diagonal with 
00373      * 1-by-1 and 2-by-2 diagonal blocks.
00374      */
00375 
00376     namespace detail {
00377 
00378       inline 
00379       void hetrf (char const uplo, int const n, 
00380                   traits::complex_f* a, int const lda, int* ipiv,  
00381                   traits::complex_f* w, int const lw, int* info) 
00382       {
00383         LAPACK_CHETRF (&uplo, &n, 
00384                        traits::complex_ptr (a), &lda, ipiv, 
00385                        traits::complex_ptr (w), &lw, info);
00386       }
00387 
00388       inline 
00389       void hetrf (char const uplo, int const n, 
00390                   traits::complex_d* a, int const lda, int* ipiv, 
00391                   traits::complex_d* w, int const lw, int* info) 
00392       {
00393         LAPACK_ZHETRF (&uplo, &n, 
00394                        traits::complex_ptr (a), &lda, ipiv, 
00395                        traits::complex_ptr (w), &lw, info);
00396       }
00397 
00398       template <typename HermA, typename IVec, typename Work>
00399       inline
00400       int hetrf (char const ul, HermA& a, IVec& i, Work& w) {
00401 
00402         int const n = traits::matrix_size1 (a);
00403         assert (n == traits::matrix_size2 (a)); 
00404         assert (n == traits::vector_size (i)); 
00405 
00406         int info; 
00407         hetrf (ul, n, traits::matrix_storage (a), 
00408                traits::leading_dimension (a),
00409                traits::vector_storage (i),  
00410                traits::vector_storage (w), 
00411                traits::vector_size (w), 
00412                &info);
00413         return info; 
00414       }
00415 
00416     }
00417 
00418     template <typename HermA, typename IVec, typename Work>
00419     inline
00420     int hetrf (char const ul, HermA& a, IVec& i, Work& w) {
00421 
00422       assert (ul == 'U' || ul == 'L'); 
00423 
00424 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00425       BOOST_STATIC_ASSERT((boost::is_same<
00426         typename traits::matrix_traits<HermA>::matrix_structure, 
00427         traits::general_t
00428       >::value));
00429 #endif
00430 
00431       int const lw = traits::vector_size (w); 
00432       assert (lw >= 1); 
00433       return detail::hetrf (ul, a, i, w); 
00434     }
00435 
00436     template <typename HermA, typename IVec, typename Work>
00437     inline
00438     int hetrf (HermA& a, IVec& i, Work& w) {
00439 
00440 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00441       BOOST_STATIC_ASSERT((boost::is_same<
00442         typename traits::matrix_traits<HermA>::matrix_structure, 
00443         traits::hermitian_t
00444       >::value));
00445 #endif
00446 
00447       int const lw = traits::vector_size (w); 
00448       assert (lw >= 1); 
00449       char uplo = traits::matrix_uplo_tag (a);
00450       return detail::hetrf (uplo, a, i, w); 
00451     }
00452 
00453     template <typename HermA, typename Ivec>
00454     inline
00455     int hetrf (char const ul, HermA& a, Ivec& i) {
00456       // with 'internal' work vector
00457 
00458       assert (ul == 'U' || ul == 'L'); 
00459 
00460 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00461       BOOST_STATIC_ASSERT((boost::is_same<
00462         typename traits::matrix_traits<HermA>::matrix_structure, 
00463         traits::general_t
00464       >::value));
00465 #endif
00466 
00467       int info = -101; 
00468       int lw = hetrf_work ('O', ul, a); 
00469       assert (lw >= 1); // paranoia ? 
00470 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00471       typedef typename traits::matrix_traits<HermA>::value_type val_t; 
00472 #else 
00473       typedef typename HermA::value_type val_t; 
00474 #endif 
00475       traits::detail::array<val_t> w (lw); 
00476       if (w.valid()) 
00477         info = detail::hetrf (ul, a, i, w); 
00478       return info; 
00479     }
00480 
00481     template <typename HermA, typename Ivec>
00482     inline
00483     int hetrf (HermA& a, Ivec& i) {
00484       // with 'internal' work vector 
00485 
00486 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00487       BOOST_STATIC_ASSERT((boost::is_same<
00488         typename traits::matrix_traits<HermA>::matrix_structure, 
00489         traits::hermitian_t
00490       >::value));
00491 #endif
00492 
00493       char uplo = traits::matrix_uplo_tag (a);
00494       int info = -101; 
00495       int lw = hetrf_work ('O', a); 
00496       assert (lw >= 1); // paranoia ? 
00497 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00498       typedef typename traits::matrix_traits<HermA>::value_type val_t; 
00499 #else 
00500       typedef typename HermA::value_type val_t; 
00501 #endif 
00502       traits::detail::array<val_t> w (lw); 
00503       if (w.valid()) 
00504         info = detail::hetrf (uplo, a, i, w); 
00505       return info; 
00506     }
00507 
00508 
00509     /*
00510      * hetrs() solves a system of linear equations A*X = B with 
00511      * a Hermitian matrix A using the factorization 
00512      *    A = U * D * U^H   or  A = L * D * L^H
00513      * computed by hetrf().
00514      */
00515 
00516     namespace detail {
00517 
00518       inline 
00519       void hetrs (char const uplo, int const n, int const nrhs,
00520                   traits::complex_f const* a, int const lda, 
00521                   int const* ipiv,  
00522                   traits::complex_f* b, int const ldb, int* info) 
00523       {
00524         LAPACK_CHETRS (&uplo, &n, &nrhs, 
00525                        traits::complex_ptr (a), &lda, ipiv, 
00526                        traits::complex_ptr (b), &ldb, info);
00527       }
00528 
00529       inline 
00530       void hetrs (char const uplo, int const n, int const nrhs,
00531                   traits::complex_d const* a, int const lda, 
00532                   int const* ipiv, 
00533                   traits::complex_d* b, int const ldb, int* info) 
00534       {
00535         LAPACK_ZHETRS (&uplo, &n, &nrhs, 
00536                        traits::complex_ptr (a), &lda, ipiv, 
00537                        traits::complex_ptr (b), &ldb, info);
00538       }
00539 
00540       template <typename HermA, typename MatrB, typename IVec>
00541       inline
00542       int hetrs (char const ul, HermA const& a, IVec const& i, MatrB& b) {
00543 
00544         int const n = traits::matrix_size1 (a);
00545         assert (n == traits::matrix_size2 (a)); 
00546         assert (n == traits::matrix_size1 (b)); 
00547         assert (n == traits::vector_size (i)); 
00548 
00549         int info; 
00550         hetrs (ul, n, traits::matrix_size2 (b), 
00551 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
00552                traits::matrix_storage (a), 
00553 #else
00554                traits::matrix_storage_const (a), 
00555 #endif 
00556                traits::leading_dimension (a),
00557 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
00558                traits::vector_storage (i),  
00559 #else
00560                traits::vector_storage_const (i),  
00561 #endif
00562                traits::matrix_storage (b),
00563                traits::leading_dimension (b), &info);
00564         return info; 
00565       }
00566 
00567     }
00568 
00569     template <typename HermA, typename MatrB, typename IVec>
00570     inline
00571     int hetrs (char const ul, HermA const& a, IVec const& i, MatrB& b) {
00572 
00573       assert (ul == 'U' || ul == 'L'); 
00574 
00575 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00576       BOOST_STATIC_ASSERT((boost::is_same<
00577         typename traits::matrix_traits<HermA>::matrix_structure, 
00578         traits::general_t
00579       >::value));
00580       BOOST_STATIC_ASSERT((boost::is_same<
00581         typename traits::matrix_traits<MatrB>::matrix_structure, 
00582         traits::general_t
00583       >::value));
00584 #endif
00585 
00586       return detail::hetrs (ul, a, i, b); 
00587     }
00588 
00589     template <typename HermA, typename MatrB, typename IVec>
00590     inline
00591     int hetrs (HermA const& a, IVec const& i, MatrB& b) {
00592 
00593 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
00594       BOOST_STATIC_ASSERT((boost::is_same<
00595         typename traits::matrix_traits<HermA>::matrix_structure, 
00596         traits::hermitian_t
00597       >::value));
00598       BOOST_STATIC_ASSERT((boost::is_same<
00599         typename traits::matrix_traits<MatrB>::matrix_structure, 
00600         traits::general_t
00601       >::value));
00602 #endif
00603 
00604       char uplo = traits::matrix_uplo_tag (a);
00605       return detail::hetrs (uplo, a, i, b); 
00606     }
00607 
00608 
00609     // TO DO: hetri
00610 
00611   }
00612 
00613 }}}
00614 
00615 #endif 

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