hbevx.hpp

Go to the documentation of this file.
00001 /*
00002  * 
00003  * Copyright Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
00004  * Copyright Thomas Klimpel 2008
00005  *
00006  * Distributed under the Boost Software License, Version 1.0.
00007  * (See accompanying file LICENSE_1_0.txt or copy at
00008  * http://www.boost.org/LICENSE_1_0.txt)
00009  *
00010  * KF acknowledges the support of the Faculty of Civil Engineering, 
00011  * University of Zagreb, Croatia.
00012  *
00013  */
00014 
00015 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HBEVX_HPP
00016 #define BOOST_NUMERIC_BINDINGS_LAPACK_HBEVX_HPP
00017 
00018 #include <boost/numeric/bindings/traits/type.hpp>
00019 #include <boost/numeric/bindings/traits/traits.hpp>
00020 #include <boost/numeric/bindings/traits/type_traits.hpp>
00021 #include <boost/numeric/bindings/lapack/lapack.h>
00022 #include <boost/numeric/bindings/lapack/workspace.hpp>
00023 #include <boost/numeric/bindings/traits/detail/array.hpp>
00024 #include <boost/numeric/bindings/traits/detail/utils.hpp>
00025 
00026 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00027 #  include <boost/static_assert.hpp>
00028 #  include <boost/type_traits.hpp>
00029 #endif 
00030 
00031 
00032 namespace boost { namespace numeric { namespace bindings { 
00033 
00034   namespace lapack {
00035 
00037     //
00038     // Eigendecomposition of a banded Hermitian matrix.
00039     // 
00041 
00042     /* 
00043      * hbevx() computes the eigenvalues and optionally the associated
00044      * eigenvectors of a banded Hermitian matrix A. A matrix is Hermitian
00045      * when herm( A ) == A. When A is real, a Hermitian matrix is also
00046      * called symmetric.
00047      *
00048      * The eigen decomposition is A = U S * herm(U)  where  U  is a
00049      * unitary matrix and S is a diagonal matrix. The eigenvalues of A
00050      * are on the main diagonal of S. The eigenvalues are real.
00051      */
00052 
00053     /*
00054      * If uplo=='L' only the lower triangular part is stored.
00055      * If uplo=='U' only the upper triangular part is stored.
00056      *
00057      * The matrix is assumed to be stored in LAPACK band format, i.e.
00058      * matrices are stored columnwise, in a compressed format so that when e.g. uplo=='U'
00059      * the (i,j) element with j>=i is in position  (i-j) + j * (KD+1) + KD  where KD is the
00060      * half bandwidth of the matrix. For a triadiagonal matrix, KD=1, for a diagonal matrix
00061      * KD=0.
00062      * When uplo=='L', the (i,j) element with j>=i is in position  (i-j) + j * (KD+1).
00063      *
00064      * The matrix A is thus a rectangular matrix with KD+1 rows and N columns.
00065      */ 
00066 
00067     namespace detail {
00068       inline 
00069       void hbevx (
00070         char const jobz, char const range, char const uplo, int const n, int const kd,
00071         float* ab, int const ldab, float* q, int const ldq,
00072         float const vl, float const vu, int const il, int const iu,
00073         float const abstol, int& m,
00074         float* w, float* z, int const ldz,
00075         float* work, int* iwork, int* ifail, int& info) 
00076       {
00077         LAPACK_SSBEVX (
00078           &jobz, &range, &uplo, &n, &kd, ab, &ldab, q, &ldq,
00079           &vl, &vu, &il, &iu, &abstol, &m,
00080           w, z, &ldz,
00081           work, iwork, ifail, &info);
00082       }
00083 
00084       inline 
00085       void hbevx (
00086         char const jobz, char const range, char const uplo, int const n, int const kd,
00087         double* ab, int const ldab, double* q, int const ldq,
00088         double const vl, double const vu, int const il, int const iu,
00089         double const abstol, int& m,
00090         double* w, double* z, int const ldz,
00091         double* work, int* iwork, int* ifail, int& info) 
00092       {
00093         LAPACK_DSBEVX (
00094           &jobz, &range, &uplo, &n, &kd, ab, &ldab, q, &ldq,
00095           &vl, &vu, &il, &iu, &abstol, &m,
00096           w, z, &ldz,
00097           work, iwork, ifail, &info);
00098       }
00099 
00100       inline 
00101       void hbevx (
00102         char const jobz, char const range, char const uplo, int const n, int const kd,
00103         traits::complex_f* ab, int const ldab, traits::complex_f* q, int const ldq,
00104         float const vl, float const vu, int const il, int const iu,
00105         float const abstol, int& m,
00106         float* w, traits::complex_f* z, int const ldz,
00107         traits::complex_f* work, float* rwork, int* iwork, int* ifail, int& info) 
00108       {
00109         LAPACK_CHBEVX (
00110           &jobz, &range, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
00111           traits::complex_ptr(q), &ldq,
00112           &vl, &vu, &il, &iu, &abstol, &m,
00113           w, traits::complex_ptr(z), &ldz,
00114           traits::complex_ptr(work), rwork, iwork, ifail, &info);
00115       }
00116 
00117       inline 
00118       void hbevx (
00119         char const jobz, char const range, char const uplo, int const n, int const kd,
00120         traits::complex_d* ab, int const ldab, traits::complex_d* q, int const ldq,
00121         double const vl, double const vu, int const il, int const iu,
00122         double const abstol, int& m,
00123         double* w, traits::complex_d* z, int const ldz,
00124         traits::complex_d* work, double* rwork, int* iwork, int* ifail, int& info) 
00125       {
00126         LAPACK_ZHBEVX (
00127           &jobz, &range, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
00128           traits::complex_ptr(q), &ldq,
00129           &vl, &vu, &il, &iu, &abstol, &m,
00130           w, traits::complex_ptr(z), &ldz,
00131           traits::complex_ptr(work), rwork, iwork, ifail, &info);
00132       }
00133     } 
00134 
00135 
00136     namespace detail {
00137       template <int N>
00138       struct Hbevx{};
00139 
00140 
00142       template <>
00143       struct Hbevx< 1 > {
00144         template <typename T, typename R>
00145         void operator() (char const jobz, char const range, char const uplo, int const n,
00146           int const kd, T* ab, int const ldab, T* q, int const ldq,
00147           R vl, R vu, int const il, int const iu, R abstol, int& m,
00148           R* w, T* z, int const ldz,
00149           minimal_workspace, int* ifail, int& info ) const {
00150 
00151           traits::detail::array<T> work( 7*n );
00152           traits::detail::array<int> iwork( 5*n );
00153           hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
00154             vl, vu, il, iu, abstol, m,
00155             w, z, ldz,
00156             traits::vector_storage( work ),
00157             traits::vector_storage (iwork),
00158             ifail, info );
00159         }
00160 
00161         template <typename T, typename R>
00162         void operator() (char const jobz, char const range, char const uplo, int const n,
00163           int const kd, T* ab, int const ldab, T* q, int const ldq,
00164           R vl, R vu, int const il, int const iu, R abstol, int& m,
00165           R* w, T* z, int const ldz,
00166           optimal_workspace, int* ifail, int& info ) const {
00167 
00168           traits::detail::array<T> work( 7*n );
00169           traits::detail::array<int> iwork( 5*n );
00170           hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
00171             vl, vu, il, iu, abstol, m,
00172             w, z, ldz,
00173             traits::vector_storage( work ),
00174             traits::vector_storage (iwork),
00175             ifail, info );
00176         }
00177 
00178         template <typename T, typename R, typename W, typename WI>
00179         void operator() (char const jobz, char const range, char const uplo, int const n,
00180           int const kd, T* ab, int const ldab, T* q, int const ldq,
00181           R vl, R vu, int const il, int const iu, R abstol, int& m,
00182           R* w, T* z, int const ldz,
00183           std::pair<detail::workspace1<W>, detail::workspace1<WI> > work,
00184           int* ifail, int& info ) const {
00185 
00186           assert( traits::vector_size( work.first.w_ ) >= 7*n );
00187           assert( traits::vector_size( work.second.w_ ) >= 5*n );
00188           hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
00189             vl, vu, il, iu, abstol, m,
00190             w, z, ldz,
00191             traits::vector_storage( work.first.w_ ),
00192             traits::vector_storage( work.second.w_ ),
00193             ifail, info );
00194         }
00195       }; // Hbevx< 1 >
00196 
00197 
00199       template <>
00200       struct Hbevx< 2 > {
00201         template <typename T, typename R>
00202         void operator() (char const jobz, char const range, char const uplo, int const n,
00203           int const kd, T* ab, int const ldab, T* q, int const ldq,
00204           R vl, R vu, int const il, int const iu, R abstol, int& m,
00205           R* w, T* z, int const ldz,
00206           minimal_workspace, int* ifail, int& info ) const {
00207 
00208           traits::detail::array<T> work( n );
00209           traits::detail::array<R> rwork( 7*n );
00210           traits::detail::array<int> iwork( 5*n );
00211           hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
00212             vl, vu, il, iu, abstol, m,
00213             w, z, ldz,
00214             traits::vector_storage( work ),
00215             traits::vector_storage( rwork ),
00216             traits::vector_storage (iwork),
00217             ifail, info );
00218         }
00219 
00220         template <typename T, typename R>
00221         void operator() (char const jobz, char const range, char const uplo, int const n,
00222           int const kd, T* ab, int const ldab, T* q, int const ldq,
00223           R vl, R vu, int const il, int const iu, R abstol, int& m,
00224           R* w, T* z, int const ldz,
00225           optimal_workspace, int* ifail, int& info ) const {
00226 
00227           traits::detail::array<T> work( n );
00228           traits::detail::array<R> rwork( 7*n );
00229           traits::detail::array<int> iwork( 5*n );
00230           hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
00231             vl, vu, il, iu, abstol, m,
00232             w, z, ldz,
00233             traits::vector_storage( work ),
00234             traits::vector_storage( rwork ),
00235             traits::vector_storage (iwork),
00236             ifail, info );
00237         }
00238 
00239         template <typename T, typename R, typename W, typename RW, typename WI>
00240         void operator() (char const jobz, char const range, char const uplo, int const n,
00241           int const kd, T* ab, int const ldab, T* q, int const ldq,
00242           R vl, R vu, int const il, int const iu, R abstol, int& m,
00243           R* w, T* z, int const ldz,
00244           std::pair<detail::workspace2<W,RW>, detail::workspace1<WI> > work,
00245           int* ifail, int& info ) const {
00246 
00247           assert( traits::vector_size( work.first.w_ ) >= n );
00248           assert( traits::vector_size( work.first.wr_ ) >= 7*n );
00249           assert( traits::vector_size( work.second.w_ ) >= 5*n );
00250           hbevx( jobz, range, uplo, n, kd, ab, ldab, q, ldq,
00251             vl, vu, il, iu, abstol, m,
00252             w, z, ldz,
00253             traits::vector_storage( work.first.w_ ),
00254             traits::vector_storage( work.first.wr_ ),
00255             traits::vector_storage( work.second.w_ ),
00256             ifail, info );
00257         }
00258       }; // Hbevx< 2 >
00259     } // namespace detail
00260 
00261     template <typename AB, typename Q, typename R, typename Z, typename W, typename IFail, typename Work>
00262     int hbevx( char const jobz, char const range, AB& ab, Q& q, R vl, R vu, int il, int iu, R abstol, int& m,
00263       W& w, Z& z, IFail& ifail, Work work ) {
00264 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00265       BOOST_STATIC_ASSERT((boost::is_same<
00266         typename traits::matrix_traits<AB>::matrix_structure, 
00267         traits::hermitian_t
00268       >::value)); 
00269 #endif 
00270 
00271       typedef typename AB::value_type                            value_type ;
00272 
00273       int const n = traits::matrix_size2 (ab);
00274       assert (n == traits::matrix_size1 (z)); 
00275       assert (n == traits::vector_size (w));
00276       assert (n == traits::vector_size (ifail));
00277       assert ( jobz=='N' || jobz=='V' );
00278 
00279       int info ; 
00280       detail::Hbevx< n_workspace_args<value_type>::value >() (jobz, range,
00281         traits::matrix_uplo_tag( ab ), n,
00282         traits::matrix_upper_bandwidth(ab),
00283         traits::matrix_storage (ab), 
00284         traits::leading_dimension (ab),
00285         traits::matrix_storage (q), 
00286         traits::leading_dimension (q),
00287         vl, vu, il, iu, abstol, m,
00288         traits::vector_storage (w),
00289         traits::matrix_storage (z),
00290         traits::leading_dimension (z),
00291         work,
00292         traits::vector_storage (ifail),
00293         info);
00294       return info ;
00295     } // hbevx()
00296   }
00297 
00298 }}}
00299 
00300 #endif

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