35#ifndef _BLAZE_MATH_LAPACK_GESVDX_H_
36#define _BLAZE_MATH_LAPACK_GESVDX_H_
79template<
typename MT,
bool SO,
typename VT,
bool TF >
80size_t gesvdx( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s );
82template<
typename MT,
bool SO,
typename VT,
bool TF,
typename ST >
83size_t gesvdx( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s, ST low, ST upp );
85template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF >
86size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s );
88template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename ST >
89size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
90 DenseVector<VT,TF>& s, ST low, ST upp );
92template<
typename MT1,
bool SO,
typename VT,
bool TF,
typename MT2 >
93size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s, DenseMatrix<MT2,SO>& V );
95template<
typename MT1,
bool SO,
typename VT,
bool TF,
typename MT2,
typename ST >
96size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s,
97 DenseMatrix<MT2,SO>& V, ST low, ST upp );
99template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename MT3 >
100size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
101 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V );
103template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename MT3,
typename ST >
104size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
105 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V, ST low, ST upp );
137inline auto gesvdx_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
139 -> DisableIf_t< IsComplex_v< ElementType_t<MT> >,
size_t >
141 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
142 BLAZE_INTERNAL_ASSERT( range !=
'A' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
143 BLAZE_INTERNAL_ASSERT( range !=
'V' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
144 BLAZE_INTERNAL_ASSERT( range !=
'I' || (*s).size() ==
size_t( iu-il+1 ),
"Invalid vector dimension detected" );
148 using ET = ElementType_t<MT>;
150 const size_t M( (*A).rows() );
151 const size_t N( (*A).columns() );
152 const size_t mindim(
min( M, N ) );
154 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
155 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
156 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
160 ET* sptr( (*s).data() );
161 std::unique_ptr<ET[]> stmp;
163 const bool tmpRequired( (*s).size() < mindim );
166 stmp.reset(
new ET[2UL*mindim] );
172 blas_int_t lwork( minimum*( minimum*3 + 20 ) + 2 );
173 const std::unique_ptr<ET[]> work (
new ET[lwork] );
174 const std::unique_ptr<blas_int_t[]> iwork(
new blas_int_t[12*minimum] );
176 gesvdx(
'N',
'N', range, m, n, (*A).data(), lda, vl, vu, il, iu, &ns, sptr,
177 nullptr, 1,
nullptr, 1, work.get(), lwork, iwork.get(), &info );
179 const size_t num( numeric_cast<size_t>( ns ) );
189 for(
size_t i=0UL; i<(*s).size(); ++i ) {
227inline auto gesvdx_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
229 -> EnableIf_t< IsComplex_v< ElementType_t<MT> >,
size_t >
231 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
232 BLAZE_INTERNAL_ASSERT( range !=
'A' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
233 BLAZE_INTERNAL_ASSERT( range !=
'V' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
234 BLAZE_INTERNAL_ASSERT( range !=
'I' || (*s).size() ==
size_t( iu-il+1 ),
"Invalid vector dimension detected" );
238 using CT = ElementType_t<MT>;
239 using BT = UnderlyingElement_t<CT>;
241 const size_t M( (*A).rows() );
242 const size_t N( (*A).columns() );
243 const size_t mindim(
min( M, N ) );
245 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
246 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
247 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
251 BT* sptr( (*s).data() );
252 std::unique_ptr<BT[]> stmp;
254 const bool tmpRequired( (*s).size() < mindim );
257 stmp.reset(
new BT[2UL*mindim] );
263 blas_int_t lwork( minimum*( minimum*3 + 20 ) + 2 );
264 const std::unique_ptr<CT[]> work (
new CT[lwork] );
265 const std::unique_ptr<BT[]> rwork(
new BT[17*minimum*minimum] );
266 const std::unique_ptr<blas_int_t[]> iwork(
new blas_int_t[12*minimum] );
268 gesvdx(
'N',
'N', range, m, n, (*A).data(), lda, vl, vu, il, iu, &ns, sptr,
269 nullptr, 1,
nullptr, 1, work.get(), lwork, rwork.get(), iwork.get(), &info );
271 const size_t num( numeric_cast<size_t>( ns ) );
281 for(
size_t i=0UL; i<(*s).size(); ++i ) {
364 const size_t M( (*A).rows() );
365 const size_t N( (*A).columns() );
366 const size_t mindim(
min( M, N ) );
368 resize( *s, mindim,
false );
370 if( M == 0UL || N == 0UL ) {
374 return gesvdx_backend( *A, *s,
'A', UT(), UT(), 0, 0 );
480 if( IsFloatingPoint_v<ST> && low >= upp ) {
484 if( !IsFloatingPoint_v<ST> && low > upp ) {
488 const size_t M( (*A).rows() );
489 const size_t N( (*A).columns() );
490 const size_t mindim(
min( M, N ) );
491 const size_t expected( IsFloatingPoint_v<ST> ? mindim :
size_t( upp - low ) + 1UL );
493 if( !IsFloatingPoint_v<ST> && expected > mindim ) {
497 resize( *s, expected,
false );
499 if( M == 0UL || N == 0UL ) {
503 const char range( IsFloatingPoint_v<ST> ?
'V' :
'I' );
504 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
505 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
506 const blas_int_t il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( low ) );
507 const blas_int_t iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( upp ) );
509 const size_t actual( gesvdx_backend( *A, *s, range, vl, vu, il, iu ) );
511 if( IsResizable_v<VT> ) {
512 resize( *s, actual,
true );
543template<
typename MT1
549inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s,
551 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
553 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
554 BLAZE_INTERNAL_ASSERT( range !=
'A' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
555 BLAZE_INTERNAL_ASSERT( range !=
'V' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
556 BLAZE_INTERNAL_ASSERT( range !=
'I' || (*s).size() ==
size_t( iu-il+1 ),
"Invalid vector dimension detected" );
562 using ET = ElementType_t<MT1>;
564 const size_t M( (*A).rows() );
565 const size_t N( (*A).columns() );
566 const size_t mindim(
min( M, N ) );
568 blas_int_t m ( numeric_cast<blas_int_t>( SO ? M : N ) );
569 blas_int_t n ( numeric_cast<blas_int_t>( SO ? N : M ) );
570 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
571 blas_int_t ldu ( numeric_cast<blas_int_t>( (*U).spacing() ) );
575 ET* sptr( (*s).data() );
576 ET* uptr( (*U).data() );
577 std::unique_ptr<ET[]> stmp;
578 std::unique_ptr<ET[]> utmp;
580 const bool tmpRequired( (*s).size() < mindim );
583 stmp.reset(
new ET[2UL*mindim] );
584 utmp.reset(
new ET[M*mindim] );
591 blas_int_t lwork( minimum*( minimum*3 + 20 ) + 2 );
592 const std::unique_ptr<ET[]> work (
new ET[lwork] );
593 const std::unique_ptr<blas_int_t[]> iwork(
new blas_int_t[12*minimum] );
595 gesvdx( ( SO ?
'V' :
'N' ), ( SO ?
'N' :
'V' ), range, m, n,
596 (*A).data(), lda, vl, vu, il, iu, &ns, sptr,
597 ( SO ? uptr :
nullptr ), ( tmpRequired ? m : ( SO ? ldu : 1 ) ),
598 ( SO ?
nullptr : uptr ), ( tmpRequired ? mindim : ( SO ? 1 : ldu ) ),
599 work.get(), lwork, iwork.get(), &info );
601 const size_t num( numeric_cast<size_t>( ns ) );
612 for(
size_t i=0UL; i<(*s).size(); ++i ) {
618 for(
size_t j=0UL; j<(*U).columns(); ++j ) {
619 for(
size_t i=0UL; i<(*U).rows(); ++i ) {
620 (*U)(i,j) = utmp[i+j*M];
626 for(
size_t i=0UL; i<(*U).rows(); ++i ) {
627 for(
size_t j=0UL; j<(*U).columns(); ++j ) {
628 (*U)(i,j) = utmp[i*mindim+j];
663template<
typename MT1
669inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s,
671 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
673 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
674 BLAZE_INTERNAL_ASSERT( range !=
'A' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
675 BLAZE_INTERNAL_ASSERT( range !=
'V' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
676 BLAZE_INTERNAL_ASSERT( range !=
'I' || (*s).size() ==
size_t( iu-il+1 ),
"Invalid vector dimension detected" );
682 using CT = ElementType_t<MT1>;
683 using BT = UnderlyingElement_t<CT>;
685 const size_t M( (*A).rows() );
686 const size_t N( (*A).columns() );
687 const size_t mindim(
min( M, N ) );
689 blas_int_t m ( numeric_cast<blas_int_t>( SO ? M : N ) );
690 blas_int_t n ( numeric_cast<blas_int_t>( SO ? N : M ) );
691 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
692 blas_int_t ldu ( numeric_cast<blas_int_t>( (*U).spacing() ) );
696 BT* sptr( (*s).data() );
697 CT* uptr( (*U).data() );
698 std::unique_ptr<BT[]> stmp;
699 std::unique_ptr<CT[]> utmp;
701 const bool tmpRequired( (*s).size() < mindim );
704 stmp.reset(
new BT[2UL*mindim] );
705 utmp.reset(
new CT[M*mindim] );
712 blas_int_t lwork( minimum*( minimum*3 + 20 ) + 2 );
713 const std::unique_ptr<CT[]> work (
new CT[lwork] );
714 const std::unique_ptr<BT[]> rwork(
new BT[17*minimum*minimum] );
715 const std::unique_ptr<blas_int_t[]> iwork(
new blas_int_t[12*minimum] );
717 gesvdx( ( SO ?
'V' :
'N' ), ( SO ?
'N' :
'V' ), range, m, n,
718 (*A).data(), lda, vl, vu, il, iu, &ns, sptr,
719 ( SO ? uptr :
nullptr ), ( tmpRequired ? m : ( SO ? ldu : 1 ) ),
720 ( SO ?
nullptr : uptr ), ( tmpRequired ? mindim : ( SO ? 1 : ldu ) ),
721 work.get(), lwork, rwork.get(), iwork.get(), &info );
723 const size_t num( numeric_cast<size_t>( ns ) );
734 for(
size_t i=0UL; i<(*s).size(); ++i ) {
740 for(
size_t j=0UL; j<(*U).columns(); ++j ) {
741 for(
size_t i=0UL; i<(*U).rows(); ++i ) {
742 (*U)(i,j) = utmp[i+j*M];
748 for(
size_t i=0UL; i<(*U).rows(); ++i ) {
749 for(
size_t j=0UL; j<(*U).columns(); ++j ) {
750 (*U)(i,j) = utmp[i*mindim+j];
819template<
typename MT1
846 const size_t M( (*A).rows() );
847 const size_t N( (*A).columns() );
848 const size_t mindim(
min( M, N ) );
850 resize( *s, mindim,
false );
851 resize( *U, M, mindim,
false );
853 if( M == 0UL || N == 0UL ) {
857 return gesvdx_backend( *A, *U, *s,
'A', UT(), UT(), 0, 0 );
952template<
typename MT1
980 if( IsFloatingPoint_v<ST> && low >= upp ) {
984 if( !IsFloatingPoint_v<ST> && low > upp ) {
988 const size_t M( (*A).rows() );
989 const size_t N( (*A).columns() );
990 const size_t mindim(
min( M, N ) );
991 const size_t expected( IsFloatingPoint_v<ST> ? mindim :
size_t( upp - low ) + 1UL );
993 if( !IsFloatingPoint_v<ST> && expected > mindim ) {
997 resize( *s, expected,
false );
998 resize( *U, M, expected,
false );
1000 if( M == 0UL || N == 0UL ) {
1004 const char range( IsFloatingPoint_v<ST> ?
'V' :
'I' );
1005 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
1006 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
1007 const blas_int_t il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( low ) );
1008 const blas_int_t iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( upp ) );
1010 const size_t actual( gesvdx_backend( *A, *U, *s, range, vl, vu, il, iu ) );
1012 if( IsResizable_v<VT> ) {
1013 resize( *s, actual,
true );
1016 if( IsResizable_v<MT2> ) {
1017 resize( *U, M, actual,
true );
1048template<
typename MT1
1054inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s, DenseMatrix<MT2,SO>& V,
1056 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
1058 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
1059 BLAZE_INTERNAL_ASSERT( range !=
'A' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
1060 BLAZE_INTERNAL_ASSERT( range !=
'V' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
1061 BLAZE_INTERNAL_ASSERT( range !=
'I' || (*s).size() ==
size_t( iu-il+1 ),
"Invalid vector dimension detected" );
1067 using ET = ElementType_t<MT1>;
1069 const size_t M( (*A).rows() );
1070 const size_t N( (*A).columns() );
1071 const size_t mindim(
min( M, N ) );
1073 blas_int_t m ( numeric_cast<blas_int_t>( SO ? M : N ) );
1074 blas_int_t n ( numeric_cast<blas_int_t>( SO ? N : M ) );
1075 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
1076 blas_int_t ldv ( numeric_cast<blas_int_t>( (*V).spacing() ) );
1080 ET* sptr( (*s).data() );
1081 ET* vptr( (*V).data() );
1082 std::unique_ptr<ET[]> stmp;
1083 std::unique_ptr<ET[]> vtmp;
1085 const bool tmpRequired( (*s).size() < mindim );
1088 stmp.reset(
new ET[2UL*mindim] );
1089 vtmp.reset(
new ET[mindim*N] );
1096 blas_int_t lwork( minimum*( minimum*3 + 20 ) + 2 );
1097 const std::unique_ptr<ET[]> work (
new ET[lwork] );
1098 const std::unique_ptr<blas_int_t[]> iwork(
new blas_int_t[12*minimum] );
1100 gesvdx( ( SO ?
'N' :
'V' ), ( SO ?
'V' :
'N' ), range, m, n,
1101 (*A).data(), lda, vl, vu, il, iu, &ns, sptr,
1102 ( SO ?
nullptr : vptr ), ( tmpRequired ? m : ( SO ? 1 : ldv ) ),
1103 ( SO ? vptr :
nullptr ), ( tmpRequired ? mindim : ( SO ? ldv : 1 ) ),
1104 work.get(), lwork, iwork.get(), &info );
1106 const size_t num( numeric_cast<size_t>( ns ) );
1117 for(
size_t i=0UL; i<(*s).size(); ++i ) {
1123 for(
size_t j=0UL; j<(*V).columns(); ++j ) {
1124 for(
size_t i=0UL; i<(*V).rows(); ++i ) {
1125 (*V)(i,j) = vtmp[i+j*mindim];
1131 for(
size_t i=0UL; i<(*V).rows(); ++i ) {
1132 for(
size_t j=0UL; j<(*V).columns(); ++j ) {
1133 (*V)(i,j) = vtmp[i*N+j];
1168template<
typename MT1
1174inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s, DenseMatrix<MT2,SO>& V,
1176 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
1178 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
1179 BLAZE_INTERNAL_ASSERT( range !=
'A' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
1180 BLAZE_INTERNAL_ASSERT( range !=
'V' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
1181 BLAZE_INTERNAL_ASSERT( range !=
'I' || (*s).size() ==
size_t( iu-il+1 ),
"Invalid vector dimension detected" );
1187 using CT = ElementType_t<MT1>;
1188 using BT = UnderlyingElement_t<CT>;
1190 const size_t M( (*A).rows() );
1191 const size_t N( (*A).columns() );
1192 const size_t mindim(
min( M, N ) );
1194 blas_int_t m ( numeric_cast<blas_int_t>( SO ? M : N ) );
1195 blas_int_t n ( numeric_cast<blas_int_t>( SO ? N : M ) );
1196 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
1197 blas_int_t ldv ( numeric_cast<blas_int_t>( (*V).spacing() ) );
1201 BT* sptr( (*s).data() );
1202 CT* vptr( (*V).data() );
1203 std::unique_ptr<BT[]> stmp;
1204 std::unique_ptr<CT[]> vtmp;
1206 const bool tmpRequired( (*s).size() < mindim );
1209 stmp.reset(
new BT[2UL*mindim] );
1210 vtmp.reset(
new CT[mindim*N] );
1217 blas_int_t lwork( minimum*( minimum*3 + 20 ) + 2 );
1218 const std::unique_ptr<CT[]> work (
new CT[lwork] );
1219 const std::unique_ptr<BT[]> rwork(
new BT[17*minimum*minimum] );
1220 const std::unique_ptr<blas_int_t[]> iwork(
new blas_int_t[12*minimum] );
1222 gesvdx( ( SO ?
'N' :
'V' ), ( SO ?
'V' :
'N' ), range, m, n,
1223 (*A).data(), lda, vl, vu, il, iu, &ns, sptr,
1224 ( SO ?
nullptr : vptr ), ( tmpRequired ? m : ( SO ? 1 : ldv ) ),
1225 ( SO ? vptr :
nullptr ), ( tmpRequired ? mindim : ( SO ? ldv : 1 ) ),
1226 work.get(), lwork, rwork.get(), iwork.get(), &info );
1228 const size_t num( numeric_cast<size_t>( ns ) );
1239 for(
size_t i=0UL; i<(*s).size(); ++i ) {
1245 for(
size_t j=0UL; j<(*V).columns(); ++j ) {
1246 for(
size_t i=0UL; i<(*V).rows(); ++i ) {
1247 (*V)(i,j) = vtmp[i+j*mindim];
1253 for(
size_t i=0UL; i<(*V).rows(); ++i ) {
1254 for(
size_t j=0UL; j<(*V).columns(); ++j ) {
1255 (*V)(i,j) = vtmp[i*N+j];
1324template<
typename MT1
1351 const size_t M( (*A).rows() );
1352 const size_t N( (*A).columns() );
1353 const size_t mindim(
min( M, N ) );
1355 resize( *s, mindim,
false );
1356 resize( *V, mindim, N,
false );
1358 if( M == 0UL || N == 0UL ) {
1362 return gesvdx_backend( *A, *s, *V,
'A', UT(), UT(), 0, 0 );
1457template<
typename MT1
1485 if( IsFloatingPoint_v<ST> && low >= upp ) {
1489 if( !IsFloatingPoint_v<ST> && low > upp ) {
1493 const size_t M( (*A).rows() );
1494 const size_t N( (*A).columns() );
1495 const size_t mindim(
min( M, N ) );
1496 const size_t expected( IsFloatingPoint_v<ST> ? mindim :
size_t( upp - low ) + 1UL );
1498 if( !IsFloatingPoint_v<ST> && expected > mindim ) {
1502 resize( *s, expected,
false );
1503 resize( *V, expected, N,
false );
1505 if( M == 0UL || N == 0UL ) {
1509 const char range( IsFloatingPoint_v<ST> ?
'V' :
'I' );
1510 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
1511 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
1512 const blas_int_t il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( low ) );
1513 const blas_int_t iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( upp ) );
1515 const size_t actual( gesvdx_backend( *A, *s, *V, range, vl, vu, il, iu ) );
1517 if( IsResizable_v<VT> ) {
1518 resize( *s, actual,
true );
1521 if( IsResizable_v<MT2> ) {
1522 resize( *V, actual, N,
true );
1554template<
typename MT1
1561inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s,
1562 DenseMatrix<MT3,SO>& V,
char range, ST vl, ST vu,
1564 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
1566 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
1567 BLAZE_INTERNAL_ASSERT( range !=
'A' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
1568 BLAZE_INTERNAL_ASSERT( range !=
'V' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
1569 BLAZE_INTERNAL_ASSERT( range !=
'I' || (*s).size() ==
size_t( iu-il+1 ),
"Invalid vector dimension detected" );
1577 using ET = ElementType_t<MT1>;
1579 const size_t M( (*A).rows() );
1580 const size_t N( (*A).columns() );
1581 const size_t mindim(
min( M, N ) );
1583 blas_int_t m ( numeric_cast<blas_int_t>( SO ? M : N ) );
1584 blas_int_t n ( numeric_cast<blas_int_t>( SO ? N : M ) );
1585 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
1586 blas_int_t ldu ( numeric_cast<blas_int_t>( (*U).spacing() ) );
1587 blas_int_t ldv ( numeric_cast<blas_int_t>( (*V).spacing() ) );
1591 ET* sptr( (*s).data() );
1592 ET* uptr( (*U).data() );
1593 ET* vptr( (*V).data() );
1594 std::unique_ptr<ET[]> stmp;
1595 std::unique_ptr<ET[]> utmp;
1596 std::unique_ptr<ET[]> vtmp;
1598 const bool tmpRequired( (*s).size() < mindim );
1601 stmp.reset(
new ET[2UL*mindim] );
1602 utmp.reset(
new ET[M*mindim] );
1603 vtmp.reset(
new ET[mindim*N] );
1611 blas_int_t lwork( minimum*( minimum*3 + 20 ) + 2 );
1612 const std::unique_ptr<ET[]> work (
new ET[lwork] );
1613 const std::unique_ptr<blas_int_t[]> iwork(
new blas_int_t[12*minimum] );
1615 gesvdx(
'V',
'V', range, m, n, (*A).data(), lda, vl, vu, il, iu, &ns, sptr,
1616 ( SO ? uptr : vptr ), ( tmpRequired ? m : ( SO ? ldu : ldv ) ),
1617 ( SO ? vptr : uptr ), ( tmpRequired ? mindim : ( SO ? ldv : ldu ) ),
1618 work.get(), lwork, iwork.get(), &info );
1620 const size_t num( numeric_cast<size_t>( ns ) );
1631 for(
size_t i=0UL; i<(*s).size(); ++i ) {
1637 for(
size_t j=0UL; j<(*U).columns(); ++j ) {
1638 for(
size_t i=0UL; i<(*U).rows(); ++i ) {
1639 (*U)(i,j) = utmp[i+j*M];
1643 for(
size_t j=0UL; j<(*V).columns(); ++j ) {
1644 for(
size_t i=0UL; i<(*V).rows(); ++i ) {
1645 (*V)(i,j) = vtmp[i+j*mindim];
1651 for(
size_t i=0UL; i<(*U).rows(); ++i ) {
1652 for(
size_t j=0UL; j<(*U).columns(); ++j ) {
1653 (*U)(i,j) = utmp[i*mindim+j];
1657 for(
size_t i=0UL; i<(*V).rows(); ++i ) {
1658 for(
size_t j=0UL; j<(*V).columns(); ++j ) {
1659 (*V)(i,j) = vtmp[i*N+j];
1695template<
typename MT1
1702inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s,
1703 DenseMatrix<MT3,SO>& V,
char range, ST vl, ST vu,
1705 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
1707 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
1708 BLAZE_INTERNAL_ASSERT( range !=
'A' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
1709 BLAZE_INTERNAL_ASSERT( range !=
'V' || (*s).size() ==
min( (*A).rows(), (*A).columns() ),
"Invalid vector dimension detected" );
1710 BLAZE_INTERNAL_ASSERT( range !=
'I' || (*s).size() ==
size_t( iu-il+1 ),
"Invalid vector dimension detected" );
1718 using CT = ElementType_t<MT1>;
1719 using BT = UnderlyingElement_t<CT>;
1721 const size_t M( (*A).rows() );
1722 const size_t N( (*A).columns() );
1723 const size_t mindim(
min( M, N ) );
1725 blas_int_t m ( numeric_cast<blas_int_t>( SO ? M : N ) );
1726 blas_int_t n ( numeric_cast<blas_int_t>( SO ? N : M ) );
1727 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
1728 blas_int_t ldu ( numeric_cast<blas_int_t>( (*U).spacing() ) );
1729 blas_int_t ldv ( numeric_cast<blas_int_t>( (*V).spacing() ) );
1733 BT* sptr( (*s).data() );
1734 CT* uptr( (*U).data() );
1735 CT* vptr( (*V).data() );
1736 std::unique_ptr<BT[]> stmp;
1737 std::unique_ptr<CT[]> utmp;
1738 std::unique_ptr<CT[]> vtmp;
1740 const bool tmpRequired( (*s).size() < mindim );
1743 stmp.reset(
new BT[2UL*mindim] );
1744 utmp.reset(
new CT[M*mindim] );
1745 vtmp.reset(
new CT[mindim*N] );
1753 blas_int_t lwork( minimum*( minimum*3 + 20 ) + 2 );
1754 const std::unique_ptr<CT[]> work (
new CT[lwork] );
1755 const std::unique_ptr<BT[]> rwork(
new BT[17*minimum*minimum] );
1756 const std::unique_ptr<blas_int_t[]> iwork(
new blas_int_t[12*minimum] );
1758 gesvdx(
'V',
'V', range, m, n, (*A).data(), lda, vl, vu, il, iu, &ns, sptr,
1759 ( SO ? uptr : vptr ), ( tmpRequired ? m : ( SO ? ldu : ldv ) ),
1760 ( SO ? vptr : uptr ), ( tmpRequired ? mindim : ( SO ? ldv : ldu ) ),
1761 work.get(), lwork, rwork.get(), iwork.get(), &info );
1763 const size_t num( numeric_cast<size_t>( ns ) );
1774 for(
size_t i=0UL; i<(*s).size(); ++i ) {
1780 for(
size_t j=0UL; j<(*U).columns(); ++j ) {
1781 for(
size_t i=0UL; i<(*U).rows(); ++i ) {
1782 (*U)(i,j) = utmp[i+j*M];
1786 for(
size_t j=0UL; j<(*V).columns(); ++j ) {
1787 for(
size_t i=0UL; i<(*V).rows(); ++i ) {
1788 (*V)(i,j) = vtmp[i+j*mindim];
1794 for(
size_t i=0UL; i<(*U).rows(); ++i ) {
1795 for(
size_t j=0UL; j<(*U).columns(); ++j ) {
1796 (*U)(i,j) = utmp[i*mindim+j];
1800 for(
size_t i=0UL; i<(*V).rows(); ++i ) {
1801 for(
size_t j=0UL; j<(*V).columns(); ++j ) {
1802 (*V)(i,j) = vtmp[i*N+j];
1875template<
typename MT1
1910 const size_t M( (*A).rows() );
1911 const size_t N( (*A).columns() );
1912 const size_t mindim(
min( M, N ) );
1914 resize( *s, mindim,
false );
1915 resize( *U, M, mindim,
false );
1916 resize( *V, mindim, N,
false );
1918 if( M == 0UL || N == 0UL ) {
1922 return gesvdx_backend( *A, *U, *s, *V,
'A', UT(), UT(), 0, 0 );
2024template<
typename MT1
2059 if( IsFloatingPoint_v<ST> && low >= upp ) {
2063 if( !IsFloatingPoint_v<ST> && low > upp ) {
2067 const size_t M( (*A).rows() );
2068 const size_t N( (*A).columns() );
2069 const size_t mindim(
min( M, N ) );
2070 const size_t expected( IsFloatingPoint_v<ST> ? mindim :
size_t( upp - low ) + 1UL );
2072 if( !IsFloatingPoint_v<ST> && expected > mindim ) {
2076 resize( *s, expected,
false );
2077 resize( *U, M, expected,
false );
2078 resize( *V, expected, N,
false );
2080 if( M == 0UL || N == 0UL ) {
2084 const char range( IsFloatingPoint_v<ST> ?
'V' :
'I' );
2085 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
2086 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
2087 const blas_int_t il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( low ) );
2088 const blas_int_t iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( upp ) );
2090 const size_t actual( gesvdx_backend( *A, *U, *s, *V, range, vl, vu, il, iu ) );
2092 if( IsResizable_v<VT> ) {
2093 resize( *s, actual,
true );
2096 if( IsResizable_v<MT2> ) {
2097 resize( *U, M, actual,
true );
2100 if( IsResizable_v<MT3> ) {
2101 resize( *V, actual, N,
true );
Constraint on the data type.
Header file for auxiliary alias declarations.
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
Header file for run time assertion macros.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsComplex type trait.
Header file for the IsFloatingPoint type trait.
Header file for the IsResizable type trait.
Constraint on the data type.
Cast operators for numeric types.
Header file for the UnderlyingElement type trait.
Header file for the CLAPACK gesvdx wrapper functions.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Base class for N-dimensional dense vectors.
Definition: DenseVector.h:77
Constraint on the data type.
Header file for the DenseMatrix base class.
Header file for the DenseVector base class.
#define BLAZE_CONSTRAINT_MUST_BE_BUILTIN_TYPE(T)
Constraint on the data type.
Definition: Builtin.h:60
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1339
size_t gesvdx(DenseMatrix< MT1, SO > &A, DenseMatrix< MT2, SO > &U, DenseVector< VT, TF > &s, DenseMatrix< MT3, SO > &V, ST low, ST upp)
LAPACK kernel for the singular value decomposition (SVD) of the given dense general matrix.
Definition: gesvdx.h:2031
#define BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE(T)
Constraint on the data type.
Definition: BLASCompatible.h:61
#define BLAZE_CONSTRAINT_MUST_BE_CONTIGUOUS_TYPE(T)
Constraint on the data type.
Definition: Contiguous.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ADAPTOR_TYPE(T)
Constraint on the data type.
Definition: Adaptor.h:81
#define BLAZE_CONSTRAINT_MUST_HAVE_MUTABLE_DATA_ACCESS(T)
Constraint on the data type.
Definition: MutableDataAccess.h:61
typename UnderlyingElement< T >::Type UnderlyingElement_t
Auxiliary alias declaration for the UnderlyingElement type trait.
Definition: UnderlyingElement.h:119
int32_t blas_int_t
Signed integer type used in the BLAS/LAPACK wrapper functions.
Definition: Types.h:64
#define BLAZE_THROW_LAPACK_ERROR(MESSAGE)
Macro for the emission of an exception on detection of a LAPACK error.
Definition: Exception.h:146
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
Header file for the exception macros of the math module.
Header file for the Size type trait.
Header file for basic type definitions.
Header file for the generic min algorithm.
Header file for the implementation of the Subvector view.