gees.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_GEES_HPP
00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_GEES_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     // Schur factorization of general matrix.
00038     // 
00040 
00041     /* 
00042      * gees() computes a Schur factorization of an N-by-N matrix A.
00043      *
00044      * The Schur decomposition is A = U S * herm(U)  where  U  is a
00045      * unitary matrix and S is upper triangular. The eigenvalues of A
00046      * are on the main diagonal of S. If A is real, S is in pseudo
00047      * upper triangular form.
00048      *
00049      * Workspace is organized following the arguments in the calling sequence.
00050      *  optimal_workspace() : for optimizing use of blas 3 kernels
00051      *  minimal_workspace() : minimum size of workarrays, but does not allow for optimization
00052      *                        of blas 3 kernels
00053      *  workspace( work ) for real matrices where work is a real array with
00054      *                    vector_size( work ) >= 3*matrix_size1( a )
00055      *  workspace( work, rwork ) for complex matrices where work is a complex
00056      *                           array with vector_size( work ) >= 2*matrix_size1( a )
00057      *                           and rwork is a real array with
00058      *                           vector_size( rwork ) >= matrix_size1( a ).
00059      */ 
00060 
00061     namespace detail {
00062       inline 
00063       void gees (char const jobvs, char const sort, logical_t* select, int const n,
00064                  float* a, int const lda, int& sdim, traits::complex_f* w,
00065                  float* vs, int const ldvs, float* work, int const lwork,
00066                  bool* bwork, int& info) 
00067       {
00068         traits::detail::array<float> wr(n);
00069         traits::detail::array<float> wi(n);
00070         LAPACK_SGEES (&jobvs, &sort, select, &n, a, &lda, &sdim,
00071                       traits::vector_storage(wr), traits::vector_storage(wi),
00072                       vs, &ldvs, work, &lwork, bwork, &info);
00073         traits::detail::interlace(traits::vector_storage(wr),
00074                                   traits::vector_storage(wr)+n,
00075                                   traits::vector_storage(wi),
00076                                   w);
00077       }
00078 
00079 
00080       inline 
00081       void gees (char const jobvs, char const sort, logical_t* select, int const n,
00082                  double* a, int const lda, int& sdim, traits::complex_d* w,
00083                  double* vs, int const ldvs, double* work, int const lwork,
00084                  bool* bwork, int& info) 
00085       {
00086         traits::detail::array<double> wr(n);
00087         traits::detail::array<double> wi(n);
00088         LAPACK_DGEES (&jobvs, &sort, select, &n, a, &lda, &sdim,
00089                       traits::vector_storage(wr), traits::vector_storage(wi),
00090                       vs, &ldvs, work, &lwork, bwork, &info);
00091         traits::detail::interlace(traits::vector_storage(wr),
00092                                   traits::vector_storage(wr)+n,
00093                                   traits::vector_storage(wi),
00094                                   w);
00095       }
00096 
00097 
00098       inline 
00099       void gees (char const jobvs, char const sort, logical_t* select, int const n,
00100                  traits::complex_f* a, int const lda, int& sdim, traits::complex_f* w,
00101                  traits::complex_f* vs, int const ldvs,
00102                  traits::complex_f* work, int lwork, float* rwork, bool* bwork,
00103                  int& info) 
00104       {
00105         LAPACK_CGEES (&jobvs, &sort, select, &n, traits::complex_ptr(a), &lda, &sdim,
00106                       traits::complex_ptr(w), traits::complex_ptr (vs), &ldvs,
00107                       traits::complex_ptr(work), &lwork, rwork, bwork, &info);
00108       }
00109 
00110 
00111       inline 
00112       void gees (char const jobvs, char const sort, logical_t* select, int const n,
00113                  traits::complex_d* a, int const lda, int& sdim, traits::complex_d* w,
00114                  traits::complex_d* vs, int const ldvs,
00115                  traits::complex_d* work, int lwork, double* rwork, bool* bwork,
00116                  int& info) 
00117       {
00118         LAPACK_ZGEES (&jobvs, &sort, select, &n, traits::complex_ptr(a), &lda, &sdim,
00119                       traits::complex_ptr(w), traits::complex_ptr(vs), &ldvs,
00120                       traits::complex_ptr(work), &lwork, rwork, bwork, &info);
00121       }
00122 
00123     } 
00124 
00125 
00126     namespace detail {
00128        template <typename MatrA, typename SchVec, typename EigVal, typename Work>
00129        inline
00130        int gees (char jobvs, MatrA& a, EigVal& w, SchVec& vs, Work& work) {
00131 
00132 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00133          BOOST_STATIC_ASSERT((boost::is_same<
00134            typename traits::matrix_traits<MatrA>::matrix_structure, 
00135            traits::general_t
00136          >::value)); 
00137          BOOST_STATIC_ASSERT((boost::is_same<
00138            typename traits::matrix_traits<SchVec>::matrix_structure, 
00139            traits::general_t
00140          >::value)); 
00141 #endif 
00142 
00143          typedef typename MatrA::value_type                            value_type ;
00144 
00145          int const n = traits::matrix_size1 (a);
00146          assert (n == traits::matrix_size2 (a)); 
00147          assert (n == traits::matrix_size1 (vs)); 
00148          assert (n == traits::matrix_size2 (vs)); 
00149          assert (n == traits::vector_size (w)); 
00150          assert (3*n <= traits::vector_size (work)); 
00151 
00152          logical_t* select=0;
00153          bool* bwork=0;
00154 
00155          int info, sdim; 
00156          detail::gees (jobvs, 'N', select, n,
00157                        traits::matrix_storage (a), 
00158                        traits::leading_dimension (a),
00159                        sdim,
00160                        traits::vector_storage (w),
00161                        traits::matrix_storage (vs),
00162                        traits::leading_dimension (vs),
00163                        traits::vector_storage( work ),
00164                        traits::vector_size( work ),
00165                        bwork, info);
00166          return info ;
00167        } // gees()
00168 
00169 
00171        template <typename MatrA, typename SchVec, typename EigVal,
00172                  typename Work, typename RWork>
00173        inline
00174        int gees (char jobvs, MatrA& a, EigVal& w, SchVec& vs,
00175                  Work& work, RWork& rwork) {
00176 
00177 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00178          BOOST_STATIC_ASSERT((boost::is_same<
00179            typename traits::matrix_traits<MatrA>::matrix_structure, 
00180            traits::general_t
00181          >::value)); 
00182          BOOST_STATIC_ASSERT((boost::is_same<
00183            typename traits::matrix_traits<SchVec>::matrix_structure, 
00184            traits::general_t
00185          >::value)); 
00186 #endif 
00187 
00188          typedef typename MatrA::value_type                            value_type ;
00189 
00190          int const n = traits::matrix_size1 (a);
00191          assert (n == traits::matrix_size2 (a)); 
00192          assert (n == traits::matrix_size1 (vs)); 
00193          assert (n == traits::matrix_size2 (vs)); 
00194          assert (n == traits::vector_size (w)); 
00195          assert (2*n <= traits::vector_size (work)); 
00196          assert (n <= traits::vector_size (rwork)); 
00197 
00198          logical_t* select=0;
00199          bool* bwork=0;
00200 
00201          int info, sdim; 
00202          detail::gees (jobvs, 'N', select, n,
00203                        traits::matrix_storage (a), 
00204                        traits::leading_dimension (a),
00205                        sdim,
00206                        traits::vector_storage (w),
00207                        traits::matrix_storage (vs),
00208                        traits::leading_dimension (vs),
00209                        traits::vector_storage( work ),
00210                        traits::vector_size( work ),
00211                        traits::vector_storage( rwork ),
00212                        bwork, info);
00213          return info ;
00214        } // gees()
00215 
00216 
00219        template <int N>
00220        struct Gees {};
00221 
00222 
00223        template <>
00224        struct Gees< 2 > {
00225           template <typename MatrA, typename SchVec, typename EigVal>
00226           inline
00227           int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, optimal_workspace ) const {
00228              typedef typename MatrA::value_type                            value_type ;
00229              typedef typename traits::type_traits< value_type >::real_type real_type ;
00230 
00231              int n = traits::matrix_size1( a );
00232 
00233              traits::detail::array<value_type> work( 2*n );
00234              traits::detail::array<real_type>  rwork( n );
00235 
00236              return gees( jobvs, a, w, vs, work, rwork );
00237           } // gees()
00238 
00239           template <typename MatrA, typename SchVec, typename EigVal>
00240           inline
00241           int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, minimal_workspace ) const {
00242              typedef typename MatrA::value_type                            value_type ;
00243              typedef typename traits::type_traits< value_type >::real_type real_type ;
00244 
00245              int n = traits::matrix_size1( a );
00246 
00247              traits::detail::array<value_type> work( 2*n );
00248              traits::detail::array<real_type>  rwork( n );
00249 
00250              return gees( jobvs, a, w, vs, work, rwork );
00251           } // gees()
00252 
00254           template <typename MatrA, typename SchVec, typename EigVal, typename RWork, typename Work>
00255           inline
00256           int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, workspace2<Work,RWork>& workspace ) const {
00257              return gees( jobvs, a, w, vs, workspace.w_, workspace.wr_ );
00258           } // gees()
00259        }; // Gees<2>
00260 
00261 
00262        template <>
00263        struct Gees< 1 > {
00264           template <typename MatrA, typename SchVec, typename EigVal>
00265           inline
00266           int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, optimal_workspace ) const {
00267              typedef typename MatrA::value_type                            value_type ;
00268              typedef typename traits::type_traits< value_type >::real_type real_type ;
00269 
00270              int n = traits::matrix_size1( a );
00271 
00272              traits::detail::array<value_type> work( 3*n );
00273 
00274              return gees( jobvs, a, w, vs, work );
00275           } // gees()
00276 
00277           template <typename MatrA, typename SchVec, typename EigVal>
00278           inline
00279           int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, minimal_workspace ) const {
00280              typedef typename MatrA::value_type                            value_type ;
00281              typedef typename traits::type_traits< value_type >::real_type real_type ;
00282 
00283              int n = traits::matrix_size1( a );
00284 
00285              traits::detail::array<value_type> work( 3*n );
00286 
00287              return gees( jobvs, a, w, vs, work );
00288           } // gees()
00289 
00291           template <typename MatrA, typename SchVec, typename EigVal, typename Work>
00292           inline
00293           int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, detail::workspace1<Work> workspace ) const {
00294              return gees( jobvs, a, w, vs, workspace.w_ );
00295           } // gees()
00296        }; // Gees<1>
00297 
00298     } // namespace detail
00299 
00300 
00312     template <typename MatrA, typename SchVec, typename EigVal, typename Workspace>
00313     inline
00314     int gees (MatrA& a, EigVal& e, SchVec& vs, Workspace workspace ) {
00315        return detail::Gees< n_workspace_args<typename MatrA::value_type>::value>()
00316                ( 'V', a, e, vs, workspace );
00317     } // gees()
00318 
00319 
00320     // Compute Schur factorization without Schur vectors.
00331     template <typename MatrA, typename EigVal, typename Workspace>
00332     inline
00333     int gees (MatrA& a, EigVal& e, Workspace workspace) {
00334       return detail::Gees< n_workspace_args<typename MatrA::value_type>::value>()
00335               ('N', a, e, a, workspace );
00336     }
00337 
00338   }
00339 
00340 }}}
00341 
00342 #endif 

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