35 #ifndef _BLAZE_MATH_LAPACK_GESVDX_H_ 36 #define _BLAZE_MATH_LAPACK_GESVDX_H_ 80 template<
typename MT,
bool SO,
typename VT,
bool TF >
81 size_t gesvdx( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s );
83 template<
typename MT,
bool SO,
typename VT,
bool TF,
typename ST >
84 size_t gesvdx( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s, ST low, ST upp );
86 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF >
87 size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s );
89 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename ST >
90 size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
91 DenseVector<VT,TF>& s, ST low, ST upp );
93 template<
typename MT1,
bool SO,
typename VT,
bool TF,
typename MT2 >
94 size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s, DenseMatrix<MT2,SO>& V );
96 template<
typename MT1,
bool SO,
typename VT,
bool TF,
typename MT2,
typename ST >
97 size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s,
98 DenseMatrix<MT2,SO>& V, ST low, ST upp );
100 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename MT3 >
101 size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
102 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V );
104 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename MT3,
typename ST >
105 size_t gesvdx( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
106 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V, ST low, ST upp );
133 template<
typename MT
138 inline auto gesvdx_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
139 char range, ST vl, ST vu,
int il,
int iu )
140 -> DisableIf_t< IsComplex_v< ElementType_t<MT> >,
size_t >
142 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
149 using ET = ElementType_t<MT>;
151 const size_t M( (~A).
rows() );
152 const size_t N( (~A).
columns() );
153 const size_t mindim(
min( M, N ) );
155 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
156 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
157 int lda ( numeric_cast<int>( (~A).
spacing() ) );
161 ET* sptr( (~s).
data() );
162 std::unique_ptr<ET[]> stmp;
164 const bool tmpRequired( (~s).
size() < mindim );
167 stmp.reset(
new ET[2UL*mindim] );
171 const int minimum(
min( m, n ) );
173 int lwork( minimum*( minimum*3 + 20 ) + 2 );
174 const std::unique_ptr<ET[]> work (
new ET[lwork] );
175 const std::unique_ptr<int[]> iwork(
new int[12*minimum] );
177 gesvdx(
'N',
'N', range, m, n, (~A).
data(), lda, vl, vu, il, iu, &ns, sptr,
178 nullptr, 1,
nullptr, 1, work.get(), lwork, iwork.get(), &info );
180 const size_t num( numeric_cast<size_t>( ns ) );
190 for(
size_t i=0UL; i<(~s).
size(); ++i ) {
223 template<
typename MT
228 inline auto gesvdx_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
229 char range, ST vl, ST vu,
int il,
int iu )
230 -> EnableIf_t< IsComplex_v< ElementType_t<MT> >,
size_t >
232 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
239 using CT = ElementType_t<MT>;
240 using BT = UnderlyingElement_t<CT>;
242 const size_t M( (~A).
rows() );
243 const size_t N( (~A).
columns() );
244 const size_t mindim(
min( M, N ) );
246 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
247 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
248 int lda ( numeric_cast<int>( (~A).
spacing() ) );
252 BT* sptr( (~s).
data() );
253 std::unique_ptr<BT[]> stmp;
255 const bool tmpRequired( (~s).
size() < mindim );
258 stmp.reset(
new BT[2UL*mindim] );
262 const int minimum(
min( m, n ) );
264 int lwork( minimum*( minimum*3 + 20 ) + 2 );
265 const std::unique_ptr<CT[]> work (
new CT[lwork] );
266 const std::unique_ptr<BT[]> rwork(
new BT[17*minimum*minimum] );
267 const std::unique_ptr<int[]> iwork(
new int[12*minimum] );
269 gesvdx(
'N',
'N', range, m, n, (~A).
data(), lda, vl, vu, il, iu, &ns, sptr,
270 nullptr, 1,
nullptr, 1, work.get(), lwork, rwork.get(), iwork.get(), &info );
272 const size_t num( numeric_cast<size_t>( ns ) );
282 for(
size_t i=0UL; i<(~s).
size(); ++i ) {
345 template<
typename MT
365 const size_t M( (~A).
rows() );
366 const size_t N( (~A).
columns() );
367 const size_t mindim(
min( M, N ) );
369 resize( ~s, mindim,
false );
371 if( M == 0UL || N == 0UL ) {
375 return gesvdx_backend( ~A, ~s,
'A', UT(), UT(), 0, 0 );
461 template<
typename MT
481 if( IsFloatingPoint_v<ST> && low >= upp ) {
485 if( !IsFloatingPoint_v<ST> && low > upp ) {
489 const size_t M( (~A).
rows() );
490 const size_t N( (~A).
columns() );
491 const size_t mindim(
min( M, N ) );
492 const size_t expected( IsFloatingPoint_v<ST> ? mindim :
size_t( upp - low ) + 1UL );
494 if( !IsFloatingPoint_v<ST> && expected > mindim ) {
498 resize( ~s, expected,
false );
500 if( M == 0UL || N == 0UL ) {
504 const char range( IsFloatingPoint_v<ST> ?
'V' :
'I' );
505 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
506 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
507 const int il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<int>( low ) );
508 const int iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<int>( upp ) );
510 const size_t actual( gesvdx_backend( ~A, ~s, range, vl, vu, il, iu ) );
512 if( IsResizable_v<VT> ) {
513 resize( ~s, actual,
true );
544 template<
typename MT1
550 inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s,
551 char range, ST vl, ST vu,
int il,
int iu )
552 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
554 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
563 using ET = ElementType_t<MT1>;
565 const size_t M( (~A).
rows() );
566 const size_t N( (~A).
columns() );
567 const size_t mindim(
min( M, N ) );
569 int m ( numeric_cast<int>( SO ? M : N ) );
570 int n ( numeric_cast<int>( SO ? N : M ) );
571 int lda ( numeric_cast<int>( (~A).
spacing() ) );
572 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
576 ET* sptr( (~s).
data() );
577 ET* uptr( (~U).
data() );
578 std::unique_ptr<ET[]> stmp;
579 std::unique_ptr<ET[]> utmp;
581 const bool tmpRequired( (~s).
size() < mindim );
584 stmp.reset(
new ET[2UL*mindim] );
585 utmp.reset(
new ET[M*mindim] );
590 const int minimum(
min( m, n ) );
592 int lwork( minimum*( minimum*3 + 20 ) + 2 );
593 const std::unique_ptr<ET[]> work (
new ET[lwork] );
594 const std::unique_ptr<int[]> iwork(
new int[12*minimum] );
596 gesvdx( ( SO ?
'V' :
'N' ), ( SO ?
'N' :
'V' ), range, m, n,
597 (~A).
data(), lda, vl, vu, il, iu, &ns, sptr,
598 ( SO ? uptr :
nullptr ), ( tmpRequired ? m : ( SO ? ldu : 1 ) ),
599 ( SO ?
nullptr : uptr ), ( tmpRequired ? mindim : ( SO ? 1 : ldu ) ),
600 work.get(), lwork, iwork.get(), &info );
602 const size_t num( numeric_cast<size_t>( ns ) );
613 for(
size_t i=0UL; i<(~s).
size(); ++i ) {
619 for(
size_t j=0UL; j<(~U).
columns(); ++j ) {
620 for(
size_t i=0UL; i<(~U).
rows(); ++i ) {
621 (~U)(i,j) = utmp[i+j*M];
627 for(
size_t i=0UL; i<(~U).
rows(); ++i ) {
628 for(
size_t j=0UL; j<(~U).
columns(); ++j ) {
629 (~U)(i,j) = utmp[i*mindim+j];
664 template<
typename MT1
670 inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s,
671 char range, ST vl, ST vu,
int il,
int iu )
672 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
674 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
683 using CT = ElementType_t<MT1>;
684 using BT = UnderlyingElement_t<CT>;
686 const size_t M( (~A).
rows() );
687 const size_t N( (~A).
columns() );
688 const size_t mindim(
min( M, N ) );
690 int m ( numeric_cast<int>( SO ? M : N ) );
691 int n ( numeric_cast<int>( SO ? N : M ) );
692 int lda ( numeric_cast<int>( (~A).
spacing() ) );
693 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
697 BT* sptr( (~s).
data() );
698 CT* uptr( (~U).
data() );
699 std::unique_ptr<BT[]> stmp;
700 std::unique_ptr<CT[]> utmp;
702 const bool tmpRequired( (~s).
size() < mindim );
705 stmp.reset(
new BT[2UL*mindim] );
706 utmp.reset(
new CT[M*mindim] );
711 const int minimum(
min( m, n ) );
713 int lwork( minimum*( minimum*3 + 20 ) + 2 );
714 const std::unique_ptr<CT[]> work (
new CT[lwork] );
715 const std::unique_ptr<BT[]> rwork(
new BT[17*minimum*minimum] );
716 const std::unique_ptr<int[]> iwork(
new int[12*minimum] );
718 gesvdx( ( SO ?
'V' :
'N' ), ( SO ?
'N' :
'V' ), range, m, n,
719 (~A).
data(), lda, vl, vu, il, iu, &ns, sptr,
720 ( SO ? uptr :
nullptr ), ( tmpRequired ? m : ( SO ? ldu : 1 ) ),
721 ( SO ?
nullptr : uptr ), ( tmpRequired ? mindim : ( SO ? 1 : ldu ) ),
722 work.get(), lwork, rwork.get(), iwork.get(), &info );
724 const size_t num( numeric_cast<size_t>( ns ) );
735 for(
size_t i=0UL; i<(~s).
size(); ++i ) {
741 for(
size_t j=0UL; j<(~U).
columns(); ++j ) {
742 for(
size_t i=0UL; i<(~U).
rows(); ++i ) {
743 (~U)(i,j) = utmp[i+j*M];
749 for(
size_t i=0UL; i<(~U).
rows(); ++i ) {
750 for(
size_t j=0UL; j<(~U).
columns(); ++j ) {
751 (~U)(i,j) = utmp[i*mindim+j];
820 template<
typename MT1
847 const size_t M( (~A).
rows() );
848 const size_t N( (~A).
columns() );
849 const size_t mindim(
min( M, N ) );
851 resize( ~s, mindim,
false );
852 resize( ~U, M, mindim,
false );
854 if( M == 0UL || N == 0UL ) {
858 return gesvdx_backend( ~A, ~U, ~s,
'A', UT(), UT(), 0, 0 );
953 template<
typename MT1
981 if( IsFloatingPoint_v<ST> && low >= upp ) {
985 if( !IsFloatingPoint_v<ST> && low > upp ) {
989 const size_t M( (~A).
rows() );
990 const size_t N( (~A).
columns() );
991 const size_t mindim(
min( M, N ) );
992 const size_t expected( IsFloatingPoint_v<ST> ? mindim :
size_t( upp - low ) + 1UL );
994 if( !IsFloatingPoint_v<ST> && expected > mindim ) {
998 resize( ~s, expected,
false );
999 resize( ~U, M, expected,
false );
1001 if( M == 0UL || N == 0UL ) {
1005 const char range( IsFloatingPoint_v<ST> ?
'V' :
'I' );
1006 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
1007 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
1008 const int il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<int>( low ) );
1009 const int iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<int>( upp ) );
1011 const size_t actual( gesvdx_backend( ~A, ~U, ~s, range, vl, vu, il, iu ) );
1013 if( IsResizable_v<VT> ) {
1014 resize( ~s, actual,
true );
1017 if( IsResizable_v<MT2> ) {
1018 resize( ~U, M, actual,
true );
1049 template<
typename MT1
1055 inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s, DenseMatrix<MT2,SO>& V,
1056 char range, ST vl, ST vu,
int il,
int iu )
1057 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
1059 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
1068 using ET = ElementType_t<MT1>;
1070 const size_t M( (~A).
rows() );
1071 const size_t N( (~A).
columns() );
1072 const size_t mindim(
min( M, N ) );
1074 int m ( numeric_cast<int>( SO ? M : N ) );
1075 int n ( numeric_cast<int>( SO ? N : M ) );
1076 int lda ( numeric_cast<int>( (~A).
spacing() ) );
1077 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
1081 ET* sptr( (~s).
data() );
1082 ET* vptr( (~V).
data() );
1083 std::unique_ptr<ET[]> stmp;
1084 std::unique_ptr<ET[]> vtmp;
1086 const bool tmpRequired( (~s).
size() < mindim );
1089 stmp.reset(
new ET[2UL*mindim] );
1090 vtmp.reset(
new ET[mindim*N] );
1095 const int minimum(
min( m, n ) );
1097 int lwork( minimum*( minimum*3 + 20 ) + 2 );
1098 const std::unique_ptr<ET[]> work (
new ET[lwork] );
1099 const std::unique_ptr<int[]> iwork(
new int[12*minimum] );
1101 gesvdx( ( SO ?
'N' :
'V' ), ( SO ?
'V' :
'N' ), range, m, n,
1102 (~A).
data(), lda, vl, vu, il, iu, &ns, sptr,
1103 ( SO ?
nullptr : vptr ), ( tmpRequired ? m : ( SO ? 1 : ldv ) ),
1104 ( SO ? vptr :
nullptr ), ( tmpRequired ? mindim : ( SO ? ldv : 1 ) ),
1105 work.get(), lwork, iwork.get(), &info );
1107 const size_t num( numeric_cast<size_t>( ns ) );
1118 for(
size_t i=0UL; i<(~s).
size(); ++i ) {
1124 for(
size_t j=0UL; j<(~V).
columns(); ++j ) {
1125 for(
size_t i=0UL; i<(~V).
rows(); ++i ) {
1126 (~V)(i,j) = vtmp[i+j*mindim];
1132 for(
size_t i=0UL; i<(~V).
rows(); ++i ) {
1133 for(
size_t j=0UL; j<(~V).
columns(); ++j ) {
1134 (~V)(i,j) = vtmp[i*N+j];
1169 template<
typename MT1
1175 inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s, DenseMatrix<MT2,SO>& V,
1176 char range, ST vl, ST vu,
int il,
int iu )
1177 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
1179 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
1188 using CT = ElementType_t<MT1>;
1189 using BT = UnderlyingElement_t<CT>;
1191 const size_t M( (~A).
rows() );
1192 const size_t N( (~A).
columns() );
1193 const size_t mindim(
min( M, N ) );
1195 int m ( numeric_cast<int>( SO ? M : N ) );
1196 int n ( numeric_cast<int>( SO ? N : M ) );
1197 int lda ( numeric_cast<int>( (~A).
spacing() ) );
1198 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
1202 BT* sptr( (~s).
data() );
1203 CT* vptr( (~V).
data() );
1204 std::unique_ptr<BT[]> stmp;
1205 std::unique_ptr<CT[]> vtmp;
1207 const bool tmpRequired( (~s).
size() < mindim );
1210 stmp.reset(
new BT[2UL*mindim] );
1211 vtmp.reset(
new CT[mindim*N] );
1216 const int minimum(
min( m, n ) );
1218 int lwork( minimum*( minimum*3 + 20 ) + 2 );
1219 const std::unique_ptr<CT[]> work (
new CT[lwork] );
1220 const std::unique_ptr<BT[]> rwork(
new BT[17*minimum*minimum] );
1221 const std::unique_ptr<int[]> iwork(
new int[12*minimum] );
1223 gesvdx( ( SO ?
'N' :
'V' ), ( SO ?
'V' :
'N' ), range, m, n,
1224 (~A).
data(), lda, vl, vu, il, iu, &ns, sptr,
1225 ( SO ?
nullptr : vptr ), ( tmpRequired ? m : ( SO ? 1 : ldv ) ),
1226 ( SO ? vptr :
nullptr ), ( tmpRequired ? mindim : ( SO ? ldv : 1 ) ),
1227 work.get(), lwork, rwork.get(), iwork.get(), &info );
1229 const size_t num( numeric_cast<size_t>( ns ) );
1240 for(
size_t i=0UL; i<(~s).
size(); ++i ) {
1246 for(
size_t j=0UL; j<(~V).
columns(); ++j ) {
1247 for(
size_t i=0UL; i<(~V).
rows(); ++i ) {
1248 (~V)(i,j) = vtmp[i+j*mindim];
1254 for(
size_t i=0UL; i<(~V).
rows(); ++i ) {
1255 for(
size_t j=0UL; j<(~V).
columns(); ++j ) {
1256 (~V)(i,j) = vtmp[i*N+j];
1325 template<
typename MT1
1352 const size_t M( (~A).
rows() );
1353 const size_t N( (~A).
columns() );
1354 const size_t mindim(
min( M, N ) );
1356 resize( ~s, mindim,
false );
1357 resize( ~V, mindim, N,
false );
1359 if( M == 0UL || N == 0UL ) {
1363 return gesvdx_backend( ~A, ~s, ~V,
'A', UT(), UT(), 0, 0 );
1458 template<
typename MT1
1486 if( IsFloatingPoint_v<ST> && low >= upp ) {
1490 if( !IsFloatingPoint_v<ST> && low > upp ) {
1494 const size_t M( (~A).
rows() );
1495 const size_t N( (~A).
columns() );
1496 const size_t mindim(
min( M, N ) );
1497 const size_t expected( IsFloatingPoint_v<ST> ? mindim :
size_t( upp - low ) + 1UL );
1499 if( !IsFloatingPoint_v<ST> && expected > mindim ) {
1503 resize( ~s, expected,
false );
1504 resize( ~V, expected, N,
false );
1506 if( M == 0UL || N == 0UL ) {
1510 const char range( IsFloatingPoint_v<ST> ?
'V' :
'I' );
1511 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
1512 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
1513 const int il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<int>( low ) );
1514 const int iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<int>( upp ) );
1516 const size_t actual( gesvdx_backend( ~A, ~s, ~V, range, vl, vu, il, iu ) );
1518 if( IsResizable_v<VT> ) {
1519 resize( ~s, actual,
true );
1522 if( IsResizable_v<MT2> ) {
1523 resize( ~V, actual, N,
true );
1555 template<
typename MT1
1562 inline auto gesvdx_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U, DenseVector<VT,TF>& s,
1563 DenseMatrix<MT3,SO>& V,
char range, ST vl, ST vu,
int il,
int iu )
1564 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
1566 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag 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 int m ( numeric_cast<int>( SO ? M : N ) );
1584 int n ( numeric_cast<int>( SO ? N : M ) );
1585 int lda ( numeric_cast<int>( (~A).
spacing() ) );
1586 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
1587 int ldv ( numeric_cast<int>( (~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] );
1609 const int minimum(
min( m, n ) );
1611 int lwork( minimum*( minimum*3 + 20 ) + 2 );
1612 const std::unique_ptr<ET[]> work (
new ET[lwork] );
1613 const std::unique_ptr<int[]> iwork(
new int[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];
1695 template<
typename MT1
1702 inline 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,
int il,
int iu )
1704 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> >,
size_t >
1706 BLAZE_INTERNAL_ASSERT( range ==
'A' || range ==
'V' || range ==
'I',
"Invalid range flag detected" );
1717 using CT = ElementType_t<MT1>;
1718 using BT = UnderlyingElement_t<CT>;
1720 const size_t M( (~A).
rows() );
1721 const size_t N( (~A).
columns() );
1722 const size_t mindim(
min( M, N ) );
1724 int m ( numeric_cast<int>( SO ? M : N ) );
1725 int n ( numeric_cast<int>( SO ? N : M ) );
1726 int lda ( numeric_cast<int>( (~A).
spacing() ) );
1727 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
1728 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
1732 BT* sptr( (~s).
data() );
1733 CT* uptr( (~U).
data() );
1734 CT* vptr( (~V).
data() );
1735 std::unique_ptr<BT[]> stmp;
1736 std::unique_ptr<CT[]> utmp;
1737 std::unique_ptr<CT[]> vtmp;
1739 const bool tmpRequired( (~s).
size() < mindim );
1742 stmp.reset(
new BT[2UL*mindim] );
1743 utmp.reset(
new CT[M*mindim] );
1744 vtmp.reset(
new CT[mindim*N] );
1750 const int minimum(
min( m, n ) );
1752 int lwork( minimum*( minimum*3 + 20 ) + 2 );
1753 const std::unique_ptr<CT[]> work (
new CT[lwork] );
1754 const std::unique_ptr<BT[]> rwork(
new BT[17*minimum*minimum] );
1755 const std::unique_ptr<int[]> iwork(
new int[12*minimum] );
1757 gesvdx(
'V',
'V', range, m, n, (~A).
data(), lda, vl, vu, il, iu, &ns, sptr,
1758 ( SO ? uptr : vptr ), ( tmpRequired ? m : ( SO ? ldu : ldv ) ),
1759 ( SO ? vptr : uptr ), ( tmpRequired ? mindim : ( SO ? ldv : ldu ) ),
1760 work.get(), lwork, rwork.get(), iwork.get(), &info );
1762 const size_t num( numeric_cast<size_t>( ns ) );
1773 for(
size_t i=0UL; i<(~s).
size(); ++i ) {
1779 for(
size_t j=0UL; j<(~U).
columns(); ++j ) {
1780 for(
size_t i=0UL; i<(~U).
rows(); ++i ) {
1781 (~U)(i,j) = utmp[i+j*M];
1785 for(
size_t j=0UL; j<(~V).
columns(); ++j ) {
1786 for(
size_t i=0UL; i<(~V).
rows(); ++i ) {
1787 (~V)(i,j) = vtmp[i+j*mindim];
1793 for(
size_t i=0UL; i<(~U).
rows(); ++i ) {
1794 for(
size_t j=0UL; j<(~U).
columns(); ++j ) {
1795 (~U)(i,j) = utmp[i*mindim+j];
1799 for(
size_t i=0UL; i<(~V).
rows(); ++i ) {
1800 for(
size_t j=0UL; j<(~V).
columns(); ++j ) {
1801 (~V)(i,j) = vtmp[i*N+j];
1874 template<
typename MT1
1909 const size_t M( (~A).
rows() );
1910 const size_t N( (~A).
columns() );
1911 const size_t mindim(
min( M, N ) );
1913 resize( ~s, mindim,
false );
1914 resize( ~U, M, mindim,
false );
1915 resize( ~V, mindim, N,
false );
1917 if( M == 0UL || N == 0UL ) {
1921 return gesvdx_backend( ~A, ~U, ~s, ~V,
'A', UT(), UT(), 0, 0 );
2023 template<
typename MT1
2058 if( IsFloatingPoint_v<ST> && low >= upp ) {
2062 if( !IsFloatingPoint_v<ST> && low > upp ) {
2066 const size_t M( (~A).
rows() );
2067 const size_t N( (~A).
columns() );
2068 const size_t mindim(
min( M, N ) );
2069 const size_t expected( IsFloatingPoint_v<ST> ? mindim :
size_t( upp - low ) + 1UL );
2071 if( !IsFloatingPoint_v<ST> && expected > mindim ) {
2075 resize( ~s, expected,
false );
2076 resize( ~U, M, expected,
false );
2077 resize( ~V, expected, N,
false );
2079 if( M == 0UL || N == 0UL ) {
2083 const char range( IsFloatingPoint_v<ST> ?
'V' :
'I' );
2084 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
2085 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
2086 const int il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<int>( low ) );
2087 const int iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<int>( upp ) );
2089 const size_t actual( gesvdx_backend( ~A, ~U, ~s, ~V, range, vl, vu, il, iu ) );
2091 if( IsResizable_v<VT> ) {
2092 resize( ~s, actual,
true );
2095 if( IsResizable_v<MT2> ) {
2096 resize( ~U, M, actual,
true );
2099 if( IsResizable_v<MT3> ) {
2100 resize( ~V, actual, N,
true );
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
#define BLAZE_CONSTRAINT_MUST_HAVE_MUTABLE_DATA_ACCESS(T)
Constraint on the data type.In case the given data type T does not provide low-level data access to m...
Definition: MutableDataAccess.h:61
Header file for basic type definitions.
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:170
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i....
Definition: Computation.h:81
Header file for the DenseVector base class.
Header file for the UnderlyingElement type trait.
Constraint on the data type.
Constraint on the data type.
Cast operators for numeric types.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ADAPTOR_TYPE(T)
Constraint on the data type.In case the given data type T is an adaptor type (as for instance LowerMa...
Definition: Adaptor.h:81
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:253
Header file for the implementation of the Subvector view.
Constraint on the data type.
Header file for the DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_CONTIGUOUS_TYPE(T)
Constraint on the data type.In case the given data type T is not an array-like data type with contigu...
Definition: Contiguous.h:61
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:1162
Header file for the DenseMatrix base class.
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
Header file for the exception macros of the math module.
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:738
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the CLAPACK gesvdx wrapper functions.
Header file for run time assertion macros.
void gesvdx(char jobu, char jobv, char range, int m, int n, float *A, int lda, float vl, float vu, int il, int iu, int *ns, float *s, float *U, int ldu, float *V, int ldv, float *work, int lwork, int *iwork, int *info)
LAPACK kernel for the singular value decomposition (SVD) of the given dense general single precision ...
Definition: gesvdx.h:192
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
#define BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a BLAS compatible data type (i....
Definition: BLASCompatible.h:61
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
#define BLAZE_CONSTRAINT_MUST_BE_BUILTIN_TYPE(T)
Constraint on the data type.In case the given data type T is not a built-in data type,...
Definition: Builtin.h:60
#define BLAZE_THROW_LAPACK_ERROR(MESSAGE)
Macro for the emission of an exception on detection of a LAPACK error.This macro encapsulates the def...
Definition: Exception.h:146
Header file for the IsComplex type trait.
typename UnderlyingElement< T >::Type UnderlyingElement_t
Auxiliary alias declaration for the UnderlyingElement type trait.The UnderlyingElement_t alias declar...
Definition: UnderlyingElement.h:119
Header file for the IsResizable type trait.
Header file for the Size type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
Constraint on the data type.