Mercurial > octave
changeset 24195:d3dc76efb38b
Return correct value for pinv of zero vectors and scalars (bug #51246).
CMatrix.cc, dMatrix.cc (pseudo_inverse): Change any computed tolerance of 0 to
std::numeric_limits<double>::min() so that zero values are later dropped from
calculation.
fCMatrix.cc, fMatrix.cc (pseudo_inverse): Change calculation of default tolerance
to us the <float> version of std::numeric_limits::epsilon () rather than the
double version. Change any computed tolerance of 0 to
std::numeric_limits<float>::min() so that zero values are later dropped from
calculation.
* pinv.cc (Fpinv): Add BIST tests.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 03 Nov 2017 10:03:36 -0700 |
parents | 3333ca37c038 |
children | 2b769c242188 |
files | libinterp/corefcn/pinv.cc liboctave/array/CMatrix.cc liboctave/array/dMatrix.cc liboctave/array/fCMatrix.cc liboctave/array/fMatrix.cc |
diffstat | 5 files changed, 25 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/pinv.cc Fri Nov 03 15:49:18 2017 +0100 +++ b/libinterp/corefcn/pinv.cc Fri Nov 03 10:03:36 2017 -0700 @@ -189,4 +189,13 @@ %! y = pinv (x, 2); %! assert (diag (y), [1/3 1/2 0 0 0]'); +## Test special case of 0 scalars and vectors +%!assert (pinv (0), 0) +%!assert (pinv ([0, 0, 0]), [0; 0; 0]) +%!assert (pinv (single (0)), single (0)) +%!assert (pinv (single ([0, 0, 0])), single ([0; 0; 0])) +%!assert (pinv (complex (0,0)), 0) +%!assert (pinv (complex ([0,0,0], [0,0,0])), [0; 0; 0]) +%!assert (pinv (complex (single (0),0)), single (0)) +%!assert (pinv (complex (single ([0,0,0]), [0,0,0])), single ([0; 0; 0])) */
--- a/liboctave/array/CMatrix.cc Fri Nov 03 15:49:18 2017 +0100 +++ b/liboctave/array/CMatrix.cc Fri Nov 03 10:03:36 2017 -0700 @@ -973,6 +973,9 @@ tol = nr * sigma.elem (0) * std::numeric_limits<double>::epsilon (); else tol = nc * sigma.elem (0) * std::numeric_limits<double>::epsilon (); + + if (tol == 0) + tol = std::numeric_limits<double>::min (); } while (r >= 0 && sigma.elem (r) < tol)
--- a/liboctave/array/dMatrix.cc Fri Nov 03 15:49:18 2017 +0100 +++ b/liboctave/array/dMatrix.cc Fri Nov 03 10:03:36 2017 -0700 @@ -672,6 +672,9 @@ tol = nr * sigma.elem (0) * std::numeric_limits<double>::epsilon (); else tol = nc * sigma.elem (0) * std::numeric_limits<double>::epsilon (); + + if (tol == 0) + tol = std::numeric_limits<double>::min (); } while (r >= 0 && sigma.elem (r) < tol)
--- a/liboctave/array/fCMatrix.cc Fri Nov 03 15:49:18 2017 +0100 +++ b/liboctave/array/fCMatrix.cc Fri Nov 03 10:03:36 2017 -0700 @@ -972,9 +972,12 @@ if (tol <= 0.0) { if (nr > nc) - tol = nr * sigma.elem (0) * std::numeric_limits<double>::epsilon (); + tol = nr * sigma.elem (0) * std::numeric_limits<float>::epsilon (); else - tol = nc * sigma.elem (0) * std::numeric_limits<double>::epsilon (); + tol = nc * sigma.elem (0) * std::numeric_limits<float>::epsilon (); + + if (tol == 0) + tol = std::numeric_limits<float>::min (); } while (r >= 0 && sigma.elem (r) < tol)
--- a/liboctave/array/fMatrix.cc Fri Nov 03 15:49:18 2017 +0100 +++ b/liboctave/array/fMatrix.cc Fri Nov 03 10:03:36 2017 -0700 @@ -675,9 +675,12 @@ if (tol <= 0.0) { if (nr > nc) - tol = nr * sigma.elem (0) * std::numeric_limits<double>::epsilon (); + tol = nr * sigma.elem (0) * std::numeric_limits<float>::epsilon (); else - tol = nc * sigma.elem (0) * std::numeric_limits<double>::epsilon (); + tol = nc * sigma.elem (0) * std::numeric_limits<float>::epsilon (); + + if (tol == 0) + tol = std::numeric_limits<float>::min (); } while (r >= 0 && sigma.elem (r) < tol)