35 #ifndef _BLAZE_MATH_LAPACK_GESVD_H_ 36 #define _BLAZE_MATH_LAPACK_GESVD_H_ 44 #include <boost/cast.hpp> 74 template<
typename MT,
bool SO,
typename VT,
bool TF >
75 inline void gesvd( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
char jobu,
char jobv );
77 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF >
78 inline void gesvd( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
79 DenseVector<VT,TF>& s,
char jobu,
char jobv );
81 template<
typename MT1,
bool SO,
typename VT,
bool TF,
typename MT2 >
82 inline void gesvd( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s,
83 DenseMatrix<MT2,SO>& V,
char jobu,
char jobv );
85 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename MT3 >
86 inline void gesvd( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
87 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V,
char jobu,
char jobv );
111 template<
typename MT
115 inline DisableIf_< IsComplex< ElementType_<MT> > >
116 gesvd_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
char jobu,
char jobv )
118 using boost::numeric_cast;
122 BLAZE_INTERNAL_ASSERT( jobu !=
'O' || jobv !=
'O',
"Invalid combination of jobu and jobv detected" );
125 using ET = ElementType_<MT>;
127 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
128 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
129 int lda ( numeric_cast<int>( (~A).
spacing() ) );
132 const int minimum(
min( m, n ) );
133 const int maximum(
max( m, n ) );
135 int lwork(
max( 3*minimum + maximum, 5*minimum ) + 2 );
136 const std::unique_ptr<ET[]> work(
new ET[lwork] );
138 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ), m, n, (~A).data(), lda,
139 (~s).data(),
nullptr, 1,
nullptr, 1, work.get(), lwork, &info );
170 template<
typename MT
174 inline EnableIf_< IsComplex< ElementType_<MT> > >
175 gesvd_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s,
char jobu,
char jobv )
177 using boost::numeric_cast;
181 BLAZE_INTERNAL_ASSERT( jobu !=
'O' || jobv !=
'O',
"Invalid combination of jobu and jobv detected" );
184 using CT = ElementType_<MT>;
185 using BT = UnderlyingElement_<CT>;
187 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
188 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
189 int lda ( numeric_cast<int>( (~A).
spacing() ) );
192 const int minimum(
min( m, n ) );
193 const int maximum(
max( m, n ) );
195 int lwork( 2*minimum + maximum + 2 );
196 const std::unique_ptr<CT[]> work (
new CT[lwork] );
197 const std::unique_ptr<BT[]> rwork(
new BT[5*minimum] );
199 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ), m, n, (~A).data(), lda,
200 (~s).data(),
nullptr, 1,
nullptr, 1, work.get(), lwork, rwork.get(), &info );
296 template<
typename MT
311 const size_t M( (~A).
rows() );
312 const size_t N( (~A).
columns() );
313 const size_t mindim(
min( M, N ) );
315 if( jobu !=
'O' && jobu !=
'N' ) {
319 if( jobv !=
'O' && jobv !=
'N' ) {
323 if( jobu ==
'O' && jobv ==
'O' ) {
327 resize( ~s, mindim,
false );
329 if( M == 0UL || N == 0UL ) {
333 gesvd_backend( ~A, ~s, jobu, jobv );
358 template<
typename MT1
367 using boost::numeric_cast;
378 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
379 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
380 int lda ( numeric_cast<int>( (~A).
spacing() ) );
381 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
384 const int minimum(
min( m, n ) );
385 const int maximum(
max( m, n ) );
387 int lwork(
max( 3*minimum + maximum, 5*minimum ) + 2 );
388 const std::unique_ptr<ET[]> work(
new ET[lwork] );
390 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
391 m, n, (~A).data(), lda, (~s).data(),
392 ( SO ? (~U).data() :
nullptr ), ( SO ? ldu : 1 ),
393 ( SO ?
nullptr : (~U).data() ), ( SO ? 1 : ldu ),
394 work.get(), lwork, &info );
426 template<
typename MT1
435 using boost::numeric_cast;
447 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
448 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
449 int lda ( numeric_cast<int>( (~A).
spacing() ) );
450 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
453 const int minimum(
min( m, n ) );
454 const int maximum(
max( m, n ) );
456 int lwork( 2*minimum + maximum + 2 );
457 const std::unique_ptr<CT[]> work (
new CT[lwork] );
458 const std::unique_ptr<BT[]> rwork(
new BT[5*minimum] );
460 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
461 m, n, (~A).data(), lda, (~s).data(),
462 ( SO ? (~U).data() :
nullptr ), ( SO ? ldu : 1 ),
463 ( SO ?
nullptr : (~U).data() ), ( SO ? 1 : ldu ),
464 work.get(), lwork, rwork.get(), &info );
577 template<
typename MT1
599 const size_t M( (~A).
rows() );
600 const size_t N( (~A).
columns() );
601 const size_t mindim(
min( M, N ) );
603 if( jobu !=
'A' && jobu !=
'S' && jobu !=
'N' ) {
607 if( jobv !=
'O' && jobv !=
'N' ) {
611 resize( ~s, mindim,
false );
614 resize( ~U, M, ( jobu ==
'A' ? M : mindim ),
false );
617 if( M == 0UL || N == 0UL ) {
621 gesvd_backend( ~A, ~U, ~s, jobu, jobv );
646 template<
typename MT1
655 using boost::numeric_cast;
666 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
667 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
668 int lda ( numeric_cast<int>( (~A).
spacing() ) );
669 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
672 const int minimum(
min( m, n ) );
673 const int maximum(
max( m, n ) );
675 int lwork(
max( 3*minimum + maximum, 5*minimum ) + 2 );
676 const std::unique_ptr<ET[]> work(
new ET[lwork] );
678 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
679 m, n, (~A).data(), lda, (~s).data(),
680 ( SO ?
nullptr : (~V).data() ), ( SO ? 1 : ldv ),
681 ( SO ? (~V).data() :
nullptr ), ( SO ? ldv : 1 ),
682 work.get(), lwork, &info );
714 template<
typename MT1
723 using boost::numeric_cast;
735 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
736 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
737 int lda ( numeric_cast<int>( (~A).
spacing() ) );
738 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
741 const int minimum(
min( m, n ) );
742 const int maximum(
max( m, n ) );
744 int lwork( 2*minimum + maximum + 2 );
745 const std::unique_ptr<CT[]> work (
new CT[lwork] );
746 const std::unique_ptr<BT[]> rwork(
new BT[5*minimum] );
748 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
749 m, n, (~A).data(), lda, (~s).data(),
750 ( SO ?
nullptr : (~V).data() ), ( SO ? 1 : ldv ),
751 ( SO ? (~V).data() :
nullptr ), ( SO ? ldv : 1 ),
752 work.get(), lwork, rwork.get(), &info );
865 template<
typename MT1
887 const size_t M( (~A).
rows() );
888 const size_t N( (~A).
columns() );
889 const size_t mindim(
min( M, N ) );
891 if( jobu !=
'O' && jobu !=
'N' ) {
895 if( jobv !=
'A' && jobv !=
'S' && jobv !=
'N' ) {
899 resize( ~s, mindim,
false );
902 resize( ~V, ( jobv ==
'A' ? N : mindim ), N,
false );
905 if( M == 0UL || N == 0UL ) {
909 gesvd_backend( ~A, ~s, ~V, jobu, jobv );
935 template<
typename MT1
945 using boost::numeric_cast;
959 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
960 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
961 int lda ( numeric_cast<int>( (~A).
spacing() ) );
962 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
963 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
966 const int minimum(
min( m, n ) );
967 const int maximum(
max( m, n ) );
969 int lwork(
max( 3*minimum + maximum, 5*minimum ) + 2 );
970 const std::unique_ptr<ET[]> work(
new ET[lwork] );
972 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
973 m, n, (~A).data(), lda, (~s).data(),
974 ( SO ? (~U).data() : (~V).data() ), ( SO ? ldu : ldv ),
975 ( SO ? (~V).data() : (~U).data() ), ( SO ? ldv : ldu ),
976 work.get(), lwork, &info );
1009 template<
typename MT1
1019 using boost::numeric_cast;
1034 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
1035 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
1036 int lda ( numeric_cast<int>( (~A).
spacing() ) );
1037 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
1038 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
1041 const int minimum(
min( m, n ) );
1042 const int maximum(
max( m, n ) );
1044 int lwork( 2*minimum + maximum + 2 );
1045 const std::unique_ptr<CT[]> work (
new CT[lwork] );
1046 const std::unique_ptr<BT[]> rwork(
new BT[5*minimum] );
1048 gesvd( ( SO ? jobu : jobv ), ( SO ? jobv : jobu ),
1049 m, n, (~A).data(), lda, (~s).data(),
1050 ( SO ? (~U).data() : (~V).data() ), ( SO ? ldu : ldv ),
1051 ( SO ? (~V).data() : (~U).data() ), ( SO ? ldv : ldu ),
1052 work.get(), lwork, rwork.get(), &info );
1172 template<
typename MT1
1200 const size_t M( (~A).
rows() );
1201 const size_t N( (~A).
columns() );
1202 const size_t mindim(
min( M, N ) );
1204 if( jobu !=
'A' && jobu !=
'S' && jobu !=
'N' ) {
1208 if( jobv !=
'A' && jobv !=
'S' && jobv !=
'N' ) {
1212 resize( ~s, mindim,
false );
1215 resize( ~U, M, ( jobu ==
'A' ? M : mindim ),
false );
1216 resize( ~V, ( jobv ==
'A' ? N : mindim ), N,
false );
1219 if( M == 0UL || N == 0UL ) {
1223 gesvd_backend( ~A, ~U, ~s, ~V, jobu, jobv );
#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.
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:102
Header file for auxiliary alias declarations.
void gesvd(char jobu, char jobv, int m, int n, float *A, int lda, float *s, float *U, int ldu, float *V, int ldv, float *work, int lwork, int *info)
LAPACK kernel for the singular value decomposition (SVD) of the given dense general single precision ...
Definition: gesvd.h:161
Header file for mathematical functions.
#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
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:261
#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 CLAPACK gesvd wrapper functions.
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1755
Header file for the DenseVector base class.
Header file for the UnderlyingElement type trait.
Constraint on the data type.
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1802
#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:71
Constraint on the data type.
Header file for the DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the DenseMatrix base class.
typename UnderlyingElement< T >::Type UnderlyingElement_
Auxiliary alias declaration for the UnderlyingElement type trait.The UnderlyingElement_ alias declara...
Definition: UnderlyingElement.h:133
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:336
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:544
Constraint on the data type.
Header file for the EnableIf class template.
Header file for run time assertion macros.
#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
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:320
#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.
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:677
Header file for the IsResizable type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101