hbev.hpp

Go to the documentation of this file.
00001 /*
00002  * 
00003  * Copyright (c) Toon Knapen, Karl Meerbergen & 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_HBEV_HPP
00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_HBEV_HPP
00016 
00017 #include <boost/numeric/bindings/traits/type.hpp>
00018 #include <boost/numeric/bindings/traits/traits.hpp>
00019 #include <boost/numeric/bindings/traits/type_traits.hpp>
00020 #include <boost/numeric/bindings/lapack/lapack.h>
00021 #include <boost/numeric/bindings/lapack/workspace.hpp>
00022 #include <boost/numeric/bindings/traits/detail/array.hpp>
00023 #include <boost/numeric/bindings/traits/detail/utils.hpp>
00024 
00025 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00026 #  include <boost/static_assert.hpp>
00027 #  include <boost/type_traits.hpp>
00028 #endif 
00029 
00030 
00031 namespace boost { namespace numeric { namespace bindings { 
00032 
00033   namespace lapack {
00034 
00036     //
00037     // Eigendecomposition of a banded Hermitian matrix.
00038     // 
00040 
00041     /* 
00042      * hbev() computes the eigenvalues and optionally the associated
00043      * eigenvectors of a banded Hermitian matrix A. A matrix is Hermitian
00044      * when herm( A ) == A. When A is real, a Hermitian matrix is also
00045      * called symmetric.
00046      *
00047      * The eigen decomposition is A = U S * herm(U)  where  U  is a
00048      * unitary matrix and S is a diagonal matrix. The eigenvalues of A
00049      * are on the main diagonal of S. The eigenvalues are real.
00050      *
00051      * Workspace is organized following the arguments in the calling sequence.
00052      *  optimal_workspace() : for optimizing use of blas 3 kernels
00053      *  minimal_workspace() : minimum size of workarrays, but does not allow for optimization
00054      *                        of blas 3 kernels
00055      *  workspace( work ) for real matrices where work is a real array with
00056      *                    vector_size( work ) >= 3*matrix_size1( a ) - 2
00057      *  workspace( work, rwork ) for complex matrices where work is a complex
00058      *                           array with vector_size( work ) >= matrix_size1( a )
00059      *                           and rwork is a real array with
00060      *                           vector_size( rwork ) >= 3 * matrix_size1( a ) - 2.
00061      */
00062 
00063     /*
00064      * If uplo=='L' only the lower triangular part is stored.
00065      * If uplo=='U' only the upper triangular part is stored.
00066      *
00067      * The matrix is assumed to be stored in LAPACK band format, i.e.
00068      * matrices are stored columnwise, in a compressed format so that when e.g. uplo=='U'
00069      * the (i,j) element with j>=i is in position  (i-j) + j * (KD+1) + KD  where KD is the
00070      * half bandwidth of the matrix. For a triadiagonal matrix, KD=1, for a diagonal matrix
00071      * KD=0.
00072      * When uplo=='L', the (i,j) element with j>=i is in position  (i-j) + j * (KD+1).
00073      *
00074      * The matrix A is thus a rectangular matrix with KD+1 rows and N columns.
00075      */ 
00076 
00077     namespace detail {
00078       inline 
00079       void hbev (char const jobz, char const uplo, int const n, int const kd,
00080                  float* ab, int const ldab, float* w, float* z, int const ldz,
00081                  float* work, int& info) 
00082       {
00083               //for (int i=0; i<n*kd; ++i) std::cout << *(ab+i) << " " ;
00084               //std::cout << "\n" ;
00085         LAPACK_SSBEV (&jobz, &uplo, &n, &kd, ab, &ldab, w, z, &ldz,
00086                       work, &info);
00087       }
00088 
00089       inline 
00090       void hbev (char const jobz, char const uplo, int const n, int const kd,
00091                  double* ab, int const ldab, double* w, double* z, int const ldz,
00092                  double* work, int& info) 
00093       {
00094         LAPACK_DSBEV (&jobz, &uplo, &n, &kd, ab, &ldab, w, z, &ldz,
00095                       work, &info);
00096       }
00097 
00098       inline 
00099       void hbev (char const jobz, char const uplo, int const n, int const kd,
00100                  traits::complex_f* ab, int const ldab, float* w,
00101                  traits::complex_f* z, int const ldz,
00102                  traits::complex_f* work, float* rwork, int& info) 
00103       {
00104         LAPACK_CHBEV (&jobz, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
00105                       w, traits::complex_ptr(z), &ldz,
00106                       traits::complex_ptr(work), rwork, &info);
00107       }
00108 
00109       inline 
00110       void hbev (char const jobz, char const uplo, int const n, int const kd,
00111                  traits::complex_d* ab, int const ldab, double* w,
00112                  traits::complex_d* z, int const ldz,
00113                  traits::complex_d* work, double* rwork, int& info) 
00114       {
00115         LAPACK_ZHBEV (&jobz, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
00116                       w, traits::complex_ptr(z), &ldz,
00117                       traits::complex_ptr(work), rwork, &info);
00118       }
00119     } 
00120 
00121 
00122     namespace detail {
00123        template <int N>
00124        struct Hbev{};
00125 
00126 
00128        template <>
00129        struct Hbev< 1 > {
00130           template <typename T, typename R>
00131           void operator() (char const jobz, char const uplo, int const n,
00132                            int const kd, T* ab, int const ldab, R* w, T* z,
00133                            int const ldz, minimal_workspace , int& info ) const {
00134              traits::detail::array<T> work( 3*n-2 );
00135              hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
00136                    traits::vector_storage( work ),
00137                    info );
00138           }
00139 
00140           template <typename T, typename R>
00141           void operator() (char const jobz, char const uplo, int const n,
00142                            int const kd, T* ab, int const ldab, R* w, T* z,
00143                            int const ldz, optimal_workspace , int& info ) const {
00144              traits::detail::array<T> work( 3*n-2 );
00145 
00146              hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
00147                    traits::vector_storage( work ),
00148                    info );
00149           }
00150 
00151           template <typename T, typename R, typename W>
00152           void operator() (char const jobz, char const uplo, int const n,
00153                            int const kd, T* ab, int const ldab, R* w, T* z,
00154                            int const ldz, detail::workspace1<W> work,
00155                            int& info ) const {
00156              assert( traits::vector_size( work.w_ ) >= 3*n-2 );
00157 
00158              hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
00159                    traits::vector_storage( work.w_ ),
00160                    info );
00161           }
00162        }; // Hbev< 1 >
00163 
00164 
00166        template <>
00167        struct Hbev< 2 > {
00168           template <typename T, typename R>
00169           void operator() (char const jobz, char const uplo, int const n,
00170                            int const kd, T* ab, int const ldab, R* w, T* z,
00171                            int const ldz, minimal_workspace , int& info ) const {
00172              traits::detail::array<T> work( n );
00173              traits::detail::array<R> rwork( 3*n-2 );
00174 
00175              hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
00176                    traits::vector_storage( work ),
00177                    traits::vector_storage( rwork ),
00178                    info );
00179           }
00180 
00181           template <typename T, typename R>
00182           void operator() (char const jobz, char const uplo, int const n,
00183                            int const kd, T* ab, int const ldab, R* w, T* z,
00184                            int const ldz, optimal_workspace , int& info ) const {
00185              traits::detail::array<T> work( n );
00186              traits::detail::array<R> rwork( 3*n-2 );
00187 
00188              hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
00189                    traits::vector_storage( work ),
00190                    traits::vector_storage( rwork ),
00191                    info );
00192           }
00193 
00194           template <typename T, typename R, typename W, typename RW>
00195           void operator() (char const jobz, char const uplo, int const n,
00196                            int const kd, T* ab, int const ldab, R* w, T* z,
00197                            int const ldz, detail::workspace2<W,RW> work,
00198                            int& info ) const {
00199              assert( traits::vector_size( work.wr_ ) >= 3*n-2 );
00200              assert( traits::vector_size( work.w_ ) >= n );
00201 
00202              hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
00203                    traits::vector_storage( work.w_ ),
00204                    traits::vector_storage( work.wr_ ),
00205                    info );
00206           }
00207        }; // Hbev< 2 >
00208     
00209 
00210 
00225        template <typename AB, typename Z, typename W, typename Work>
00226        int hbev( char const jobz, AB& ab, W& w, Z& z, Work work ) {
00227 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00228          BOOST_STATIC_ASSERT((boost::is_same<
00229            typename traits::matrix_traits<AB>::matrix_structure, 
00230            traits::hermitian_t
00231          >::value)); 
00232 #endif 
00233 
00234          typedef typename AB::value_type                            value_type ;
00235 
00236          int const n = traits::matrix_size2 (ab);
00237          assert (n == traits::matrix_size1 (z)); 
00238          assert (n == traits::vector_size (w));
00239          assert ( jobz=='N' || jobz=='V' );
00240 
00241          int info ; 
00242          detail::Hbev< n_workspace_args<value_type>::value >() (jobz,
00243                        traits::matrix_uplo_tag( ab ), n,
00244                        traits::matrix_upper_bandwidth(ab),
00245                        traits::matrix_storage (ab), 
00246                        traits::leading_dimension (ab),
00247                        traits::vector_storage (w),
00248                        traits::matrix_storage (z),
00249                        traits::leading_dimension (z),
00250                        work, info);
00251          return info ;
00252        } // hbev()
00253        
00254        } // namespace detail
00255 
00256 
00258        template <typename AB, typename W, typename Work>
00259        inline
00260        int hbev (AB& ab, W& w, Work work) {
00261           return detail::hbev( 'N', ab, w, ab, work );
00262        } // hbev()
00263 
00264 
00266        template <typename AB, typename W, typename Z, typename Work>
00267        inline
00268        int hbev (AB& ab, W& w, Z& z, Work work) {
00269          BOOST_STATIC_ASSERT((boost::is_same<
00270            typename traits::matrix_traits<Z>::matrix_structure, 
00271            traits::general_t
00272          >::value)); 
00273          int const n = traits::matrix_size2 (ab);
00274           assert (n == traits::matrix_size1 (z)); 
00275           assert (n == traits::matrix_size2 (z)); 
00276           return detail::hbev( 'V', ab, w, z, work );
00277        } // hbev()
00278 
00279   }
00280 
00281 }}}
00282 
00283 #endif 

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