syev.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_SYEV_HPP
00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_SYEV_HPP
00016 
00017 #include <boost/numeric/bindings/traits/traits.hpp>
00018 #include <boost/numeric/bindings/lapack/lapack.h>
00019 #include <boost/numeric/bindings/lapack/workspace.hpp>
00020 #include <boost/numeric/bindings/traits/detail/array.hpp>
00021 // #include <boost/numeric/bindings/traits/std_vector.hpp>
00022 
00023 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00024 #  include <boost/static_assert.hpp>
00025 #  include <boost/type_traits.hpp>
00026 #endif 
00027 
00028 #include <cassert>
00029 
00030 
00031 namespace boost { namespace numeric { namespace bindings { 
00032 
00033   namespace lapack {
00034 
00036     //
00037     // Eigendecomposition of a real symmetric matrix A = Q * D * Q'
00038     // 
00040 
00041     /* 
00042      * syev() computes the eigendecomposition of a N x N matrix
00043      * A = Q * D * Q',  where Q is a N x N orthogonal matrix and
00044      * D is a diagonal matrix. The diagonal elements D(i,i) is an
00045      * eigenvalue of A and Q(:,i) is a corresponding eigenvector.
00046      *
00047      * On return of syev, A is overwritten by Q and w contains the main
00048      * diagonal of D.
00049      *
00050      * int syev (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 syev (char const jobz, char const uplo, int const n,
00061                  float* a, int const lda,
00062                  float* w, float* work, int const lwork, int& info) 
00063       {
00064         LAPACK_SSYEV (&jobz, &uplo, &n, a, &lda, w, work, &lwork, &info);
00065       }
00066 
00067       inline 
00068       void syev (char const jobz, char const uplo, int const n,
00069                  double* a, int const lda,
00070                  double* w, double* work, int const lwork, int& info) 
00071       {
00072         LAPACK_DSYEV (&jobz, &uplo, &n, a, &lda, w, work, &lwork, &info);
00073       }
00074 
00075 
00076       template <typename A, typename W, typename Work>
00077       inline
00078       int syev (char jobz, char uplo, A& a, W& w, Work& work) {
00079 
00080 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00081         BOOST_STATIC_ASSERT((boost::is_same<
00082           typename traits::matrix_traits<A>::matrix_structure, 
00083           traits::general_t
00084         >::value)); 
00085 #endif 
00086 
00087         int const n = traits::matrix_size1 (a);
00088         assert ( n>0 );
00089         assert (traits::matrix_size2 (a)==n); 
00090         assert (traits::leading_dimension (a)>=n); 
00091         assert (traits::vector_size (w)==n); 
00092         assert (3*n-1 <= traits::vector_size (work)); 
00093         assert ( uplo=='U' || uplo=='L' );
00094         assert ( jobz=='N' || jobz=='V' );
00095 
00096         int info; 
00097         detail::syev (jobz, uplo, n,
00098                      traits::matrix_storage (a), 
00099                      traits::leading_dimension (a),
00100                      traits::vector_storage (w),  
00101                      traits::vector_storage (work),
00102                      traits::vector_size (work),
00103                      info);
00104         return info; 
00105       }
00106     }  // namespace detail
00107 
00108 
00109     // Function that allocates work arrays
00110     template <typename A, typename W>
00111     inline
00112     int syev (char jobz, char uplo, A& a, W& w, optimal_workspace ) {
00113        typedef typename A::value_type value_type ;
00114 
00115        int const n = traits::matrix_size1 (a);
00116 
00117        traits::detail::array<value_type> work( std::max(1,34*n) );
00118        return detail::syev(jobz, uplo, a, w, work);
00119     } // syev()
00120 
00121 
00122     // Function that allocates work arrays
00123     template <typename A, typename W>
00124     inline
00125     int syev (char jobz, char uplo, A& a, W& w, minimal_workspace ) {
00126        typedef typename A::value_type value_type ;
00127 
00128        int const n = traits::matrix_size1 (a);
00129 
00130        traits::detail::array<value_type> work( std::max(1,3*n-1) );
00131        return detail::syev(jobz, uplo, a, w, work);
00132     } // syev()
00133 
00134 
00135     // Function that allocates work arrays
00136     template <typename A, typename W, typename Work>
00137     inline
00138     int syev (char jobz, char uplo, A& a, W& w, detail::workspace1<Work> workspace ) {
00139        typedef typename A::value_type value_type ;
00140 
00141        return detail::syev(jobz, uplo, a, w, workspace.w_);
00142     } // syev()
00143 
00144   }
00145 
00146 }}}
00147 
00148 #endif 

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