ormqr.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_ORMQR_HPP
00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_ORMQR_HPP
00016 
00017 #include <complex>
00018 #include <boost/numeric/bindings/traits/traits.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     // Apply the orthogonal transformation abtained by geqrf() to
00037     // a general matrix.
00038     // 
00040 
00041     /* 
00042      * ormqr() overwrites the general M by N matrix C with
00043      *
00044      *                         SIDE = 'L'     SIDE = 'R'
00045      *  TRANS = 'N':             Q * C          C * Q
00046      *  TRANS = 'C' || 'T':      Q**H * C       C * Q**H
00047      *
00048      *  where Q is a complex unitary matrix defined as the product of k
00049      *  elementary reflectors
00050      *
00051      *        Q = H(1) H(2) . . . H(k)
00052      *
00053      *  as returned by geqrf(). Q is of order M if SIDE = 'L' and of order N
00054      *  if SIDE = 'R'.
00055      *
00056      *  Workspace is organized following the arguments in the calling sequence.
00057      *   optimal_workspace() : for optimizing use of blas 3 kernels
00058      *   minimal_workspace() : minimum size of workarrays, but does not allow for optimization
00059      *                         of blas 3 kernels
00060      *   workspace( work ) where is an array that is used as auxiliary memory with the same value_type
00061      *                     as C.
00062      *                     We must have that vector_size( work ) >= matrix_size2( c )
00063      *                     if SIDE=='L' otherwise  vector_size( work ) >= matrix_size1( c )
00064      */ 
00065 
00066     namespace detail {
00067 
00068       inline 
00069       void ormqr (char const side, char const trans, int const m, int const n,
00070                  int const k, const float* a, int const lda,
00071                  const float* tau, float* c,
00072                  int const ldc, float* work, int const lwork,
00073                  int& info) 
00074       {
00075         LAPACK_SORMQR (&side, &trans, &m, &n, &k,
00076                       a, &lda,
00077                       tau,
00078                       c, &ldc,
00079                       work, &lwork,
00080                       &info);
00081       }
00082 
00083       inline 
00084       void ormqr (char const side, char const trans, int const m, int const n,
00085                  int const k, const double* a, int const lda,
00086                  const double* tau, double* c,
00087                  int const ldc, double* work, int const lwork,
00088                  int& info) 
00089       {
00090         LAPACK_DORMQR (&side, &trans, &m, &n, &k,
00091                       a, &lda,
00092                       tau,
00093                       c, &ldc,
00094                       work, &lwork,
00095                       &info);
00096       }
00097 
00098       inline 
00099       void ormqr (char const side, char const trans, int const m, int const n,
00100                  int const k, const traits::complex_f* a, int const lda,
00101                  const traits::complex_f* tau, traits::complex_f* c,
00102                  int const ldc, traits::complex_f* work, int const lwork,
00103                  int& info) 
00104       {
00105         LAPACK_CUNMQR (&side, &trans, &m, &n, &k,
00106                       traits::complex_ptr(a), &lda,
00107                       traits::complex_ptr(tau),
00108                       traits::complex_ptr(c), &ldc,
00109                       traits::complex_ptr(work), &lwork,
00110                       &info);
00111       }
00112 
00113       inline 
00114       void ormqr (char const side, char const trans, int const m, int const n,
00115                  int const k, const traits::complex_d* a, int const lda,
00116                  const traits::complex_d* tau, traits::complex_d* c,
00117                  int const ldc, traits::complex_d* work, int const lwork,
00118                  int& info) 
00119       {
00120         LAPACK_ZUNMQR (&side, &trans, &m, &n, &k,
00121                       traits::complex_ptr(a), &lda,
00122                       traits::complex_ptr(tau),
00123                       traits::complex_ptr(c), &ldc,
00124                       traits::complex_ptr(work), &lwork,
00125                       &info);
00126       }
00127 
00128 
00129       template <typename A, typename Tau, typename C, typename Work>
00130       inline
00131       int ormqr (char side, char trans, const A& a, const Tau& tau, C& c,
00132                  Work& work) {
00133 
00134 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00135         BOOST_STATIC_ASSERT((boost::is_same<
00136           typename traits::matrix_traits<A>::matrix_structure, 
00137           traits::general_t
00138         >::value)); 
00139         BOOST_STATIC_ASSERT((boost::is_same<
00140           typename traits::matrix_traits<C>::matrix_structure, 
00141           traits::general_t
00142         >::value)); 
00143 #endif 
00144 
00145         int const m = traits::matrix_size1 (c);
00146         int const n = traits::matrix_size2 (c);
00147         int const k = traits::vector_size (tau);
00148         int const lwork = traits::vector_size (work);
00149 
00150         assert ( side=='L' || side=='R' );
00151         assert ( trans=='N' || trans=='C' || trans=='T' );
00152         assert ( (side=='L' ?  m >= k : n >= k ) );
00153 
00154         assert ( (side=='L' ?
00155                   m == traits::matrix_size1 (a) :
00156                   n == traits::matrix_size1 (a) ) );
00157         assert (traits::matrix_size2 (a)==k); 
00158 
00159         assert ( (side=='L' ?
00160                   lwork >= n : lwork >= m ) );
00161 
00162         int info; 
00163         ormqr (side, trans, m, n, k,
00164                        traits::matrix_storage (a), 
00165                        traits::leading_dimension (a),
00166                        traits::vector_storage (tau),  
00167                        traits::matrix_storage (c), 
00168                        traits::leading_dimension (c),
00169                        traits::vector_storage (work),
00170                        lwork,
00171                        info);
00172         return info; 
00173       }
00174     } // namespace detail
00175 
00176 
00177     // Function that allocates temporary arrays for optimal execution time.
00178     template <typename A, typename Tau, typename C>
00179     inline
00180     int ormqr (char side, char trans, const A& a, const Tau& tau, C& c, optimal_workspace ) {
00181        typedef typename A::value_type                              value_type ;
00182 
00183        int const n_w = (side=='L' ? traits::matrix_size2 (c)
00184                                   : traits::matrix_size1 (c) );
00185 
00186        traits::detail::array<value_type> work( std::max(1,n_w*32) );
00187 
00188        return detail::ormqr( side, trans, a, tau, c, work );
00189     }
00190 
00191 
00192     // Function that allocates temporary arrays with minimal size
00193     template <typename A, typename Tau, typename C>
00194     inline
00195     int ormqr (char side, char trans, const A& a, const Tau& tau, C& c, minimal_workspace ) {
00196        typedef typename A::value_type                              value_type ;
00197 
00198        int const n_w = (side=='L' ? traits::matrix_size2 (c)
00199                                   : traits::matrix_size1 (c) );
00200 
00201        traits::detail::array<value_type> work( std::max(1,n_w) );
00202 
00203        return detail::ormqr( side, trans, a, tau, c, work );
00204     }
00205 
00206 
00207     // Function that uses auxiliary array in workspace
00208     // The calling sequence is ormqr(side, trans, a, tau, c, workspace( work_array ) )
00209     // where work_array is an array with the same value_type as a and c .
00210     template <typename A, typename Tau, typename C, typename Work>
00211     inline
00212     int ormqr (char side, char trans, const A& a, const Tau& tau, C& c, detail::workspace1<Work> workspace ) {
00213        typedef typename A::value_type                              value_type ;
00214 
00215        return detail::ormqr( side, trans, a, tau, c, workspace.w_ );
00216     }
00217 
00218   }
00219 
00220 }}}
00221 
00222 #endif 

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