gesdd.hpp

Go to the documentation of this file.
00001 /*
00002  * 
00003  * Copyright (c) Toon Knapen & 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_GESDD_HPP
00015 #define BOOST_NUMERIC_BINDINGS_LAPACK_GESDD_HPP
00016 
00017 #include <boost/numeric/bindings/traits/type_traits.hpp>
00018 #include <boost/numeric/bindings/traits/traits.hpp>
00019 #include <boost/numeric/bindings/lapack/lapack.h>
00020 #include <boost/numeric/bindings/traits/detail/array.hpp>
00021 #include <boost/numeric/bindings/traits/detail/utils.hpp>
00022 
00023 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00024 #  include <boost/static_assert.hpp>
00025 #  include <boost/type_traits/is_same.hpp>
00026 #endif 
00027 
00028 #include <cassert>
00029 
00030 namespace boost { namespace numeric { namespace bindings { 
00031 
00032   namespace lapack {
00033 
00035     //
00036     // singular value decomposition 
00037     // 
00039 
00040     /* 
00041      * (divide and conquer driver) 
00042      * gesdd() computes the singular value decomposition (SVD) of 
00043      * M-by-N matrix A, optionally computing the left and/or right 
00044      * singular vectors, by using divide-and-conquer method. 
00045      * The SVD is written
00046      *
00047      *     A = U * S * V^T    or    A = U * S * V^H
00048      *
00049      * where S is an M-by-N matrix which is zero except for its min(m,n)
00050      * diagonal elements, U is an M-by-M orthogonal/unitary matrix, and V 
00051      * is an N-by-N orthogonal/unitary matrix. The diagonal elements of S
00052      * are the singular values of A; they are real and non-negative, and 
00053      * are returnede in descending  order. The first min(m,n) columns of 
00054      * U and V are the left and right singular vectors of A. (Note that 
00055      * the routine returns V^T or V^H, not V.
00056      */ 
00057 
00058     namespace detail {
00059 
00060       inline 
00061       void gesdd (char const jobz, int const m, int const n, 
00062                   float* a, int const lda, 
00063                   float* s, float* u, int const ldu, 
00064                   float* vt, int const ldvt,
00065                   float* work, int const lwork, float* /* dummy */, 
00066                   int* iwork, int* info)
00067       {
00068         LAPACK_SGESDD (&jobz, &m, &n, a, &lda, s, 
00069                        u, &ldu, vt, &ldvt, work, &lwork, iwork, info); 
00070       }
00071 
00072       inline 
00073       void gesdd (char const jobz, int const m, int const n, 
00074                   double* a, int const lda, 
00075                   double* s, double* u, int const ldu, 
00076                   double* vt, int const ldvt,
00077                   double* work, int const lwork, double* /* dummy */, 
00078                   int* iwork, int* info)
00079       {
00080         LAPACK_DGESDD (&jobz, &m, &n, a, &lda, s, 
00081                        u, &ldu, vt, &ldvt, work, &lwork, iwork, info); 
00082       }
00083 
00084       inline 
00085       void gesdd (char const jobz, int const m, int const n, 
00086                   traits::complex_f* a, int const lda, 
00087                   float* s, traits::complex_f* u, int const ldu, 
00088                   traits::complex_f* vt, int const ldvt,
00089                   traits::complex_f* work, int const lwork, 
00090                   float* rwork, int* iwork, int* info)
00091       {
00092         LAPACK_CGESDD (&jobz, &m, &n, 
00093                        traits::complex_ptr (a), &lda, s, 
00094                        traits::complex_ptr (u), &ldu, 
00095                        traits::complex_ptr (vt), &ldvt, 
00096                        traits::complex_ptr (work), &lwork, 
00097                        rwork, iwork, info); 
00098       }
00099 
00100       inline 
00101       void gesdd (char const jobz, int const m, int const n, 
00102                   traits::complex_d* a, int const lda, 
00103                   double* s, traits::complex_d* u, int const ldu, 
00104                   traits::complex_d* vt, int const ldvt,
00105                   traits::complex_d* work, int const lwork, 
00106                   double* rwork, int* iwork, int* info)
00107       {
00108         LAPACK_ZGESDD (&jobz, &m, &n, 
00109                        traits::complex_ptr (a), &lda, s, 
00110                        traits::complex_ptr (u), &ldu, 
00111                        traits::complex_ptr (vt), &ldvt, 
00112                        traits::complex_ptr (work), &lwork, 
00113                        rwork, iwork, info); 
00114       }
00115 
00116 
00117       inline 
00118       int gesdd_min_work (float, char jobz, int m, int n) {
00119         int minmn = m < n ? m : n; 
00120         int maxmn = m < n ? n : m; 
00121         int m3 = 3 * minmn; 
00122         int m4 = 4 * minmn; 
00123         int minw; 
00124         if (jobz == 'N') {
00125           // leading comments:
00126           //   LWORK >= 3*min(M,N) + max(max(M,N), 6*min(M,N))
00127           // code:
00128           //   LWORK >= 3*min(M,N) + max(max(M,N), 7*min(M,N))
00129           int m7 = 7 * minmn; 
00130           minw = maxmn < m7 ? m7 : maxmn;
00131           minw += m3; 
00132         }
00133         if (jobz == 'O') {
00134           // LWORK >= 3*min(M,N)*min(M,N) 
00135           //          + max(max(M,N), 5*min(M,N)*min(M,N)+4*min(M,N))
00136           int m5 = 5 * minmn * minmn + m4; 
00137           minw = maxmn < m5 ? m5 : maxmn;
00138           minw += m3 * minmn; 
00139         }
00140         if (jobz == 'S' || jobz == 'A') {
00141           // LWORK >= 3*min(M,N)*min(M,N) 
00142           //          + max(max(M,N), 4*min(M,N)*min(M,N)+4*min(M,N)).
00143           int m44 = m4 * minmn + m4; 
00144           minw = maxmn < m44 ? m44 : maxmn;
00145           minw += m3 * minmn; 
00146         }
00147         return minw; 
00148       }
00149       inline 
00150       int gesdd_min_work (double, char jobz, int m, int n) {
00151         int minmn = m < n ? m : n; 
00152         int maxmn = m < n ? n : m; 
00153         int m3 = 3 * minmn; 
00154         int m4 = 4 * minmn; 
00155         int minw; 
00156         if (jobz == 'N') {
00157           // leading comments:
00158           //   LWORK >= 3*min(M,N) + max(max(M,N), 6*min(M,N))
00159           // code:
00160           //   LWORK >= 3*min(M,N) + max(max(M,N), 7*min(M,N))
00161           int m7 = 7 * minmn; 
00162           minw = maxmn < m7 ? m7 : maxmn;
00163           minw += m3; 
00164         }
00165         else if (jobz == 'O') {
00166           // LWORK >= 3*min(M,N)*min(M,N) 
00167           //          + max(max(M,N), 5*min(M,N)*min(M,N)+4*min(M,N))
00168           int m5 = 5 * minmn * minmn + m4; 
00169           minw = maxmn < m5 ? m5 : maxmn;
00170           minw += m3 * minmn; 
00171         }
00172         else if (jobz == 'S' || jobz == 'A') {
00173           // LWORK >= 3*min(M,N)*min(M,N) 
00174           //          + max(max(M,N), 4*min(M,N)*min(M,N)+4*min(M,N)).
00175           int m44 = m4 * minmn + m4; 
00176           minw = maxmn < m44 ? m44 : maxmn;
00177           minw += m3 * minmn; 
00178         }
00179         else {
00180           std::cerr << "Invalid option passed to gesdd" << std::endl ;  
00181           return 0 ;
00182         }
00183         return minw; 
00184       }
00185       inline 
00186       int gesdd_min_work (traits::complex_f, char jobz, int m, int n) {
00187         int minmn = m < n ? m : n; 
00188         int maxmn = m < n ? n : m; 
00189         int m2 = 2 * minmn;
00190         int minw = m2 + maxmn; 
00191         if (jobz == 'N') 
00192           // LWORK >= 2*min(M,N)+max(M,N)
00193           ; 
00194         if (jobz == 'O') 
00195           // LWORK >= 2*min(M,N)*min(M,N) + 2*min(M,N) + max(M,N)
00196           minw += m2 * minmn; 
00197         if (jobz == 'S' || jobz == 'A') 
00198           // LWORK >= min(M,N)*min(M,N) + 2*min(M,N) + max(M,N)
00199           minw += minmn * minmn; 
00200         return minw; 
00201       }
00202       inline 
00203       int gesdd_min_work (traits::complex_d, char jobz, int m, int n) {
00204         int minmn = m < n ? m : n; 
00205         int maxmn = m < n ? n : m; 
00206         int m2 = 2 * minmn;
00207         int minw = m2 + maxmn; 
00208         if (jobz == 'N') 
00209           // LWORK >= 2*min(M,N)+max(M,N)
00210           ; 
00211         if (jobz == 'O') 
00212           // LWORK >= 2*min(M,N)*min(M,N) + 2*min(M,N) + max(M,N)
00213           minw += m2 * minmn; 
00214         if (jobz == 'S' || jobz == 'A') 
00215           // LWORK >= min(M,N)*min(M,N) + 2*min(M,N) + max(M,N)
00216           minw += minmn * minmn; 
00217         return minw; 
00218       }
00219 
00220       inline 
00221       int gesdd_rwork (float, char, int, int) { return 1; }
00222       inline 
00223       int gesdd_rwork (double, char, int, int) { return 1; }
00224       inline 
00225       int gesdd_rwork (traits::complex_f, char jobz, int m, int n) {
00226         int minmn = m < n ? m : n; 
00227         int minw; 
00228         if (jobz == 'N') 
00229           // LWORK >= 7*min(M,N)
00230           minw = 7 * minmn; 
00231         else 
00232           // LRWORK >= 5*min(M,N)*min(M,N) + 5*min(M,N)
00233           minw = 5 * (minmn * minmn + minmn);
00234         return minw; 
00235       }
00236       inline 
00237       int gesdd_rwork (traits::complex_d, char jobz, int m, int n) {
00238         int minmn = m < n ? m : n; 
00239         int minw; 
00240         if (jobz == 'N') 
00241           // LWORK >= 7*min(M,N)
00242           minw = 7 * minmn; 
00243         else 
00244           // LRWORK >= 5*min(M,N)*min(M,N) + 5*min(M,N)
00245           minw = 5 * (minmn * minmn + minmn);
00246         return minw; 
00247       }
00248 
00249       inline
00250       int gesdd_iwork (int m, int n) {
00251         int minmn = m < n ? m : n; 
00252         return 8 * minmn; 
00253       }
00254 
00255     } // detail 
00256 
00257 
00258     template <typename MatrA> 
00259     inline
00260     int gesdd_work (char const q, char const jobz, MatrA const& a) 
00261     {
00262 
00263 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00264       BOOST_STATIC_ASSERT((boost::is_same<
00265         typename traits::matrix_traits<MatrA>::matrix_structure, 
00266         traits::general_t
00267       >::value)); 
00268 #endif 
00269 
00270 #ifdef BOOST_NUMERIC_BINDINGS_LAPACK_2
00271       assert (q == 'M'); 
00272 #else
00273       assert (q == 'M' || q == 'O'); 
00274 #endif 
00275       assert (jobz == 'N' || jobz == 'O' || jobz == 'A' || jobz == 'S'); 
00276 
00277       int const m = traits::matrix_size1 (a);
00278       int const n = traits::matrix_size2 (a);
00279       int lw = -13; 
00280 
00281 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00282       typedef typename traits::matrix_traits<MatrA>::value_type val_t; 
00283 #else 
00284       typedef typename MatrA::value_type val_t; 
00285 #endif 
00286 
00287       if (q == 'M') 
00288         lw = detail::gesdd_min_work (val_t(), jobz, m, n);
00289 
00290 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_2
00291       MatrA& a2 = const_cast<MatrA&> (a); 
00292       if (q == 'O') {
00293         // traits::detail::array<val_t> w (1); 
00294         val_t w; 
00295         int info; 
00296         detail::gesdd (jobz, m, n, 
00297                        traits::matrix_storage (a2), 
00298                        traits::leading_dimension (a2),
00299                        0, // traits::vector_storage (s),  
00300                        0, // traits::matrix_storage (u),
00301                        m, // traits::leading_dimension (u),
00302                        0, // traits::matrix_storage (vt),
00303                        n, // traits::leading_dimension (vt),
00304                        &w, // traits::vector_storage (w),  
00305                        -1, // traits::vector_size (w),  
00306                        0, // traits::vector_storage (rw),  
00307                        0, // traits::vector_storage (iw),  
00308                        &info);
00309         assert (info == 0); 
00310 
00311         lw = traits::detail::to_int (w);  
00312         // // lw = traits::detail::to_int (w[0]); 
00313         /*
00314          * is there a bug in LAPACK? or in Mandrake's .rpm?
00315          * if m == 3, n == 4 and jobz == 'N' (real A), 
00316          * gesdd() returns optimal size == 1 while minimum size == 27
00317          */
00318         // int lwo = traits::detail::to_int (w);  
00319         // int lwmin = detail::gesdd_min_work (val_t(), jobz, m, n);
00320         // lw = lwo < lwmin ? lwmin : lwo; 
00321       }
00322 #endif 
00323       
00324       return lw; 
00325     }
00326 
00327 
00328     template <typename MatrA> 
00329     inline
00330     int gesdd_rwork (char jobz, MatrA const& a) {
00331 
00332 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00333       BOOST_STATIC_ASSERT((boost::is_same<
00334         typename traits::matrix_traits<MatrA>::matrix_structure, 
00335         traits::general_t
00336       >::value)); 
00337 #endif 
00338 
00339       assert (jobz == 'N' || jobz == 'O' || jobz == 'A' || jobz == 'S'); 
00340 
00341 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00342       typedef typename traits::matrix_traits<MatrA>::value_type val_t; 
00343 #else 
00344       typedef typename MatrA::value_type val_t; 
00345 #endif 
00346 
00347       return detail::gesdd_rwork (val_t(), jobz, 
00348                                   traits::matrix_size1 (a),
00349                                   traits::matrix_size2 (a));
00350     }
00351 
00352 
00353     template <typename MatrA> 
00354     inline
00355     int gesdd_iwork (MatrA const& a) {
00356 
00357 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00358       BOOST_STATIC_ASSERT((boost::is_same<
00359         typename traits::matrix_traits<MatrA>::matrix_structure, 
00360         traits::general_t
00361       >::value)); 
00362 #endif 
00363 
00364       return detail::gesdd_iwork (traits::matrix_size1 (a),
00365                                   traits::matrix_size2 (a));
00366     }
00367 
00368 
00369     template <typename MatrA, typename VecS, 
00370               typename MatrU, typename MatrV, typename VecW, typename VecIW>
00371     inline
00372     int gesdd (char const jobz, MatrA& a, 
00373                VecS& s, MatrU& u, MatrV& vt, VecW& w, VecIW& iw) 
00374     {
00375 
00376 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00377       BOOST_STATIC_ASSERT((boost::is_same<
00378         typename traits::matrix_traits<MatrA>::matrix_structure, 
00379         traits::general_t
00380       >::value)); 
00381       BOOST_STATIC_ASSERT((boost::is_same<
00382         typename traits::matrix_traits<MatrU>::matrix_structure, 
00383         traits::general_t
00384       >::value)); 
00385       BOOST_STATIC_ASSERT((boost::is_same<
00386         typename traits::matrix_traits<MatrV>::matrix_structure, 
00387         traits::general_t
00388       >::value)); 
00389 
00390       BOOST_STATIC_ASSERT(
00391         (boost::is_same<
00392           typename traits::matrix_traits<MatrA>::value_type, float
00393         >::value
00394         ||
00395         boost::is_same<
00396           typename traits::matrix_traits<MatrA>::value_type, double
00397         >::value));
00398 #endif 
00399 
00400       int const m = traits::matrix_size1 (a);
00401       int const n = traits::matrix_size2 (a);
00402       int const minmn = m < n ? m : n; 
00403 
00404       assert (minmn == traits::vector_size (s)); 
00405       assert ((jobz == 'N')
00406               || ((jobz == 'O' || jobz == 'A') && m >= n)
00407               || ((jobz == 'O' || jobz == 'A') 
00408                   && m < n 
00409                   && m == traits::matrix_size2 (u))
00410               || (jobz == 'S' && minmn == traits::matrix_size2 (u))); 
00411       assert ((jobz == 'N' && traits::leading_dimension (u) >= 1)
00412               || (jobz == 'O' 
00413                   && m >= n
00414                   && traits::leading_dimension (u) >= 1)
00415               || (jobz == 'O' 
00416                   && m < n
00417                   && traits::leading_dimension (u) >= m)
00418               || (jobz == 'A' && traits::leading_dimension (u) >= m)
00419               || (jobz == 'S' && traits::leading_dimension (u) >= m));
00420       assert (n == traits::matrix_size2 (vt)); 
00421       assert ((jobz == 'N' && traits::leading_dimension (vt) >= 1)
00422               || (jobz == 'O' 
00423                   && m < n
00424                   && traits::leading_dimension (vt) >= 1)
00425               || (jobz == 'O' 
00426                   && m >= n
00427                   && traits::leading_dimension (vt) >= n)
00428               || (jobz == 'A' && traits::leading_dimension (vt) >= n)
00429               || (jobz == 'S' && traits::leading_dimension (vt) >= minmn));
00430 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00431       typedef typename traits::matrix_traits<MatrA>::value_type val_t; 
00432 #else 
00433       typedef typename MatrA::value_type val_t; 
00434 #endif 
00435       assert (traits::vector_size (w) 
00436               >= detail::gesdd_min_work (val_t(), jobz, m, n)); 
00437       assert (traits::vector_size (iw) >= detail::gesdd_iwork (m, n)); 
00438 
00439       int info; 
00440       detail::gesdd (jobz, m, n, 
00441                      traits::matrix_storage (a), 
00442                      traits::leading_dimension (a),
00443                      traits::vector_storage (s),  
00444                      traits::matrix_storage (u),
00445                      traits::leading_dimension (u),
00446                      traits::matrix_storage (vt),
00447                      traits::leading_dimension (vt),
00448                      traits::vector_storage (w),  
00449                      traits::vector_size (w),  
00450                      0, // dummy argument 
00451                      traits::vector_storage (iw),  
00452                      &info);
00453       return info; 
00454     }
00455 
00456 
00457     template <typename MatrA, typename VecS, typename MatrU, 
00458               typename MatrV, typename VecW, typename VecRW, typename VecIW>
00459     inline
00460     int gesdd (char const jobz, MatrA& a, 
00461                VecS& s, MatrU& u, MatrV& vt, VecW& w, VecRW& rw, VecIW& iw) 
00462     {
00463 
00464 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00465       BOOST_STATIC_ASSERT((boost::is_same<
00466         typename traits::matrix_traits<MatrA>::matrix_structure, 
00467         traits::general_t
00468       >::value)); 
00469       BOOST_STATIC_ASSERT((boost::is_same<
00470         typename traits::matrix_traits<MatrU>::matrix_structure, 
00471         traits::general_t
00472       >::value)); 
00473       BOOST_STATIC_ASSERT((boost::is_same<
00474         typename traits::matrix_traits<MatrV>::matrix_structure, 
00475         traits::general_t
00476       >::value)); 
00477 #endif 
00478 
00479       int const m = traits::matrix_size1 (a);
00480       int const n = traits::matrix_size2 (a);
00481       int const minmn = m < n ? m : n; 
00482 
00483       assert (minmn == traits::vector_size (s)); 
00484       assert ((jobz == 'N')
00485               || ((jobz == 'O' || jobz == 'A') && m >= n)
00486               || ((jobz == 'O' || jobz == 'A') 
00487                   && m < n 
00488                   && m == traits::matrix_size2 (u))
00489               || (jobz == 'S' && minmn == traits::matrix_size2 (u))); 
00490       assert ((jobz == 'N' && traits::leading_dimension (u) >= 1)
00491               || (jobz == 'O' 
00492                   && m >= n
00493                   && traits::leading_dimension (u) >= 1)
00494               || (jobz == 'O' 
00495                   && m < n
00496                   && traits::leading_dimension (u) >= m)
00497               || (jobz == 'A' && traits::leading_dimension (u) >= m)
00498               || (jobz == 'S' && traits::leading_dimension (u) >= m));
00499       assert (n == traits::matrix_size2 (vt)); 
00500       assert ((jobz == 'N' && traits::leading_dimension (vt) >= 1)
00501               || (jobz == 'O' 
00502                   && m < n
00503                   && traits::leading_dimension (vt) >= 1)
00504               || (jobz == 'O' 
00505                   && m >= n
00506                   && traits::leading_dimension (vt) >= n)
00507               || (jobz == 'A' && traits::leading_dimension (vt) >= n)
00508               || (jobz == 'S' && traits::leading_dimension (vt) >= minmn));
00509 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00510       typedef typename traits::matrix_traits<MatrA>::value_type val_t; 
00511 #else 
00512       typedef typename MatrA::value_type val_t; 
00513 #endif 
00514       assert (traits::vector_size (w) 
00515               >= detail::gesdd_min_work (val_t(), jobz, m, n)); 
00516       assert (traits::vector_size (rw) 
00517               >= detail::gesdd_rwork (val_t(), jobz, m, n));
00518       assert (traits::vector_size (iw) >= detail::gesdd_iwork (m, n)); 
00519 
00520       int info; 
00521       detail::gesdd (jobz, m, n, 
00522                      traits::matrix_storage (a), 
00523                      traits::leading_dimension (a),
00524                      traits::vector_storage (s),  
00525                      traits::matrix_storage (u),
00526                      traits::leading_dimension (u),
00527                      traits::matrix_storage (vt),
00528                      traits::leading_dimension (vt),
00529                      traits::vector_storage (w),  
00530                      traits::vector_size (w),  
00531                      traits::vector_storage (rw),  
00532                      traits::vector_storage (iw),  
00533                      &info);
00534       return info; 
00535     }
00536 
00537 
00538     template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
00539     inline
00540     int gesdd (char const opt, char const jobz, 
00541                MatrA& a, VecS& s, MatrU& u, MatrV& vt) 
00542     {
00543 
00544 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00545       BOOST_STATIC_ASSERT((boost::is_same<
00546         typename traits::matrix_traits<MatrA>::matrix_structure, 
00547         traits::general_t
00548       >::value)); 
00549       BOOST_STATIC_ASSERT((boost::is_same<
00550         typename traits::matrix_traits<MatrU>::matrix_structure, 
00551         traits::general_t
00552       >::value)); 
00553       BOOST_STATIC_ASSERT((boost::is_same<
00554         typename traits::matrix_traits<MatrV>::matrix_structure, 
00555         traits::general_t
00556       >::value)); 
00557 #endif 
00558 
00559       int const m = traits::matrix_size1 (a);
00560       int const n = traits::matrix_size2 (a);
00561 #ifndef NDEBUG
00562       int const minmn = m < n ? m : n; 
00563 #endif // NDEBUG
00564 
00565       assert (minmn == traits::vector_size (s)); 
00566       assert ((jobz == 'N')
00567               || ((jobz == 'O' || jobz == 'A') && m >= n)
00568               || ((jobz == 'O' || jobz == 'A') 
00569                   && m < n 
00570                   && m == traits::matrix_size2 (u))
00571               || (jobz == 'S' && minmn == traits::matrix_size2 (u))); 
00572       assert ((jobz == 'N' && traits::leading_dimension (u) >= 1)
00573               || (jobz == 'O' 
00574                   && m >= n
00575                   && traits::leading_dimension (u) >= 1)
00576               || (jobz == 'O' 
00577                   && m < n
00578                   && traits::leading_dimension (u) >= m)
00579               || (jobz == 'A' && traits::leading_dimension (u) >= m)
00580               || (jobz == 'S' && traits::leading_dimension (u) >= m));
00581       assert (n == traits::matrix_size2 (vt)); 
00582       assert ((jobz == 'N' && traits::leading_dimension (vt) >= 1)
00583               || (jobz == 'O' 
00584                   && m < n
00585                   && traits::leading_dimension (vt) >= 1)
00586               || (jobz == 'O' 
00587                   && m >= n
00588                   && traits::leading_dimension (vt) >= n)
00589               || (jobz == 'A' && traits::leading_dimension (vt) >= n)
00590               || (jobz == 'S' && traits::leading_dimension (vt) >= minmn));
00591 
00592 #ifdef BOOST_NUMERIC_BINDINGS_LAPACK_2
00593       assert (opt == 'M'); 
00594 #else
00595       assert (opt == 'M' || opt == 'O'); 
00596 #endif 
00597 
00598 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00599       typedef typename traits::matrix_traits<MatrA>::value_type val_t; 
00600 #else 
00601       typedef typename MatrA::value_type val_t; 
00602 #endif 
00603       typedef typename traits::type_traits<val_t>::real_type real_t;
00604 
00605       int const lw = gesdd_work (opt, jobz, a); 
00606       traits::detail::array<val_t> w (lw); 
00607       if (!w.valid()) return -101; 
00608 
00609       int const lrw = gesdd_rwork (jobz, a); 
00610       traits::detail::array<real_t> rw (lrw); 
00611       if (!rw.valid()) return -102; 
00612 
00613       int const liw = gesdd_iwork (a); 
00614       traits::detail::array<int> iw (liw); 
00615       if (!iw.valid()) return -103; 
00616 
00617       int info; 
00618       detail::gesdd (jobz, m, n, 
00619                      traits::matrix_storage (a), 
00620                      traits::leading_dimension (a),
00621                      traits::vector_storage (s),  
00622                      traits::matrix_storage (u),
00623                      traits::leading_dimension (u),
00624                      traits::matrix_storage (vt),
00625                      traits::leading_dimension (vt),
00626                      traits::vector_storage (w),  
00627                      lw, //traits::vector_size (w),  
00628                      traits::vector_storage (rw),  
00629                      traits::vector_storage (iw),  
00630                      &info);
00631       return info; 
00632     }
00633 
00634 
00635 #ifndef BOOST_NUMERIC_BINDINGS_LAPACK_2
00636 
00637     template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
00638     inline
00639     int gesdd (char const jobz, MatrA& a, VecS& s, MatrU& u, MatrV& vt) {
00640       return gesdd ('O', jobz, a, s, u, vt); 
00641     }
00642 
00643     template <typename MatrA, typename VecS, typename MatrU, typename MatrV>
00644     inline
00645     int gesdd (MatrA& a, VecS& s, MatrU& u, MatrV& vt) {
00646       return gesdd ('O', 'S', a, s, u, vt); 
00647     }
00648 
00649     template <typename MatrA, typename VecS> 
00650     inline
00651     int gesdd (MatrA& a, VecS& s) {
00652 
00653 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
00654       BOOST_STATIC_ASSERT((boost::is_same<
00655         typename traits::matrix_traits<MatrA>::matrix_structure, 
00656         traits::general_t
00657       >::value)); 
00658 #endif 
00659 
00660       int const m = traits::matrix_size1 (a);
00661       int const n = traits::matrix_size2 (a);
00662       int const minmn = m < n ? m : n; 
00663 
00664       assert (minmn == traits::vector_size (s)); 
00665 
00666 #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
00667       typedef typename traits::matrix_traits<MatrA>::value_type val_t; 
00668 #else 
00669       typedef typename MatrA::value_type val_t; 
00670 #endif 
00671       typedef typename traits::type_traits<val_t>::real_type real_t;
00672 
00673       int const lw = gesdd_work ('O', 'N', a); 
00674       traits::detail::array<val_t> w (lw); 
00675       if (!w.valid()) return -101; 
00676 
00677       int const lrw = gesdd_rwork ('N', a); 
00678       traits::detail::array<real_t> rw (lrw); 
00679       if (!rw.valid()) return -102; 
00680 
00681       int const liw = gesdd_iwork (a); 
00682       traits::detail::array<int> iw (liw); 
00683       if (!iw.valid()) return -103; 
00684 
00685       int info; 
00686       detail::gesdd ('N', m, n, 
00687                      traits::matrix_storage (a), 
00688                      traits::leading_dimension (a),
00689                      traits::vector_storage (s),  
00690                      0, // traits::matrix_storage (u),
00691                      1, // traits::leading_dimension (u),
00692                      0, // traits::matrix_storage (vt),
00693                      1, // traits::leading_dimension (vt),
00694                      traits::vector_storage (w),  
00695                      traits::vector_size (w),  
00696                      traits::vector_storage (rw),  
00697                      traits::vector_storage (iw),  
00698                      &info);
00699       return info; 
00700     }
00701 
00702 #endif 
00703 
00704   } // namespace lapack
00705 
00706 }}}
00707 
00708 #endif 

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