00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00037
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
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* ,
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* ,
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
00126
00127
00128
00129 int m7 = 7 * minmn;
00130 minw = maxmn < m7 ? m7 : maxmn;
00131 minw += m3;
00132 }
00133 if (jobz == 'O') {
00134
00135
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
00142
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
00158
00159
00160
00161 int m7 = 7 * minmn;
00162 minw = maxmn < m7 ? m7 : maxmn;
00163 minw += m3;
00164 }
00165 else if (jobz == 'O') {
00166
00167
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
00174
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
00193 ;
00194 if (jobz == 'O')
00195
00196 minw += m2 * minmn;
00197 if (jobz == 'S' || jobz == 'A')
00198
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
00210 ;
00211 if (jobz == 'O')
00212
00213 minw += m2 * minmn;
00214 if (jobz == 'S' || jobz == 'A')
00215
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
00230 minw = 7 * minmn;
00231 else
00232
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
00242 minw = 7 * minmn;
00243 else
00244
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 }
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
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,
00300 0,
00301 m,
00302 0,
00303 n,
00304 &w,
00305 -1,
00306 0,
00307 0,
00308 &info);
00309 assert (info == 0);
00310
00311 lw = traits::detail::to_int (w);
00312
00313
00314
00315
00316
00317
00318
00319
00320
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,
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,
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,
00691 1,
00692 0,
00693 1,
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 }
00705
00706 }}}
00707
00708 #endif