heev.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_HEEV_HPP
00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_HEEV_HPP
00016 
00017 #include <boost/numeric/bindings/traits/traits.hpp>
00018 #include <boost/numeric/bindings/traits/type.hpp>
00019 #include <boost/numeric/bindings/lapack/lapack.h>
00020 #include <boost/numeric/bindings/lapack/workspace.hpp>
00021 #include <boost/numeric/bindings/traits/detail/array.hpp>
00022 // #include <boost/numeric/bindings/traits/std_vector.hpp>
00023 
00024 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00025 #  include <boost/static_assert.hpp>
00026 #  include <boost/type_traits.hpp>
00027 #endif 
00028 
00029 
00030 namespace boost { namespace numeric { namespace bindings { 
00031 
00032   namespace lapack {
00033 
00035     //
00036     // Eigendecomposition of a complex Hermitian matrix A = Q * D * Q'
00037     // 
00039 
00040     /* 
00041      * heev() computes the eigendecomposition of a N x N matrix
00042      * A = Q * D * Q',  where Q is a N x N unitary matrix and
00043      * D is a diagonal matrix. The diagonal element D(i,i) is an
00044      * eigenvalue of A and Q(:,i) is a corresponding eigenvector.
00045      * The eigenvalues are stored in ascending order.
00046      *
00047      * On return of heev, A is overwritten by Q and w contains the main
00048      * diagonal of D.
00049      *
00050      * int heev (char jobz, char uplo, A& a, W& w, minimal_workspace ) ;
00051      *    jobz : 'V' : compute eigenvectors
00052      *           'N' : do not compute eigenvectors
00053      *    uplo : 'U' : only the upper triangular part of A is used on input.
00054      *           'L' : only the lower triangular part of A is used on input.
00055      */ 
00056 
00057     namespace detail {
00058 
00059       inline 
00060       void heev (char const jobz, char const uplo, int const n,
00061                  traits::complex_f* a, int const lda,
00062                  float* w, traits::complex_f* work, int const lwork,
00063                  float* rwork, int& info) 
00064       {
00065         LAPACK_CHEEV (&jobz, &uplo, &n,
00066                       traits::complex_ptr(a), &lda, w,
00067                       traits::complex_ptr(work), &lwork,
00068                       rwork, &info);
00069       }
00070 
00071       inline 
00072       void heev (char const jobz, char const uplo, int const n,
00073                  traits::complex_d* a, int const lda,
00074                  double* w, traits::complex_d* work, int const lwork,
00075                  double* rwork, int& info) 
00076       {
00077         LAPACK_ZHEEV (&jobz, &uplo, &n,
00078                       traits::complex_ptr(a), &lda, w,
00079                       traits::complex_ptr(work), &lwork,
00080                       rwork, &info);
00081       }
00082 
00083 
00084       template <typename A, typename W, typename Work, typename RWork>
00085       inline
00086       int heev (char jobz, char uplo, A& a, W& w, Work& work, RWork& rwork) {
00087 
00088 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00089         BOOST_STATIC_ASSERT((boost::is_same<
00090           typename traits::matrix_traits<A>::matrix_structure, 
00091           traits::general_t
00092         >::value)); 
00093 #endif 
00094 
00095         int const n = traits::matrix_size1 (a);
00096         assert (traits::matrix_size2 (a)==n); 
00097         assert (traits::vector_size (w)==n); 
00098         assert (2*n-1 <= traits::vector_size (work)); 
00099         assert (3*n-2 <= traits::vector_size (rwork)); 
00100         assert ( uplo=='U' || uplo=='L' );
00101         assert ( jobz=='N' || jobz=='V' );
00102 
00103         int info; 
00104         detail::heev (jobz, uplo, n,
00105                      traits::matrix_storage (a), 
00106                      traits::leading_dimension (a),
00107                      traits::vector_storage (w),  
00108                      traits::vector_storage (work),
00109                      traits::vector_size (work),
00110                      traits::vector_storage (rwork),
00111                      info);
00112         return info; 
00113       }
00114     } // namespace detail
00115 
00116 
00117     // Function that allocates temporary arrays
00118     template <typename A, typename W>
00119     int heev (char jobz, char uplo, A& a, W& w, minimal_workspace ) {
00120        typedef typename A::value_type                              value_type ;
00121        typedef typename traits::type_traits<value_type>::real_type real_type ;
00122 
00123        int const n = traits::matrix_size1 (a);
00124 
00125        traits::detail::array<value_type> work( std::max(1,2*n-1) );
00126        traits::detail::array<real_type> rwork( std::max(3*n-1,1) );
00127 
00128        return detail::heev( jobz, uplo, a, w, work, rwork );
00129     }
00130 
00131 
00132     // Function that allocates temporary arrays
00133     template <typename A, typename W>
00134     int heev (char jobz, char uplo, A& a, W& w, optimal_workspace ) {
00135        typedef typename A::value_type                              value_type ;
00136        typedef typename traits::type_traits<value_type>::real_type real_type ;
00137 
00138        int const n = traits::matrix_size1 (a);
00139 
00140        traits::detail::array<value_type> work( std::max(1,33*n) );
00141        traits::detail::array<real_type> rwork( std::max(3*n-1,1) );
00142 
00143        return detail::heev( jobz, uplo, a, w, work, rwork );
00144     }
00145 
00146 
00147     // Function that uses given workarrays
00148     template <typename A, typename W, typename WC, typename WR>
00149     int heev (char jobz, char uplo, A& a, W& w, detail::workspace2<WC,WR> workspace ) {
00150        typedef typename A::value_type                              value_type ;
00151        typedef typename traits::type_traits<value_type>::real_type real_type ;
00152 
00153        return detail::heev( jobz, uplo, a, w, workspace.w_, workspace.wr_ );
00154     }
00155 
00156   }
00157 
00158 }}}
00159 
00160 #endif 

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