orgqr.hpp

Go to the documentation of this file.
00001 //
00002 // Copyright Fabien Dekeyser, Quoc-Cuong Pham 2008
00003 //
00004 // Distributed under the Boost Software License, Version 1.0.
00005 // (See accompanying file LICENSE_1_0.txt or copy at
00006 // http://www.boost.org/LICENSE_1_0.txt)
00007 //
00008 
00009 
00010 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_ORGQR_HPP
00011 #define BOOST_NUMERIC_BINDINGS_LAPACK_ORGQR_HPP
00012 
00013 #include <complex>
00014 #include <boost/numeric/bindings/traits/traits.hpp>
00015 #include <boost/numeric/bindings/lapack/lapack.h>
00016 #include <boost/numeric/bindings/lapack/workspace.hpp>
00017 #include <boost/numeric/bindings/traits/detail/array.hpp>
00018 // #include <boost/numeric/bindings/traits/std_vector.hpp>
00019 
00020 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00021 #  include <boost/static_assert.hpp>
00022 #  include <boost/type_traits.hpp>
00023 #endif 
00024 
00025 
00026 namespace boost { namespace numeric { namespace bindings { 
00027 
00028   namespace lapack {
00029 
00030    
00032     /* 
00033      * Generates an M-by-N real matrix Q with orthonormal columns,
00034          * which is defined as the first N columns of a product of K elementary
00035          *        reflectors of order M
00036          *        Q  =  H(1) H(2) . . . H(k)
00037          * as returned by geqrf().
00038          * The init value of matrix Q is the matrix A returned by geqrf()
00039      */ 
00041     namespace detail {
00042 
00057       inline 
00058       void orgqr(int const m, int const n, int const k,
00059                  float* a, int const lda,
00060                  float* tau, float* work, int const lwork, int& info) 
00061       {
00062         LAPACK_SORGQR (&m, &n, &k, a, &lda, tau, work, &lwork, &info);
00063       }
00064 
00065       inline 
00066       void orgqr(int const m, int const n, int const k,
00067                  double* a, int const lda,
00068                  double* tau, double* work, int const lwork, int& info) 
00069       {
00070         LAPACK_DORGQR (&m, &n, &k, a, &lda, tau, work, &lwork, &info);
00071       }
00072 
00073       inline 
00074       void orgqr(int const m, int const n, int const k,
00075                  traits::complex_f* a, int const lda,
00076                  traits::complex_f* tau, traits::complex_f* work, int const lwork, int& info) 
00077       {
00078         LAPACK_CUNGQR (&m, &n, &k, traits::complex_ptr(a), &lda, traits::complex_ptr(tau),
00079                        traits::complex_ptr(work), &lwork, &info);
00080       }
00081 
00082       inline 
00083       void orgqr(int const m, int const n, int const k,
00084                  traits::complex_d* a, int const lda,
00085                  traits::complex_d* tau, traits::complex_d* work, int const lwork, int& info) 
00086       {
00087         LAPACK_ZUNGQR (&m, &n, &k, traits::complex_ptr(a), &lda, traits::complex_ptr(tau),
00088                        traits::complex_ptr(work), &lwork, &info);
00089       }
00090 
00091     } // fin namespace detail
00092 
00093 
00094         //--------------------------------------------
00095 
00096    template <typename A, typename Tau, typename Work>
00097    inline int orgqr(A& a, Tau& tau, Work &work) {
00098 
00099 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00100       BOOST_STATIC_ASSERT((boost::is_same<
00101         typename traits::matrix_traits<A>::matrix_structure, 
00102         traits::general_t
00103       >::value)); 
00104 #endif 
00105 
00106           const int m = traits::matrix_size1 (a);
00107           const int n = traits::matrix_size2 (a);
00108           const int k = n;
00109 
00110           assert (std::min<int>(m,n) <= traits::vector_size (tau)); 
00111       assert (n <= traits::vector_size (work)); 
00112          
00113           int info; 
00114       detail::orgqr (m, n, k,
00115                      traits::matrix_storage (a), 
00116                      traits::leading_dimension (a),
00117                      traits::vector_storage (tau),  
00118                      traits::vector_storage (work),
00119                      traits::vector_size (work),
00120                      info);
00121       return info;
00122     }
00123 
00124     // Computation of Q.
00125     // Workspace is allocated dynamically so that the optimization of
00126     // blas 3 calls is optimal.
00127     template <typename A, typename Tau>
00128     inline
00129     int orgqr (A& a, Tau& tau, optimal_workspace ) {
00130        typedef typename A::value_type value_type ;
00131            const int n = traits::matrix_size2 (a);
00132        traits::detail::array<value_type> work(std::max<int>(1, n*32));
00133        return orgqr( a, tau, work );
00134            
00135     }
00136 
00137     // Computation of Q
00138     // Workspace is allocated dynamically to its minimum size.
00139     // Blas 3 calls are not optimal.
00140     template <typename A, typename Tau>
00141     inline
00142     int orgqr (A& a, Tau& tau, minimal_workspace ) {
00143        typedef typename A::value_type value_type ;
00144            const int n = traits::matrix_size2 (a);
00145        traits::detail::array<value_type> work(std::max<int>(1, n));
00146        return orgqr( a, tau, work );
00147     }
00148 
00149     // Computation of the Q
00150     // Workspace is taken from the array in workspace.
00151    
00152     template <typename A, typename Tau, typename Work>
00153     inline
00154     int orgqr (A& a, Tau& tau, detail::workspace1<Work> workspace ) {
00155        typedef typename A::value_type value_type ;
00156            const int n = traits::matrix_size2 (a);
00157        traits::detail::array<value_type> work(std::max<int>(1, n));
00158        return orgqr( a, tau, workspace.w_ );
00159     }
00160 
00161     // Function without workarray as argument
00162     template <typename A, typename Tau>
00163     inline
00164     int orgqr (A& a, Tau& tau) {
00165        return orgqr( a, tau, optimal_workspace() );
00166     }
00167 
00168   }
00169 
00170 }}}
00171 
00172 #endif 

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