Mercurial > octave
diff libinterp/corefcn/gsvd.cc @ 22236:065a44375723
gsvd: reduce code duplication with templates.
* CmplxGSVD.cc, CmplxGSVD.h, dbleGSVD.cc, dbleGSVD.h: Remove files for
no longer existing classes. Replaced by gsvd template class. This
classes never existed in an Octave release, this was freshly imported
from Octave Forge so backwards compatibility is not an issue.
* liboctave/numeric/gsvd.h, liboctave/numeric/gsvd.cc: New files for gsvd
class template generated from CmplxGSVD.cc, CmplxGSVD.h, dbleGSVD.cc, and
dbleGSVD.h and converted to template. Removed unused << operator, unused
constructor with &info, and commented code. Only instantiated for Matrix
and ComplexMatrix, providing interface to DGGSVD and ZGGSVD.
* liboctave/numeric/module.mk: Update.
* mx-defs.h, mx-ext.h: Use new classes.
author | Barbara Locsi <locsi.barbara@gmail.com> |
---|---|
date | Tue, 09 Aug 2016 18:02:11 +0200 |
parents | 63b41167ef1e |
children | 867b177af1fe |
line wrap: on
line diff
--- a/libinterp/corefcn/gsvd.cc Thu Aug 04 07:50:31 2016 +0200 +++ b/libinterp/corefcn/gsvd.cc Tue Aug 09 18:02:11 2016 +0200 @@ -1,5 +1,6 @@ // Copyright (C) 1996, 1997 John W. Eaton // Copyright (C) 2006, 2010 Pascal Dupuis <Pascal.Dupuis@uclouvain.be> +// Copyright (C) 2016 Barbara Lócsi // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software @@ -25,8 +26,17 @@ #include "utils.h" #include "ovl.h" -#include "CmplxGSVD.h" -#include "dbleGSVD.h" +#include "gsvd.h" + +template <typename T> +static typename 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); +} + DEFUN (gsvd, args, nargout, doc: /* -*- texinfo -*- @@ -86,7 +96,7 @@ @end ifinfo The common upper triangular right term. Other authors, like S. Van Huffel, define this transformation as the simulatenous diagonalisation of the -input matrices, this can be achieved by multiplying +input matrices, this can be achieved by multiplying @iftex @tex X @@ -185,7 +195,7 @@ // octave_idx_type nn = argB.rows (); octave_idx_type np = argB.columns (); - + if (nr == 0 || nc == 0) { if (nargout == 5) @@ -208,10 +218,6 @@ return retval; } - GSVD::type type = ((nargout == 0 || nargout == 1) - ? GSVD::sigma_only - : (nargout > 5) ? GSVD::std : GSVD::economy ); - if (argA.is_real_type () && argB.is_real_type ()) { Matrix tmpA = argA.matrix_value (); @@ -221,17 +227,17 @@ { if (tmpA.any_element_is_inf_or_nan ()) { - error ("gsvd: cannot take GSVD of matrix containing Inf or NaN values"); - return retval; - } - - if (tmpB.any_element_is_inf_or_nan ()) - { - error ("gsvd: cannot take GSVD of matrix containing Inf or NaN values"); + error ("gsvd: cannot take gsvd of matrix containing Inf or NaN values"); return retval; } - GSVD result (tmpA, tmpB, type); + if (tmpB.any_element_is_inf_or_nan ()) + { + error ("gsvd: cannot take gsvd of matrix containing Inf or NaN values"); + return retval; + } + + gsvd<Matrix> result (tmpA, tmpB, gsvd_type<Matrix> (nargout)); // DiagMatrix sigma = result.singular_values (); @@ -244,7 +250,7 @@ retval = ovl (sigA.diag()); } else - { + { if (nargout > 5) retval = ovl (result.left_singular_matrix_A (), result.left_singular_matrix_B (), @@ -270,16 +276,16 @@ { if (ctmpA.any_element_is_inf_or_nan ()) { - error ("gsvd: cannot take GSVD of matrix containing Inf or NaN values"); + error ("gsvd: cannot take gsvd of matrix containing Inf or NaN values"); return retval; } if (ctmpB.any_element_is_inf_or_nan ()) { - error ("gsvd: cannot take GSVD of matrix containing Inf or NaN values"); + error ("gsvd: cannot take gsvd of matrix containing Inf or NaN values"); return retval; } - ComplexGSVD result (ctmpA, ctmpB, type); + gsvd<ComplexMatrix> result (ctmpA, ctmpB, gsvd_type<ComplexMatrix> (nargout)); // DiagMatrix sigma = result.singular_values (); @@ -370,7 +376,7 @@ %! [U, V, C, S, X, R] = gsvd(A, B); %! D1 = [C zeros(3,2)]; -%! D2 = [S zeros(3,2); zeros(2, 3) eye(2)]; +%! D2 = [S zeros(3,2); zeros(2, 3) eye(2)]; %!assert(norm(diag(C).^2+diag(S).^2 - ones(3, 1)) <= 1e-6) %!assert(norm((U'*A*X)-D1*R) <= 1e-6) %!assert(norm((V'*B*X)-D2*R) <= 1e-6) @@ -453,13 +459,13 @@ %!assert(norm((V'*B*X)-D2*[zeros(2, 1) R]) <= 1e-6) %! # now, A is 3x5 -%! A = A0.'; B0=diag([1 2 4 8 16])+j*diag([-5 4 -3 2 -1]); +%! A = A0.'; B0=diag([1 2 4 8 16])+j*diag([-5 4 -3 2 -1]); %! B = B0; %! # disp('Complex: Full rank, 3x5 by 5x5 matrices'); %! # disp([rank(A) rank(B) rank([A' B'])]); %! [U, V, C, S, X, R] = gsvd(A, B); %! D1 = [C zeros(3,2)]; -%! D2 = [S zeros(3,2); zeros(2, 3) eye(2)]; +%! D2 = [S zeros(3,2); zeros(2, 3) eye(2)]; %!assert(norm(diag(C).^2+diag(S).^2 - ones(3, 1)) <= 1e-6) %!assert(norm((U'*A*X)-D1*R) <= 1e-6) %!assert(norm((V'*B*X)-D2*R) <= 1e-6) @@ -497,4 +503,4 @@ %!assert(norm((U'*A*X)-D1*[zeros(4, 1) R]) <= 1e-6) %!assert(norm((V'*B*X)-D2*[zeros(4, 1) R]) <= 1e-6) - */ +*/