31 #include <unordered_map>
47 static std::unordered_map<std::string, void *> gsvd_fcn;
49 static bool have_DGGSVD3 =
false;
50 static bool gsvd_initialized =
false;
53 #define xSTRINGIZE(x) #x
54 #define STRINGIZE(x) xSTRINGIZE(x)
64 (*current_liboctave_error_handler)
65 (
"gsvd: unable to query LAPACK library");
85 gsvd_initialized =
true;
125 struct real_ggsvd3_ptr
157 template<
class T1,
class T2>
158 struct comp_ggsvd_ptr
190 template<
class T1,
class T2>
191 struct comp_ggsvd3_ptr
229 typedef comp_ggsvd_ptr<F77_DBLE_CMPLX, F77_DBLE>::type
zggsvd_type;
240 double *tmp_dataA,
F77_INT m1,
double *tmp_dataB,
246 if (! gsvd_initialized)
252 f_ptr (F77_CONST_CHAR_ARG2 (&jobu, 1),
253 F77_CONST_CHAR_ARG2 (&jobv, 1),
254 F77_CONST_CHAR_ARG2 (&jobq, 1),
255 m,
n, p, k, l, tmp_dataA, m1, tmp_dataB, p1,
257 u, nrow_u, v, nrow_v, q, nrow_q,
258 work, lwork, iwork, info
261 F77_CHAR_ARG_LEN (1));
266 f_ptr (F77_CONST_CHAR_ARG2 (&jobu, 1),
267 F77_CONST_CHAR_ARG2 (&jobv, 1),
268 F77_CONST_CHAR_ARG2 (&jobq, 1),
269 m,
n, p, k, l, tmp_dataA, m1, tmp_dataB, p1,
271 u, nrow_u, v, nrow_v, q, nrow_q,
275 F77_CHAR_ARG_LEN (1));
283 float *tmp_dataA,
F77_INT m1,
float *tmp_dataB,
286 float *v,
F77_INT nrow_v,
float *q,
290 if (! gsvd_initialized)
296 f_ptr (F77_CONST_CHAR_ARG2 (&jobu, 1),
297 F77_CONST_CHAR_ARG2 (&jobv, 1),
298 F77_CONST_CHAR_ARG2 (&jobq, 1),
299 m,
n, p, k, l, tmp_dataA, m1, tmp_dataB, p1,
301 u, nrow_u, v, nrow_v, q, nrow_q,
302 work, lwork, iwork, info
305 F77_CHAR_ARG_LEN (1));
310 f_ptr (F77_CONST_CHAR_ARG2 (&jobu, 1),
311 F77_CONST_CHAR_ARG2 (&jobv, 1),
312 F77_CONST_CHAR_ARG2 (&jobq, 1),
313 m,
n, p, k, l, tmp_dataA, m1, tmp_dataB, p1,
315 u, nrow_u, v, nrow_v, q, nrow_q,
319 F77_CHAR_ARG_LEN (1));
334 if (! gsvd_initialized)
342 f_ptr (F77_CONST_CHAR_ARG2 (&jobu, 1),
343 F77_CONST_CHAR_ARG2 (&jobv, 1),
344 F77_CONST_CHAR_ARG2 (&jobq, 1),
353 lwork, rwork, iwork, info
356 F77_CHAR_ARG_LEN (1));
361 f_ptr (F77_CONST_CHAR_ARG2 (&jobu, 1),
362 F77_CONST_CHAR_ARG2 (&jobv, 1),
363 F77_CONST_CHAR_ARG2 (&jobq, 1),
375 F77_CHAR_ARG_LEN (1));
393 if (! gsvd_initialized)
401 f_ptr (F77_CONST_CHAR_ARG2 (&jobu, 1),
402 F77_CONST_CHAR_ARG2 (&jobv, 1),
403 F77_CONST_CHAR_ARG2 (&jobq, 1),
415 F77_CHAR_ARG_LEN (1));
420 f_ptr (F77_CONST_CHAR_ARG2 (&jobu, 1),
421 F77_CONST_CHAR_ARG2 (&jobv, 1),
422 F77_CONST_CHAR_ARG2 (&jobq, 1),
434 F77_CHAR_ARG_LEN (1));
438 template <
typename T>
443 (*current_liboctave_error_handler)
444 (
"gsvd: U not computed because type == gsvd::sigma_only");
449 template <
typename T>
454 (*current_liboctave_error_handler)
455 (
"gsvd: V not computed because type == gsvd::sigma_only");
460 template <
typename T>
465 (*current_liboctave_error_handler)
466 (
"gsvd: X not computed because type == gsvd::sigma_only");
471 template <
typename T>
474 if (a.isempty () || b.isempty ())
475 (*current_liboctave_error_handler)
476 (
"gsvd: A and B cannot be empty matrices");
482 F77_INT p = to_f77_int (b.rows ());
485 P *tmp_dataA = atmp.fortran_vec ();
488 P *tmp_dataB = btmp.fortran_vec ();
513 jobu = jobv = jobq =
'N';
514 nrow_u = nrow_v = nrow_q = 1;
524 m_left_smA.resize (nrow_u,
m);
526 P *u = m_left_smA.fortran_vec ();
529 m_left_smB.resize (nrow_v, p);
531 P *v = m_left_smB.fortran_vec ();
534 m_right_sm.resize (nrow_q,
n);
536 P *q = m_right_sm.fortran_vec ();
538 real_matrix alpha (
n, 1);
539 real_matrix beta (
n, 1);
543 if (! gsvd_initialized)
553 tmp_dataA,
m, tmp_dataB, p,
554 alpha, beta, u, nrow_u, v, nrow_v, q, nrow_q,
555 &work_tmp, lwork, iwork, info);
557 lwork =
static_cast<F77_INT> (std::abs (work_tmp));
568 tmp_dataA,
m, tmp_dataB, p,
569 alpha, beta, u, nrow_u, v, nrow_v, q, nrow_q,
570 work, lwork, iwork, info);
573 (*current_liboctave_error_handler)
574 (
"*ggsvd.f: argument %" OCTAVE_F77_INT_TYPE_FORMAT
" illegal",
578 (*current_liboctave_error_handler)
579 (
"*ggsvd.f: Jacobi-type procedure failed to converge");
592 for (i = 0; i < k+l; i++)
593 for (j = 0; j < k+l; j++)
594 R.xelem (i, j) = atmp.xelem (i, astart + j);
600 for (i = 0; i <
m; i++)
601 for (j = 0; j < k+l; j++)
602 R.xelem (i, j) = atmp.xelem (i, astart + j);
604 for (i =
m; i < k + l; i++)
605 for (j =
n - l - k +
m; j <
n; j++)
606 R.xelem (i, j) = btmp.xelem (i - k, j);
612 m_right_sm = m_right_sm * R.hermitian ();
632 m_sigmaA.resize (k+l, 1);
633 m_sigmaB.resize (k+l, 1);
637 for (i = 0; i < k; i++)
639 m_sigmaA.xelem (i) = 1.0;
640 m_sigmaB.xelem (i) = 0.0;
642 for (i = k, j = k+l-1; i < k+l; i++, j--)
644 m_sigmaA.xelem (i) = alpha.xelem (i);
645 m_sigmaB.xelem (i) = beta.xelem (i);
650 for (i = 0; i < k; i++)
652 m_sigmaA.xelem (i) = 1.0;
653 m_sigmaB.xelem (i) = 0.0;
655 for (i = k; i <
m; i++)
657 m_sigmaA.xelem (i) = alpha.xelem (i);
658 m_sigmaB.xelem (i) = beta.xelem (i);
660 for (i =
m; i < k+l; i++)
662 m_sigmaA.xelem (i) = 0.0;
663 m_sigmaB.xelem (i) = 1.0;
671 m_sigmaA.resize (
m,
n);
672 m_sigmaB.resize (p,
n);
674 for (i = 0; i < k; i++)
675 m_sigmaA.xelem (i, i) = 1.0;
677 for (i = 0; i < rank; i++)
679 m_sigmaA.xelem (k+i, k+i) = alpha.xelem (k+i);
680 m_sigmaB.xelem (i, k+i) = beta.xelem (k+i);
685 for (i =
m; i <
n; i++)
686 m_sigmaB.xelem (i-k, i) = 1.0;
698 OCTAVE_END_NAMESPACE(math)
699 OCTAVE_END_NAMESPACE(
octave)
charNDArray max(char d, const charNDArray &m)
T * fortran_vec()
Size of the specified dimension.
void * search(const std::string &nm, const name_mangler &mangler=name_mangler()) const
T left_singular_matrix_B() const
T left_singular_matrix_A() const
T right_singular_matrix() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define F77_DBLE_CMPLX_ARG(x)
octave_f77_int_type F77_INT
comp_ggsvd3_ptr< F77_DBLE_CMPLX, F77_DBLE >::type zggsvd3_type
comp_ggsvd_ptr< F77_CMPLX, F77_REAL >::type cggsvd_type
real_ggsvd_ptr< F77_DBLE >::type dggsvd_type
comp_ggsvd3_ptr< F77_CMPLX, F77_REAL >::type cggsvd3_type
real_ggsvd3_ptr< F77_REAL >::type sggsvd3_type
real_ggsvd3_ptr< F77_DBLE >::type dggsvd3_type
comp_ggsvd_ptr< F77_DBLE_CMPLX, F77_DBLE >::type zggsvd_type
real_ggsvd_ptr< F77_REAL >::type sggsvd_type
F77_RET_T F77_CONST_CHAR_ARG_DECL
F77_RET_T const F77_INT F77_INT const F77_DBLE F77_DBLE const F77_INT F77_DBLE const F77_INT F77_INT F77_INT F77_DBLE F77_DBLE const F77_INT F77_INT &F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL
F77_RET_T(F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, const F77_INT &, const F77_INT &, const F77_INT &, F77_INT &, F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, F77_DBLE *, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, F77_INT *, F77_INT &F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL)
std::complex< double > Complex
std::complex< float > FloatComplex
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
F77_RET_T F77_FUNC(xerbla, XERBLA)(F77_CONST_CHAR_ARG_DEF(s_arg