Mercurial > octave
changeset 22437:0aee8b620864
gsvd: move new class into the octave::math namespace.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Sun, 04 Sep 2016 17:37:35 +0100 |
parents | 09005ac7d56c |
children | 5a838a892adb |
files | libinterp/corefcn/gsvd.cc liboctave/numeric/gsvd.cc liboctave/numeric/gsvd.h |
diffstat | 3 files changed, 366 insertions(+), 345 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/gsvd.cc Sun Sep 04 17:12:03 2016 +0100 +++ b/libinterp/corefcn/gsvd.cc Sun Sep 04 17:37:35 2016 +0100 @@ -34,21 +34,21 @@ template <typename T> -static typename gsvd<T>::Type +static typename octave::math::gsvd<T>::Type gsvd_type (int nargout) { return ((nargout == 0 || nargout == 1) - ? gsvd<T>::Type::sigma_only - : (nargout > 5) ? gsvd<T>::Type::std : gsvd<T>::Type::economy); + ? octave::math::gsvd<T>::Type::sigma_only + : (nargout > 5) ? octave::math::gsvd<T>::Type::std + : octave::math::gsvd<T>::Type::economy); } - // Named like this to avoid conflicts with the gsvd class. template <typename T> static octave_value_list function_gsvd (const T& A, const T& B, const octave_idx_type nargout) { - gsvd<T> result (A, B, gsvd_type<T> (nargout)); + octave::math::gsvd<T> result (A, B, gsvd_type<T> (nargout)); octave_value_list retval (nargout); if (nargout < 2)
--- a/liboctave/numeric/gsvd.cc Sun Sep 04 17:12:03 2016 +0100 +++ b/liboctave/numeric/gsvd.cc Sun Sep 04 17:37:35 2016 +0100 @@ -32,326 +32,340 @@ #include "dDiagMatrix.h" #include "fDiagMatrix.h" - -template <> -void -gsvd<Matrix>::ggsvd (char& jobu, char& jobv, char& jobq, octave_idx_type m, - octave_idx_type n, octave_idx_type p, octave_idx_type& k, - octave_idx_type& l, double *tmp_dataA, octave_idx_type m1, - double *tmp_dataB, octave_idx_type p1, Matrix& alpha, - Matrix& beta, double *u, octave_idx_type nrow_u, double *v, - octave_idx_type nrow_v, double *q, octave_idx_type nrow_q, - Matrix& work, octave_idx_type* iwork, - octave_idx_type& info) -{ - F77_XFCN (dggsvd, DGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), - F77_CONST_CHAR_ARG2 (&jobv, 1), - F77_CONST_CHAR_ARG2 (&jobq, 1), - m, n, p, k, l, tmp_dataA, m1, - tmp_dataB, p1, alpha.fortran_vec (), - beta.fortran_vec (), u, nrow_u, - v, nrow_v, q, nrow_q, work.fortran_vec (), - iwork, info - F77_CHAR_ARG_LEN (1) - F77_CHAR_ARG_LEN (1) - F77_CHAR_ARG_LEN (1))); -} - -template <> -void -gsvd<FloatMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, octave_idx_type m, - octave_idx_type n, octave_idx_type p, - octave_idx_type& k, octave_idx_type& l, - float *tmp_dataA, octave_idx_type m1, - float *tmp_dataB, octave_idx_type p1, - FloatMatrix& alpha, FloatMatrix& beta, float *u, - octave_idx_type nrow_u, float *v, - octave_idx_type nrow_v, float *q, - octave_idx_type nrow_q, FloatMatrix& work, - octave_idx_type* iwork, octave_idx_type& info) -{ - F77_XFCN (sggsvd, SGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), - F77_CONST_CHAR_ARG2 (&jobv, 1), - F77_CONST_CHAR_ARG2 (&jobq, 1), - m, n, p, k, l, tmp_dataA, m1, - tmp_dataB, p1, alpha.fortran_vec (), - beta.fortran_vec (), u, nrow_u, - v, nrow_v, q, nrow_q, work.fortran_vec (), - iwork, info - F77_CHAR_ARG_LEN (1) - F77_CHAR_ARG_LEN (1) - F77_CHAR_ARG_LEN (1))); -} - -template <> -void -gsvd<ComplexMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, - octave_idx_type m, octave_idx_type n, - octave_idx_type p, octave_idx_type& k, - octave_idx_type& l, Complex *tmp_dataA, - octave_idx_type m1, Complex *tmp_dataB, - octave_idx_type p1, Matrix& alpha, - Matrix& beta, Complex *u, octave_idx_type nrow_u, - Complex *v, octave_idx_type nrow_v, Complex *q, - octave_idx_type nrow_q, ComplexMatrix& work, - octave_idx_type* iwork, octave_idx_type& info) -{ - Matrix rwork(2*n, 1); - F77_XFCN (zggsvd, ZGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), - F77_CONST_CHAR_ARG2 (&jobv, 1), - F77_CONST_CHAR_ARG2 (&jobq, 1), - m, n, p, k, l, F77_DBLE_CMPLX_ARG (tmp_dataA), m1, - F77_DBLE_CMPLX_ARG (tmp_dataB), p1, - alpha.fortran_vec (), beta.fortran_vec (), - F77_DBLE_CMPLX_ARG (u), nrow_u, - F77_DBLE_CMPLX_ARG (v), nrow_v, - F77_DBLE_CMPLX_ARG (q), nrow_q, - F77_DBLE_CMPLX_ARG (work.fortran_vec ()), - rwork.fortran_vec (), iwork, info - F77_CHAR_ARG_LEN (1) - F77_CHAR_ARG_LEN (1) - F77_CHAR_ARG_LEN (1))); -} - -template <> -void -gsvd<FloatComplexMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, - octave_idx_type m, octave_idx_type n, - octave_idx_type p, octave_idx_type& k, - octave_idx_type& l, FloatComplex *tmp_dataA, - octave_idx_type m1, FloatComplex *tmp_dataB, - octave_idx_type p1, FloatMatrix& alpha, - FloatMatrix& beta, FloatComplex *u, - octave_idx_type nrow_u, FloatComplex *v, - octave_idx_type nrow_v, FloatComplex *q, - octave_idx_type nrow_q, - FloatComplexMatrix& work, - octave_idx_type* iwork, octave_idx_type& info) +namespace octave { - FloatMatrix rwork(2*n, 1); - F77_XFCN (cggsvd, CGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), - F77_CONST_CHAR_ARG2 (&jobv, 1), - F77_CONST_CHAR_ARG2 (&jobq, 1), - m, n, p, k, l, F77_CMPLX_ARG (tmp_dataA), m1, - F77_CMPLX_ARG (tmp_dataB), p1, - alpha.fortran_vec (), beta.fortran_vec (), - F77_CMPLX_ARG (u), nrow_u, - F77_CMPLX_ARG (v), nrow_v, - F77_CMPLX_ARG (q), nrow_q, - F77_CMPLX_ARG (work.fortran_vec ()), - rwork.fortran_vec (), iwork, info - F77_CHAR_ARG_LEN (1) - F77_CHAR_ARG_LEN (1) - F77_CHAR_ARG_LEN (1))); -} - -template <typename T> -T -gsvd<T>::left_singular_matrix_A (void) const -{ - if (type == gsvd::Type::sigma_only) + namespace math + { + template <> + void + gsvd<Matrix>::ggsvd (char& jobu, char& jobv, char& jobq, + octave_idx_type m, octave_idx_type n, + octave_idx_type p, + octave_idx_type& k, octave_idx_type& l, + double *tmp_dataA, octave_idx_type m1, + double *tmp_dataB, octave_idx_type p1, Matrix& alpha, + Matrix& beta, double *u, octave_idx_type nrow_u, + double *v, octave_idx_type nrow_v, double *q, + octave_idx_type nrow_q, + Matrix& work, octave_idx_type* iwork, + octave_idx_type& info) { - (*current_liboctave_error_handler) - ("gsvd: U not computed because type == gsvd::sigma_only"); - return T (); + F77_XFCN (dggsvd, DGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), + F77_CONST_CHAR_ARG2 (&jobv, 1), + F77_CONST_CHAR_ARG2 (&jobq, 1), + m, n, p, k, l, tmp_dataA, m1, + tmp_dataB, p1, alpha.fortran_vec (), + beta.fortran_vec (), u, nrow_u, + v, nrow_v, q, nrow_q, work.fortran_vec (), + iwork, info + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1))); } - else - return left_smA; -} -template <typename T> -T -gsvd<T>::left_singular_matrix_B (void) const -{ - if (type == gsvd::Type::sigma_only) + template <> + void + gsvd<FloatMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, + octave_idx_type m, octave_idx_type n, + octave_idx_type p, + octave_idx_type& k, octave_idx_type& l, + float *tmp_dataA, octave_idx_type m1, + float *tmp_dataB, octave_idx_type p1, + FloatMatrix& alpha, FloatMatrix& beta, float *u, + octave_idx_type nrow_u, float *v, + octave_idx_type nrow_v, float *q, + octave_idx_type nrow_q, FloatMatrix& work, + octave_idx_type* iwork, octave_idx_type& info) { - (*current_liboctave_error_handler) - ("gsvd: V not computed because type == gsvd::sigma_only"); - return T (); + F77_XFCN (sggsvd, SGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), + F77_CONST_CHAR_ARG2 (&jobv, 1), + F77_CONST_CHAR_ARG2 (&jobq, 1), + m, n, p, k, l, tmp_dataA, m1, + tmp_dataB, p1, alpha.fortran_vec (), + beta.fortran_vec (), u, nrow_u, + v, nrow_v, q, nrow_q, work.fortran_vec (), + iwork, info + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1))); } - else - return left_smB; -} - -template <typename T> -T -gsvd<T>::right_singular_matrix (void) const -{ - if (type == gsvd::Type::sigma_only) - { - (*current_liboctave_error_handler) - ("gsvd: X not computed because type == gsvd::sigma_only"); - return T (); - } - else - return right_sm; -} -template <typename T> -T -gsvd<T>::R_matrix (void) const -{ - if (type != gsvd::Type::std) + template <> + void + gsvd<ComplexMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, + octave_idx_type m, octave_idx_type n, + octave_idx_type p, octave_idx_type& k, + octave_idx_type& l, Complex *tmp_dataA, + octave_idx_type m1, Complex *tmp_dataB, + octave_idx_type p1, Matrix& alpha, + Matrix& beta, Complex *u, + octave_idx_type nrow_u, + Complex *v, octave_idx_type nrow_v, Complex *q, + octave_idx_type nrow_q, ComplexMatrix& work, + octave_idx_type* iwork, octave_idx_type& info) { - (*current_liboctave_error_handler) - ("gsvd: R not computed because type != gsvd::std"); - return T (); + Matrix rwork(2*n, 1); + F77_XFCN (zggsvd, ZGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), + F77_CONST_CHAR_ARG2 (&jobv, 1), + F77_CONST_CHAR_ARG2 (&jobq, 1), + m, n, p, k, l, F77_DBLE_CMPLX_ARG (tmp_dataA), + m1, F77_DBLE_CMPLX_ARG (tmp_dataB), p1, + alpha.fortran_vec (), beta.fortran_vec (), + F77_DBLE_CMPLX_ARG (u), nrow_u, + F77_DBLE_CMPLX_ARG (v), nrow_v, + F77_DBLE_CMPLX_ARG (q), nrow_q, + F77_DBLE_CMPLX_ARG (work.fortran_vec ()), + rwork.fortran_vec (), iwork, info + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1))); } - else - return R; -} - -template <typename T> -gsvd<T>::gsvd (const T& a, const T& b, gsvd::Type gsvd_type) -{ - octave_idx_type info; - - octave_idx_type m = a.rows (); - octave_idx_type n = a.cols (); - octave_idx_type p = b.rows (); - - T atmp = a; - P *tmp_dataA = atmp.fortran_vec (); - - T btmp = b; - P *tmp_dataB = btmp.fortran_vec (); - char jobu = 'U'; - char jobv = 'V'; - char jobq = 'Q'; - - octave_idx_type nrow_u = m; - octave_idx_type nrow_v = p; - octave_idx_type nrow_q = n; - - octave_idx_type k, l; - - switch (gsvd_type) + template <> + void + gsvd<FloatComplexMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, + octave_idx_type m, octave_idx_type n, + octave_idx_type p, octave_idx_type& k, + octave_idx_type& l, + FloatComplex *tmp_dataA, + octave_idx_type m1, + FloatComplex *tmp_dataB, + octave_idx_type p1, FloatMatrix& alpha, + FloatMatrix& beta, FloatComplex *u, + octave_idx_type nrow_u, FloatComplex *v, + octave_idx_type nrow_v, FloatComplex *q, + octave_idx_type nrow_q, + FloatComplexMatrix& work, + octave_idx_type* iwork, + octave_idx_type& info) { - case gsvd<T>::Type::sigma_only: + FloatMatrix rwork(2*n, 1); + F77_XFCN (cggsvd, CGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), + F77_CONST_CHAR_ARG2 (&jobv, 1), + F77_CONST_CHAR_ARG2 (&jobq, 1), + m, n, p, k, l, F77_CMPLX_ARG (tmp_dataA), m1, + F77_CMPLX_ARG (tmp_dataB), p1, + alpha.fortran_vec (), beta.fortran_vec (), + F77_CMPLX_ARG (u), nrow_u, + F77_CMPLX_ARG (v), nrow_v, + F77_CMPLX_ARG (q), nrow_q, + F77_CMPLX_ARG (work.fortran_vec ()), + rwork.fortran_vec (), iwork, info + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1))); + } - // Note: for this case, both jobu and jobv should be 'N', but - // there seems to be a bug in dgesvd from Lapack V2.0. To - // demonstrate the bug, set both jobu and jobv to 'N' and find - // the singular values of [eye(3), eye(3)]. The result is - // [-sqrt(2), -sqrt(2), -sqrt(2)]. - // - // For Lapack 3.0, this problem seems to be fixed. + template <typename T> + T + gsvd<T>::left_singular_matrix_A (void) const + { + if (type == gsvd::Type::sigma_only) + { + (*current_liboctave_error_handler) + ("gsvd: U not computed because type == gsvd::sigma_only"); + return T (); + } + else + return left_smA; + } - jobu = 'N'; - jobv = 'N'; - jobq = 'N'; - nrow_u = nrow_v = nrow_q = 1; - break; - - default: - break; + template <typename T> + T + gsvd<T>::left_singular_matrix_B (void) const + { + if (type == gsvd::Type::sigma_only) + { + (*current_liboctave_error_handler) + ("gsvd: V not computed because type == gsvd::sigma_only"); + return T (); + } + else + return left_smB; } - type = gsvd_type; - - if (! (jobu == 'N' || jobu == 'O')) - left_smA.resize (nrow_u, m); - - P *u = left_smA.fortran_vec (); - - if (! (jobv == 'N' || jobv == 'O')) - left_smB.resize (nrow_v, p); + template <typename T> + T + gsvd<T>::right_singular_matrix (void) const + { + if (type == gsvd::Type::sigma_only) + { + (*current_liboctave_error_handler) + ("gsvd: X not computed because type == gsvd::sigma_only"); + return T (); + } + else + return right_sm; + } - P *v = left_smB.fortran_vec (); + template <typename T> + T + gsvd<T>::R_matrix (void) const + { + if (type != gsvd::Type::std) + { + (*current_liboctave_error_handler) + ("gsvd: R not computed because type != gsvd::std"); + return T (); + } + else + return R; + } - if (! (jobq == 'N' || jobq == 'O')) - right_sm.resize (nrow_q, n); + template <typename T> + gsvd<T>::gsvd (const T& a, const T& b, gsvd::Type gsvd_type) + { + octave_idx_type info; - P *q = right_sm.fortran_vec (); + octave_idx_type m = a.rows (); + octave_idx_type n = a.cols (); + octave_idx_type p = b.rows (); + + T atmp = a; + P *tmp_dataA = atmp.fortran_vec (); + + T btmp = b; + P *tmp_dataB = btmp.fortran_vec (); - octave_idx_type lwork = 3*n; - lwork = lwork > m ? lwork : m; - lwork = (lwork > p ? lwork : p) + n; + char jobu = 'U'; + char jobv = 'V'; + char jobq = 'Q'; + + octave_idx_type nrow_u = m; + octave_idx_type nrow_v = p; + octave_idx_type nrow_q = n; + + octave_idx_type k, l; - T work (lwork, 1); - real_matrix alpha (n, 1); - real_matrix beta (n, 1); + switch (gsvd_type) + { + case gsvd<T>::Type::sigma_only: + + // Note: for this case, both jobu and jobv should be 'N', but + // there seems to be a bug in dgesvd from Lapack V2.0. To + // demonstrate the bug, set both jobu and jobv to 'N' and find + // the singular values of [eye(3), eye(3)]. The result is + // [-sqrt(2), -sqrt(2), -sqrt(2)]. + // + // For Lapack 3.0, this problem seems to be fixed. - std::vector<octave_idx_type> iwork (n); + jobu = 'N'; + jobv = 'N'; + jobq = 'N'; + nrow_u = nrow_v = nrow_q = 1; + break; - gsvd<T>::ggsvd (jobu, jobv, jobq, m, n, p, k, l, - tmp_dataA, m, tmp_dataB, p, alpha, beta, u, - nrow_u, v, nrow_v, q, nrow_q, work, iwork.data (), info); + default: + break; + } + + type = gsvd_type; + + if (! (jobu == 'N' || jobu == 'O')) + left_smA.resize (nrow_u, m); + + P *u = left_smA.fortran_vec (); - if (f77_exception_encountered) - (*current_liboctave_error_handler) ("unrecoverable error in *ggsvd"); + if (! (jobv == 'N' || jobv == 'O')) + left_smB.resize (nrow_v, p); + + P *v = left_smB.fortran_vec (); + + if (! (jobq == 'N' || jobq == 'O')) + right_sm.resize (nrow_q, n); + + P *q = right_sm.fortran_vec (); + + octave_idx_type lwork = 3*n; + lwork = lwork > m ? lwork : m; + lwork = (lwork > p ? lwork : p) + n; - if (info < 0) - (*current_liboctave_error_handler) ("*ggsvd.f: argument %d illegal", -info); - else - { - if (info > 0) - (*current_liboctave_error_handler) - ("*ggsvd.f: Jacobi-type procedure failed to converge."); + T work (lwork, 1); + real_matrix alpha (n, 1); + real_matrix beta (n, 1); + + std::vector<octave_idx_type> iwork (n); + + gsvd<T>::ggsvd (jobu, jobv, jobq, m, n, p, k, l, + tmp_dataA, m, tmp_dataB, p, alpha, beta, u, + nrow_u, v, nrow_v, q, nrow_q, work, iwork.data (), info); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in *ggsvd"); + + if (info < 0) + (*current_liboctave_error_handler) ("*ggsvd.f: argument %d illegal", + -info); else { - octave_idx_type i, j; - - if (gsvd<T>::Type::std == gsvd_type) + if (info > 0) + (*current_liboctave_error_handler) + ("*ggsvd.f: Jacobi-type procedure failed to converge."); + else { - R.resize(k+l, k+l); - int astart = n-k-l; - if (m - k - l >= 0) + octave_idx_type i, j; + + if (gsvd<T>::Type::std == gsvd_type) { - astart = n-k-l; - // R is stored in A(1:K+L,N-K-L+1:N) - for (i = 0; i < k+l; i++) - for (j = 0; j < k+l; j++) - R.xelem (i, j) = atmp.xelem (i, astart + j); + R.resize(k+l, k+l); + int astart = n-k-l; + if (m - k - l >= 0) + { + astart = n-k-l; + // R is stored in A(1:K+L,N-K-L+1:N) + for (i = 0; i < k+l; i++) + for (j = 0; j < k+l; j++) + R.xelem (i, j) = atmp.xelem (i, astart + j); + } + else + { + // (R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N), + // ( 0 R22 R23 ) + + for (i = 0; i < m; i++) + for (j = 0; j < k+l; j++) + R.xelem (i, j) = atmp.xelem (i, astart + j); + // and R33 is stored in B(M-K+1:L,N+M-K-L+1:N) + for (i = k+l-1; i >=m; i--) + { + for (j = 0; j < m; j++) + R.xelem(i, j) = 0.0; + for (j = m; j < k+l; j++) + R.xelem (i, j) = btmp.xelem (i - k, astart + j); + } + } + } + + if (m-k-l >= 0) + { + // Fills in C and S + sigmaA.resize (l, l); + sigmaB.resize (l, l); + for (i = 0; i < l; i++) + { + sigmaA.dgxelem(i) = alpha.elem(k+i); + sigmaB.dgxelem(i) = beta.elem(k+i); + } } else { - // (R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N), - // ( 0 R22 R23 ) - - for (i = 0; i < m; i++) - for (j = 0; j < k+l; j++) - R.xelem (i, j) = atmp.xelem (i, astart + j); - // and R33 is stored in B(M-K+1:L,N+M-K-L+1:N) - for (i = k+l-1; i >=m; i--) + // Fills in C and S + sigmaA.resize (m-k, m-k); + sigmaB.resize (m-k, m-k); + for (i = 0; i < m-k; i++) { - for (j = 0; j < m; j++) - R.xelem(i, j) = 0.0; - for (j = m; j < k+l; j++) - R.xelem (i, j) = btmp.xelem (i - k, astart + j); + sigmaA.dgxelem(i) = alpha.elem(k+i); + sigmaB.dgxelem(i) = beta.elem(k+i); } } } - - if (m-k-l >= 0) - { - // Fills in C and S - sigmaA.resize (l, l); - sigmaB.resize (l, l); - for (i = 0; i < l; i++) - { - sigmaA.dgxelem(i) = alpha.elem(k+i); - sigmaB.dgxelem(i) = beta.elem(k+i); - } - } - else - { - // Fills in C and S - sigmaA.resize (m-k, m-k); - sigmaB.resize (m-k, m-k); - for (i = 0; i < m-k; i++) - { - sigmaA.dgxelem(i) = alpha.elem(k+i); - sigmaB.dgxelem(i) = beta.elem(k+i); - } - } } } + + // Instantiations we need. + template class gsvd<Matrix>; + template class gsvd<FloatMatrix>; + template class gsvd<ComplexMatrix>; + template class gsvd<FloatComplexMatrix>; + } } - -// Instantiations we need. -template class gsvd<Matrix>; -template class gsvd<FloatMatrix>; -template class gsvd<ComplexMatrix>; -template class gsvd<FloatComplexMatrix>;
--- a/liboctave/numeric/gsvd.h Sun Sep 04 17:12:03 2016 +0100 +++ b/liboctave/numeric/gsvd.h Sun Sep 04 17:37:35 2016 +0100 @@ -20,76 +20,83 @@ #include "octave-config.h" -template <typename T> -class -gsvd +namespace octave { -public: - - enum class Type + namespace math { - std, - economy, - sigma_only - }; + template <typename T> + class + gsvd + { + public: - gsvd (void) : sigmaA (), sigmaB (), left_smA (), left_smB (), right_sm () { } + enum class Type + { + std, + economy, + sigma_only + }; - gsvd (const T& a, const T& b, gsvd::Type gsvd_type = gsvd<T>::Type::economy); + gsvd (void) : sigmaA (), sigmaB (), left_smA (), left_smB (), right_sm () + { } - gsvd (const gsvd& a) - : type (a.type), - sigmaA (a.sigmaA), sigmaB (a.sigmaB), - left_smA (a.left_smA), left_smB (a.left_smB), right_sm (a.right_sm), - R(a.R) { } + gsvd (const T& a, const T& b, + gsvd::Type gsvd_type = gsvd<T>::Type::economy); + + gsvd (const gsvd& a) + : type (a.type), + sigmaA (a.sigmaA), sigmaB (a.sigmaB), + left_smA (a.left_smA), left_smB (a.left_smB), right_sm (a.right_sm), + R(a.R) { } - gsvd& operator = (const gsvd& a) - { - if (this != &a) + gsvd& operator = (const gsvd& a) { - type = a.type; - sigmaA = a.sigmaA; - sigmaB = a.sigmaB; - left_smA = a.left_smA; - left_smB = a.left_smB; - right_sm = a.right_sm; - R = a.R; + if (this != &a) + { + type = a.type; + sigmaA = a.sigmaA; + sigmaB = a.sigmaB; + left_smA = a.left_smA; + left_smB = a.left_smB; + right_sm = a.right_sm; + R = a.R; + } + + return *this; } - return *this; - } + ~gsvd (void) { } - ~gsvd (void) { } - - typename T::real_diag_matrix_type - singular_values_A (void) const { return sigmaA; } + typename T::real_diag_matrix_type + singular_values_A (void) const { return sigmaA; } - typename T::real_diag_matrix_type - singular_values_B (void) const { return sigmaB; } + typename T::real_diag_matrix_type + singular_values_B (void) const { return sigmaB; } - T left_singular_matrix_A (void) const; - T left_singular_matrix_B (void) const; + T left_singular_matrix_A (void) const; + T left_singular_matrix_B (void) const; - T right_singular_matrix (void) const; - T R_matrix (void) const; + T right_singular_matrix (void) const; + T R_matrix (void) const; -private: - typedef typename T::value_type P; - typedef typename T::real_matrix_type real_matrix; + private: + typedef typename T::value_type P; + typedef typename T::real_matrix_type real_matrix; - gsvd::Type type; - typename T::real_diag_matrix_type sigmaA, sigmaB; - T left_smA, left_smB; - T right_sm, R; + gsvd::Type type; + typename T::real_diag_matrix_type sigmaA, sigmaB; + T left_smA, left_smB; + T right_sm, R; - void ggsvd (char& jobu, char& jobv, char& jobq, octave_idx_type m, - octave_idx_type n, octave_idx_type p, octave_idx_type& k, - octave_idx_type& l, P *tmp_dataA, octave_idx_type m1, - P *tmp_dataB, octave_idx_type p1, real_matrix& alpha, - real_matrix& beta, P *u, octave_idx_type nrow_u, P *v, - octave_idx_type nrow_v, P *q, octave_idx_type nrow_q, T& work, - octave_idx_type* iwork, octave_idx_type& info); -}; + void ggsvd (char& jobu, char& jobv, char& jobq, octave_idx_type m, + octave_idx_type n, octave_idx_type p, octave_idx_type& k, + octave_idx_type& l, P *tmp_dataA, octave_idx_type m1, + P *tmp_dataB, octave_idx_type p1, real_matrix& alpha, + real_matrix& beta, P *u, octave_idx_type nrow_u, P *v, + octave_idx_type nrow_v, P *q, octave_idx_type nrow_q, T& work, + octave_idx_type* iwork, octave_idx_type& info); + }; + } +} #endif -