Mercurial > octave
changeset 22615:68e9bdb7cde3
Accept second input '0' to svd (bug #49309).
* svd.cc (Fsvd): Add 3rd calling form to docstring. Document behavior
of "econ" and '0' inputs. Add BIST test for bug #49309. Change all
calls to svd_type to match new prototype.
* svd.cc (svd_type): Change function to have two additional inputs, the
octave_value_list args and the matrix A. Change code to use if/else tree
to calculate the svd type.
author | Rik <rik@octave.org> |
---|---|
date | Tue, 11 Oct 2016 14:14:44 -0700 |
parents | edd04ce99891 |
children | 5fdfde2a873d |
files | libinterp/corefcn/svd.cc |
diffstat | 1 files changed, 37 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/svd.cc Tue Oct 11 09:49:21 2016 -0700 +++ b/libinterp/corefcn/svd.cc Tue Oct 11 14:14:44 2016 -0700 @@ -38,13 +38,22 @@ template <typename T> static typename octave::math::svd<T>::Type -svd_type (int nargin, int nargout) +svd_type (int nargin, int nargout, const octave_value_list & args, const T & A) { - return ((nargout == 0 || nargout == 1) - ? octave::math::svd<T>::Type::sigma_only - : ((nargin == 2) - ? octave::math::svd<T>::Type::economy - : octave::math::svd<T>::Type::std)); + if (nargout == 0 || nargout == 1) + return octave::math::svd<T>::Type::sigma_only; + else if (nargin == 1) + return octave::math::svd<T>::Type::std; + else + if (! args(1).is_real_scalar ()) + return octave::math::svd<T>::Type::economy; + else + { + if (A.rows () > A.columns ()) + return octave::math::svd<T>::Type::economy; + else + return octave::math::svd<T>::Type::std; + } } template <typename T> @@ -60,7 +69,8 @@ doc: /* -*- texinfo -*- @deftypefn {} {@var{s} =} svd (@var{A}) @deftypefnx {} {[@var{U}, @var{S}, @var{V}] =} svd (@var{A}) -@deftypefnx {} {[@var{U}, @var{S}, @var{V}] =} svd (@var{A}, @var{econ}) +@deftypefnx {} {[@var{U}, @var{S}, @var{V}] =} svd (@var{A}, "econ") +@deftypefnx {} {[@var{U}, @var{S}, @var{V}] =} svd (@var{A}, 0) @cindex singular value decomposition Compute the singular value decomposition of @var{A} @tex @@ -135,9 +145,14 @@ @end group @end example -If given a second argument, @code{svd} returns an economy-sized +When given a second argument that is not 0, @code{svd} returns an economy-sized decomposition, eliminating the unnecessary rows or columns of @var{U} or @var{V}. + +If the second argument is exactly 0, then the choice of decomposition is based +on the matrix @var{A}. If @var{A} has more rows than columns then an +economy-sized decomposition is returned, otherwise a regular decomposition +is calculated. @seealso{svd_driver, svds, eig, lu, chol, hess, qr, qz} @end deftypefn */) { @@ -165,7 +180,8 @@ error ("svd: cannot take SVD of matrix containing Inf or NaN values"); octave::math::svd<FloatMatrix> result - (tmp, svd_type<FloatMatrix> (nargin, nargout), + (tmp, + svd_type<FloatMatrix> (nargin, nargout, args, tmp), svd_driver<FloatMatrix> ()); FloatDiagMatrix sigma = result.singular_values (); @@ -185,7 +201,8 @@ error ("svd: cannot take SVD of matrix containing Inf or NaN values"); octave::math::svd<FloatComplexMatrix> result - (ctmp, svd_type<FloatComplexMatrix> (nargin, nargout), + (ctmp, + svd_type<FloatComplexMatrix> (nargin, nargout, args, ctmp), svd_driver<FloatComplexMatrix> ()); FloatDiagMatrix sigma = result.singular_values (); @@ -208,7 +225,8 @@ error ("svd: cannot take SVD of matrix containing Inf or NaN values"); octave::math::svd<Matrix> result - (tmp, svd_type<Matrix> (nargin, nargout), + (tmp, + svd_type<Matrix> (nargin, nargout, args, tmp), svd_driver<Matrix> ()); DiagMatrix sigma = result.singular_values (); @@ -228,7 +246,8 @@ error ("svd: cannot take SVD of matrix containing Inf or NaN values"); octave::math::svd<ComplexMatrix> result - (ctmp, svd_type<ComplexMatrix> (nargin, nargout), + (ctmp, + svd_type<ComplexMatrix> (nargin, nargout, args, ctmp), svd_driver<ComplexMatrix> ()); DiagMatrix sigma = result.singular_values (); @@ -255,7 +274,6 @@ [u,s,v] = svd (a); assert (a, u * s * v', 128 * eps); - %!test %! [u, s, v] = svd ([1, 2; 2, 1]); %! x = 1 / sqrt (2); @@ -326,6 +344,12 @@ %! assert (size (s), [0, 0]); %! assert (size (v), [0, 0]); +%!test <49309> +%! [~,~,v] = svd ([1, 1, 1], 0); +%! assert (size (v), [3 3]); +%! [~,~,v] = svd ([1, 1, 1], "econ"); +%! assert (size (v), [3 1]); + %!error svd () %!error svd ([1, 2; 4, 5], 2, 3) %!error [u, v] = svd ([1, 2; 3, 4])