35 #ifndef _BLAZE_MATH_LAPACK_GESDD_H_ 36 #define _BLAZE_MATH_LAPACK_GESDD_H_ 44 #include <boost/cast.hpp> 74 template<
typename MT,
bool SO,
typename VT,
bool TF >
75 inline void gesdd( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s );
77 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF >
78 inline void gesdd( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
79 DenseVector<VT,TF>& s,
char jobz );
81 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF >
82 inline void gesdd( DenseMatrix<MT1,SO>& A, DenseVector<VT,TF>& s,
83 DenseMatrix<MT2,SO>& V,
char jobz );
85 template<
typename MT1,
bool SO,
typename MT2,
typename VT,
bool TF,
typename MT3 >
86 inline void gesdd( DenseMatrix<MT1,SO>& A, DenseMatrix<MT2,SO>& U,
87 DenseVector<VT,TF>& s, DenseMatrix<MT3,SO>& V,
char jobz );
109 template<
typename MT
113 inline DisableIf_< IsComplex< ElementType_<MT> > >
114 gesdd_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s )
116 using boost::numeric_cast;
120 using ET = ElementType_<MT>;
122 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
123 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
124 int lda ( numeric_cast<int>( (~A).
spacing() ) );
127 const int minimum(
min( m, n ) );
128 const int maximum(
max( m, n ) );
130 int lwork( 3*minimum +
max( maximum, 7*minimum ) + 2 );
131 const std::unique_ptr<ET[]> work(
new ET[lwork] );
132 const std::unique_ptr<int[]> iwork(
new int[8*minimum] );
134 gesdd(
'N', m, n, (~A).data(), lda, (~s).data(),
135 nullptr, 1,
nullptr, 1, work.get(), lwork, iwork.get(), &info );
164 template<
typename MT
168 inline EnableIf_< IsComplex< ElementType_<MT> > >
169 gesdd_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& s )
171 using boost::numeric_cast;
175 using CT = ElementType_<MT>;
176 using BT = UnderlyingElement_<CT>;
178 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
179 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
180 int lda ( numeric_cast<int>( (~A).
spacing() ) );
183 const int minimum(
min( m, n ) );
184 const int maximum(
max( m, n ) );
186 int lwork( 2*minimum + maximum + 2 );
187 const std::unique_ptr<CT[]> work(
new CT[lwork] );
188 const std::unique_ptr<BT[]> rwork(
new BT[7*minimum] );
189 const std::unique_ptr<int[]> iwork(
new int[8*minimum] );
191 gesdd(
'N', m, n, (~A).data(), lda, (~s).data(),
192 nullptr, 1,
nullptr, 1, work.get(), lwork, rwork.get(), iwork.get(), &info );
266 template<
typename MT
281 const size_t M( (~A).
rows() );
282 const size_t N( (~A).
columns() );
283 const size_t mindim(
min( M, N ) );
285 resize( ~s, mindim,
false );
287 if( M == 0UL || N == 0 ) {
291 gesdd_backend( A, s );
315 template<
typename MT1
324 using boost::numeric_cast;
333 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
334 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
335 int lda ( numeric_cast<int>( (~A).
spacing() ) );
336 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
339 const int minimum(
min( m, n ) );
340 const int maximum(
max( m, n ) );
342 int lwork( ( jobz ==
'O' )
343 ?( 3*minimum +
max( maximum, 5*minimum*minimum + 4*maximum ) + 2 )
344 :( 3*minimum +
max( maximum, 7*minimum ) + 2 ) );
345 const std::unique_ptr<ET[]> work(
new ET[lwork] );
346 const std::unique_ptr<int[]> iwork(
new int[8*minimum] );
348 gesdd( jobz, m, n, (~A).data(), lda, (~s).data(),
349 ( SO ? (~U).data() :
nullptr ), ( SO ? ldu : 1 ),
350 ( SO ?
nullptr : (~U).data() ), ( SO ? 1 : ldu ),
351 work.get(), lwork, iwork.get(), &info );
382 template<
typename MT1
391 using boost::numeric_cast;
401 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
402 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
403 int lda ( numeric_cast<int>( (~A).
spacing() ) );
404 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
407 const int minimum(
min( m, n ) );
408 const int maximum(
max( m, n ) );
410 int lwork( ( jobz ==
'O' )
411 ?( 2*minimum*minimum + 2*minimum + maximum + 2 )
412 :( 2*minimum + maximum + 2 ) );
413 const int lrwork( ( jobz ==
'O' )
414 ?(
max( 5*minimum*minimum + 5*minimum,
415 2*maximum*minimum + 2*minimum*minimum + minimum ) )
417 const std::unique_ptr<CT[]> work(
new CT[lwork] );
418 const std::unique_ptr<BT[]> rwork(
new BT[lrwork] );
419 const std::unique_ptr<int[]> iwork(
new int[8*minimum] );
421 gesdd( jobz, m, n, (~A).data(), lda, (~s).data(),
422 ( SO ? (~U).data() :
nullptr ), ( SO ? ldu : 1 ),
423 ( SO ?
nullptr : (~U).data() ), ( SO ? 1 : ldu ),
424 work.get(), lwork, rwork.get(), iwork.get(), &info );
525 template<
typename MT1
547 const size_t M( (~A).
rows() );
548 const size_t N( (~A).
columns() );
549 const size_t mindim(
min( M, N ) );
551 if( jobz !=
'O' && jobz !=
'N' ) {
555 if( jobz ==
'O' && M >= N ) {
559 resize( ~s, mindim,
false );
562 resize( ~U, M, M,
false );
565 if( (~A).
rows() == 0UL || (~A).
columns() == 0UL ) {
569 gesdd_backend( ~A, ~U, ~s, jobz );
593 template<
typename MT1
602 using boost::numeric_cast;
611 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
612 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
613 int lda ( numeric_cast<int>( (~A).
spacing() ) );
614 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
617 const int minimum(
min( m, n ) );
618 const int maximum(
max( m, n ) );
620 int lwork( ( jobz ==
'O' )
621 ?( 3*minimum +
max( maximum, 5*minimum*minimum + 4*maximum + 2 ) )
622 :( 3*minimum +
max( maximum, 7*minimum ) + 2 ) );
623 const std::unique_ptr<ET[]> work(
new ET[lwork] );
624 const std::unique_ptr<int[]> iwork(
new int[8*minimum] );
626 gesdd( jobz, m, n, (~A).data(), lda, (~s).data(),
627 ( SO ?
nullptr : (~V).data() ), ( SO ? 1 : ldv ),
628 ( SO ? (~V).data() :
nullptr ), ( SO ? ldv : 1 ),
629 work.get(), lwork, iwork.get(), &info );
660 template<
typename MT1
669 using boost::numeric_cast;
679 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
680 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
681 int lda ( numeric_cast<int>( (~A).
spacing() ) );
682 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
685 const int minimum(
min( m, n ) );
686 const int maximum(
max( m, n ) );
688 int lwork( ( jobz ==
'O' )
689 ?( 2*minimum*minimum + 2*minimum + maximum + 2 )
690 :( 2*minimum + maximum + 2 ) );
691 const int lrwork( ( jobz ==
'O' )
692 ?(
max( 5*minimum*minimum + 5*minimum,
693 2*maximum*minimum + 2*minimum*minimum + minimum ) )
695 const std::unique_ptr<CT[]> work(
new CT[lwork] );
696 const std::unique_ptr<BT[]> rwork(
new BT[lrwork] );
697 const std::unique_ptr<int[]> iwork(
new int[8*minimum] );
699 gesdd( jobz, m, n, (~A).data(), lda, (~s).data(),
700 ( SO ?
nullptr : (~V).data() ), ( SO ? 1 : ldv ),
701 ( SO ? (~V).data() :
nullptr ), ( SO ? ldv : 1 ),
702 work.get(), lwork, rwork.get(), iwork.get(), &info );
794 template<
typename MT1
816 const size_t M( (~A).
rows() );
817 const size_t N( (~A).
columns() );
818 const size_t mindim(
min( M, N ) );
820 if( jobz !=
'O' && jobz !=
'N' ) {
824 if( jobz ==
'O' && M < N ) {
828 resize( ~s, mindim,
false );
831 resize( ~V, N, N,
false );
834 if( (~A).
rows() == 0UL || (~A).
columns() == 0UL ) {
838 gesdd_backend( ~A, ~s, ~V, jobz );
863 template<
typename MT1
873 using boost::numeric_cast;
886 int m ( numeric_cast<int>( SO ? (~A).
rows() : (~A).
columns() ) );
887 int n ( numeric_cast<int>( SO ? (~A).
columns() : (~A).
rows() ) );
888 int lda ( numeric_cast<int>( (~A).
spacing() ) );
889 int ldu ( numeric_cast<int>( (~U).
spacing() ) );
890 int ldv ( numeric_cast<int>( (~V).
spacing() ) );
893 const int minimum(
min( m, n ) );
894 const int maximum(
max( m, n ) );
896 int lwork( 4*minimum*minimum + 6*minimum + maximum + 2 );
897 const std::unique_ptr<ET[]> work(
new ET[lwork] );
898 const std::unique_ptr<int[]> iwork(
new int[8*minimum] );
900 gesdd( jobz, m, n, (~A).data(), lda, (~s).data(),
901 ( SO ? (~U).data() : (~V).data() ), ( SO ? ldu : ldv ),
902 ( SO ? (~V).data() : (~U).data() ), ( SO ? ldv : ldu ),
903 work.get(), lwork, iwork.get(), &info );
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( 4*minimum*minimum + 6*minimum + maximum + 2 );
970 const int lrwork(
max( 5*minimum*minimum + 5*minimum,
971 2*maximum*minimum + 2*minimum*minimum + minimum ) );
972 const std::unique_ptr<CT[]> work(
new CT[lwork] );
973 const std::unique_ptr<BT[]> rwork(
new BT[lrwork] );
974 const std::unique_ptr<int[]> iwork(
new int[8*minimum] );
976 gesdd( jobz, m, n, (~A).data(), lda, (~s).data(),
977 ( SO ? (~U).data() : (~V).data() ), ( SO ? ldu : ldv ),
978 ( SO ? (~V).data() : (~U).data() ), ( SO ? ldv : ldu ),
979 work.get(), lwork, rwork.get(), iwork.get(), &info );
1093 template<
typename MT1
1121 const size_t M( (~A).
rows() );
1122 const size_t N( (~A).
columns() );
1123 const size_t mindim(
min( M, N ) );
1125 if( jobz !=
'A' && jobz !=
'S' && jobz !=
'N' ) {
1129 resize( ~s, mindim,
false );
1132 resize( ~U, M, ( jobz ==
'A' ? M : mindim ),
false );
1133 resize( ~V, ( jobz ==
'A' ? N : mindim ), N,
false );
1136 if( (~A).
rows() == 0UL || (~A).
columns() == 0UL ) {
1140 gesdd_backend( ~A, ~U, ~s, ~V, jobz );
#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.
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
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
void gesdd(char jobz, int m, int n, float *A, int lda, 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: gesdd.h:163
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.
Header file for the CLAPACK gesdd wrapper functions.
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