35#ifndef _BLAZE_MATH_LAPACK_GESVD_H_
36#define _BLAZE_MATH_LAPACK_GESVD_H_
74template<
typename MT,
bool SO,
typename VT,
bool TF >
75void gesvd( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
char jobu,
char jobv );
77template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF >
78void gesvd( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
79 DenseVector<VT,TF>& s,
char jobu,
char jobv );
81template<
typename MT1,
bool SO,
typename VT,
bool TF,
typename MT2 >
82void gesvd( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s,
83 DenseMatrix<MT2,SO>& V,
char jobu,
char jobv );
85template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename MT3 >
86void gesvd( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
87 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V,
char jobu,
char jobv );
115inline auto gesvd_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
char jobu,
char jobv )
116 -> DisableIf_t< IsComplex_v< ElementType_t<MT> > >
120 BLAZE_INTERNAL_ASSERT( jobu !=
'O' || jobv !=
'O',
"Invalid combination of jobu and jobv detected" );
123 using ET = ElementType_t<MT>;
125 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
126 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
127 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
133 blas_int_t lwork(
max( 3*minimum + maximum, 5*minimum ) + 2 );
134 const std::unique_ptr<ET[]> work(
new ET[lwork] );
136 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ), m, n, (*A).data(), lda,
137 (*s).data(),
nullptr, 1,
nullptr, 1, work.get(), lwork, &info );
172inline auto gesvd_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
char jobu,
char jobv )
173 -> EnableIf_t< IsComplex_v< ElementType_t<MT> > >
177 BLAZE_INTERNAL_ASSERT( jobu !=
'O' || jobv !=
'O',
"Invalid combination of jobu and jobv detected" );
180 using CT = ElementType_t<MT>;
181 using BT = UnderlyingElement_t<CT>;
183 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
184 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
185 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
192 const std::unique_ptr<CT[]> work (
new CT[lwork] );
193 const std::unique_ptr<BT[]> rwork(
new BT[5*minimum] );
195 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ), m, n, (*A).data(), lda,
196 (*s).data(),
nullptr, 1,
nullptr, 1, work.get(), lwork, rwork.get(), &info );
309 const size_t M( (*A).rows() );
310 const size_t N( (*A).columns() );
311 const size_t mindim(
min( M, N ) );
313 if( jobu !=
'O' && jobu !=
'N' ) {
317 if( jobv !=
'O' && jobv !=
'N' ) {
321 if( jobu ==
'O' && jobv ==
'O' ) {
325 resize( *s, mindim,
false );
327 if( M == 0UL || N == 0UL ) {
331 gesvd_backend( *A, *s, jobu, jobv );
356template<
typename MT1
361inline auto gesvd_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
362 DenseVector<VT,TF>& s,
char jobu,
char jobv )
363 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
367 BLAZE_INTERNAL_ASSERT( jobu ==
'N' || (*U).rows() == (*A).rows(),
"Invalid matrix dimension detected" );
369 BLAZE_INTERNAL_ASSERT( jobu !=
'S' || (*U).columns() ==
min( (*A).rows(), (*A).columns() ),
"Invalid matrix dimension detected" );
372 using ET = ElementType_t<MT1>;
374 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
375 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
376 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
377 blas_int_t ldu ( numeric_cast<blas_int_t>( (*U).spacing() ) );
383 blas_int_t lwork(
max( 3*minimum + maximum, 5*minimum ) + 2 );
384 const std::unique_ptr<ET[]> work(
new ET[lwork] );
386 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
387 m, n, (*A).data(), lda, (*s).data(),
388 ( SO ? (*U).data() :
nullptr ), ( SO ? ldu : 1 ),
389 ( SO ?
nullptr : (*U).data() ), ( SO ? 1 : ldu ),
390 work.get(), lwork, &info );
422template<
typename MT1
427inline auto gesvd_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
428 DenseVector<VT,TF>& s,
char jobu,
char jobv )
429 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
433 BLAZE_INTERNAL_ASSERT( jobu ==
'N' || (*U).rows() == (*A).rows(),
"Invalid matrix dimension detected" );
435 BLAZE_INTERNAL_ASSERT( jobu !=
'S' || (*U).columns() ==
min( (*A).rows(), (*A).columns() ),
"Invalid matrix dimension detected" );
438 using CT = ElementType_t<MT1>;
439 using BT = UnderlyingElement_t<CT>;
441 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
442 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
443 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
444 blas_int_t ldu ( numeric_cast<blas_int_t>( (*U).spacing() ) );
451 const std::unique_ptr<CT[]> work (
new CT[lwork] );
452 const std::unique_ptr<BT[]> rwork(
new BT[5*minimum] );
454 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
455 m, n, (*A).data(), lda, (*s).data(),
456 ( SO ? (*U).data() :
nullptr ), ( SO ? ldu : 1 ),
457 ( SO ?
nullptr : (*U).data() ), ( SO ? 1 : ldu ),
458 work.get(), lwork, rwork.get(), &info );
571template<
typename MT1
596 const size_t M( (*A).rows() );
597 const size_t N( (*A).columns() );
598 const size_t mindim(
min( M, N ) );
600 if( jobu !=
'A' && jobu !=
'S' && jobu !=
'N' ) {
604 if( jobv !=
'O' && jobv !=
'N' ) {
608 resize( *s, mindim,
false );
611 resize( *U, M, ( jobu ==
'A' ? M : mindim ),
false );
614 if( M == 0UL || N == 0UL ) {
618 gesvd_backend( *A, *U, *s, jobu, jobv );
643template<
typename MT1
648inline auto gesvd_backend( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s,
649 DenseMatrix<MT2,SO>& V,
char jobu,
char jobv )
650 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
654 BLAZE_INTERNAL_ASSERT( jobv ==
'N' || (*V).columns() == (*A).columns(),
"Invalid matrix dimension detected" );
656 BLAZE_INTERNAL_ASSERT( jobv !=
'S' || (*V).rows() ==
min( (*A).rows(), (*A).columns() ),
"Invalid matrix dimension detected" );
659 using ET = ElementType_t<MT1>;
661 blas_int_t m ( numeric_cast< blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
662 blas_int_t n ( numeric_cast< blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
663 blas_int_t lda ( numeric_cast< blas_int_t>( (*A).spacing() ) );
664 blas_int_t ldv ( numeric_cast< blas_int_t>( (*V).spacing() ) );
670 blas_int_t lwork(
max( 3*minimum + maximum, 5*minimum ) + 2 );
671 const std::unique_ptr<ET[]> work(
new ET[lwork] );
673 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
674 m, n, (*A).data(), lda, (*s).data(),
675 ( SO ?
nullptr : (*V).data() ), ( SO ? 1 : ldv ),
676 ( SO ? (*V).data() :
nullptr ), ( SO ? ldv : 1 ),
677 work.get(), lwork, &info );
709template<
typename MT1
714inline auto gesvd_backend( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s,
715 DenseMatrix<MT2,SO>& V,
char jobu,
char jobv )
716 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
720 BLAZE_INTERNAL_ASSERT( jobv ==
'N' || (*V).columns() == (*A).columns(),
"Invalid matrix dimension detected" );
722 BLAZE_INTERNAL_ASSERT( jobv !=
'S' || (*V).rows() ==
min( (*A).rows(), (*A).columns() ),
"Invalid matrix dimension detected" );
725 using CT = ElementType_t<MT1>;
726 using BT = UnderlyingElement_t<CT>;
728 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
729 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
730 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
731 blas_int_t ldv ( numeric_cast<blas_int_t>( (*V).spacing() ) );
738 const std::unique_ptr<CT[]> work (
new CT[lwork] );
739 const std::unique_ptr<BT[]> rwork(
new BT[5*minimum] );
741 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
742 m, n, (*A).data(), lda, (*s).data(),
743 ( SO ?
nullptr : (*V).data() ), ( SO ? 1 : ldv ),
744 ( SO ? (*V).data() :
nullptr ), ( SO ? ldv : 1 ),
745 work.get(), lwork, rwork.get(), &info );
858template<
typename MT1
883 const size_t M( (*A).rows() );
884 const size_t N( (*A).columns() );
885 const size_t mindim(
min( M, N ) );
887 if( jobu !=
'O' && jobu !=
'N' ) {
891 if( jobv !=
'A' && jobv !=
'S' && jobv !=
'N' ) {
895 resize( *s, mindim,
false );
898 resize( *V, ( jobv ==
'A' ? N : mindim ), N,
false );
901 if( M == 0UL || N == 0UL ) {
905 gesvd_backend( *A, *s, *V, jobu, jobv );
931template<
typename MT1
937inline auto gesvd_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
938 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V,
char jobu,
char jobv )
939 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
943 BLAZE_INTERNAL_ASSERT( jobu ==
'N' || (*U).rows() == (*A).rows(),
"Invalid matrix dimension detected" );
945 BLAZE_INTERNAL_ASSERT( jobu !=
'S' || (*U).columns() ==
min( (*A).rows(), (*A).columns() ),
"Invalid matrix dimension detected" );
946 BLAZE_INTERNAL_ASSERT( jobv ==
'N' || (*V).columns() == (*A).columns(),
"Invalid matrix dimension detected" );
948 BLAZE_INTERNAL_ASSERT( jobv !=
'S' || (*V).rows() ==
min( (*A).rows(), (*A).columns() ),
"Invalid matrix dimension detected" );
951 using ET = ElementType_t<MT1>;
953 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
954 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
955 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
956 blas_int_t ldu ( numeric_cast<blas_int_t>( (*U).spacing() ) );
957 blas_int_t ldv ( numeric_cast<blas_int_t>( (*V).spacing() ) );
963 blas_int_t lwork(
max( 3*minimum + maximum, 5*minimum ) + 2 );
964 const std::unique_ptr<ET[]> work(
new ET[lwork] );
966 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
967 m, n, (*A).data(), lda, (*s).data(),
968 ( SO ? (*U).data() : (*V).data() ), ( SO ? ldu : ldv ),
969 ( SO ? (*V).data() : (*U).data() ), ( SO ? ldv : ldu ),
970 work.get(), lwork, &info );
1003template<
typename MT1
1009inline auto gesvd_backend( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
1010 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V,
char jobu,
char jobv )
1011 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
1015 BLAZE_INTERNAL_ASSERT( jobu ==
'N' || (*U).rows() == (*A).rows(),
"Invalid matrix dimension detected" );
1017 BLAZE_INTERNAL_ASSERT( jobu !=
'S' || (*U).columns() ==
min( (*A).rows(), (*A).columns() ),
"Invalid matrix dimension detected" );
1018 BLAZE_INTERNAL_ASSERT( jobv ==
'N' || (*V).columns() == (*A).columns(),
"Invalid matrix dimension detected" );
1020 BLAZE_INTERNAL_ASSERT( jobv !=
'S' || (*V).rows() ==
min( (*A).rows(), (*A).columns() ),
"Invalid matrix dimension detected" );
1023 using CT = ElementType_t<MT1>;
1024 using BT = UnderlyingElement_t<CT>;
1026 blas_int_t m ( numeric_cast<blas_int_t>( SO ? (*A).rows() : (*A).columns() ) );
1027 blas_int_t n ( numeric_cast<blas_int_t>( SO ? (*A).columns() : (*A).rows() ) );
1028 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
1029 blas_int_t ldu ( numeric_cast<blas_int_t>( (*U).spacing() ) );
1030 blas_int_t ldv ( numeric_cast<blas_int_t>( (*V).spacing() ) );
1037 const std::unique_ptr<CT[]> work (
new CT[lwork] );
1038 const std::unique_ptr<BT[]> rwork(
new BT[5*minimum] );
1040 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
1041 m, n, (*A).data(), lda, (*s).data(),
1042 ( SO ? (*U).data() : (*V).data() ), ( SO ? ldu : ldv ),
1043 ( SO ? (*V).data() : (*U).data() ), ( SO ? ldv : ldu ),
1044 work.get(), lwork, rwork.get(), &info );
1164template<
typename MT1
1196 const size_t M( (*A).rows() );
1197 const size_t N( (*A).columns() );
1198 const size_t mindim(
min( M, N ) );
1200 if( jobu !=
'A' && jobu !=
'S' && jobu !=
'N' ) {
1204 if( jobv !=
'A' && jobv !=
'S' && jobv !=
'N' ) {
1208 resize( *s, mindim,
false );
1211 resize( *U, M, ( jobu ==
'A' ? M : mindim ),
false );
1212 resize( *V, ( jobv ==
'A' ? N : mindim ), N,
false );
1215 if( M == 0UL || N == 0UL ) {
1219 gesvd_backend( *A, *U, *s, *V, jobu, jobv );
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.
Header file for the EnableIf class template.
Header file for the IsComplex type trait.
Constraint on the data type.
Cast operators for numeric types.
Header file for the UnderlyingElement type trait.
Header file for the CLAPACK gesvd 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.
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
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
void gesvd(DenseMatrix< MT1, SO > &A, DenseMatrix< MT2, SO > &U, DenseVector< VT, TF > &s, DenseMatrix< MT3, SO > &V, char jobu, char jobv)
LAPACK kernel for the singular value decomposition (SVD) of the given dense general matrix.
Definition: gesvd.h:1170
#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
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
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:1383
#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 generic max algorithm.
Header file for the generic min algorithm.