Mercurial > octave
changeset 26231:c36b6e371f5d
isdefinite.m: Return only true or false, not -1, 0, +1 (bug #51270).
* NEWS: Announce change
* isdefinite.m: Rewrite documentation. Add input validation for TOL.
Remove code to check for semi-definite matrix (return value of 0 previously).
Update BIST tests and add new ones.
author | Rik <rik@octave.org> |
---|---|
date | Thu, 13 Dec 2018 17:04:01 -0800 |
parents | b2f806601d30 |
children | 90487d5431cc |
files | NEWS scripts/linear-algebra/isdefinite.m |
diffstat | 2 files changed, 51 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Thu Dec 13 15:01:29 2018 -0800 +++ b/NEWS Thu Dec 13 17:04:01 2018 -0800 @@ -12,6 +12,13 @@ or "skew" to calculate the symmetric or skew-symmetric property of a matrix. Performance has also been increased. + ** The function isdefinite now returns true or false rather than + -1, 0, 1. To test for a positive semi-definite matrix (old output + of 0) check whether the following two conditions hold: + + isdefinite (A) => 0 + isdefinite (A + 5*TOL, TOL) => 1 + ** The issorted function now uses a direction option of "ascend" or "descend" to make it compatible with both the sort function and with Matlab. Change all uses of "ascending" and "descending" in
--- a/scripts/linear-algebra/isdefinite.m Thu Dec 13 15:01:29 2018 -0800 +++ b/scripts/linear-algebra/isdefinite.m Thu Dec 13 17:04:01 2018 -0800 @@ -19,12 +19,24 @@ ## -*- texinfo -*- ## @deftypefn {} {} isdefinite (@var{A}) ## @deftypefnx {} {} isdefinite (@var{A}, @var{tol}) -## Return 1 if @var{A} is symmetric positive definite within the -## tolerance specified by @var{tol} or 0 if @var{A} is symmetric -## positive semi-definite. Otherwise, return -1. +## Return true if @var{A} is symmetric positive definite matrix within the +## tolerance specified by @var{tol}. ## ## If @var{tol} is omitted, use a tolerance of -## @code{100 * eps * norm (@var{A}, "fro")} +## @code{100 * eps * norm (@var{A}, "fro")}. +## +## Background: A positive definite matrix has eigenvalues which are all +## greater than zero. A positive semi-definite matrix has eigenvalues which +## are all greater than or equal to zero. The matrix @var{A} is very likely to +## be positive semi-definite if the following two conditions hold for a +## suitably small tolerance @var{tol}. +## +## @example +## @group +## isdefinite (@var{A}) @result{} 0 +## isdefinite (@var{A} + 5*@var{tol}, @var{tol}) @result{} 1 +## @end group +## @end example ## @seealso{issymmetric, ishermitian} ## @end deftypefn @@ -38,50 +50,58 @@ print_usage (); endif + ## Validate inputs + retval = false; + if (! isnumeric (A)) + return; + endif + if (! isfloat (A)) A = double (A); endif if (nargin == 1) tol = 100 * eps (class (A)) * norm (A, "fro"); + elseif (! (isnumeric (tol) && isscalar (tol) && tol >= 0)) + error ("isdefinite: TOL must be a scalar >= 0"); endif if (! ishermitian (A, tol)) - error ("isdefinite: A must be a Hermitian matrix"); + return; endif e = tol * eye (rows (A)); - [r, p] = chol (A - e); + [~, p] = chol (A - e); if (p == 0) - retval = 1; - else - [r, p] = chol (A + e); - if (p == 0) - retval = 0; - else - retval = -1; - endif + retval = true; endif endfunction %!test -%! A = [-1 0; 0 -1]; -%! assert (isdefinite (A), -1); +%! A = [-1, 0; 0, -1]; +%! assert (isdefinite (A), false); + +%!test +%! A = [1, 0; 0, 1]; +%! assert (isdefinite (A), true); %!test -%! A = [1 0; 0 1]; -%! assert (isdefinite (A), 1); +%! A = [2, -1, 0; -1, 2, -1; 0, -1, 2]; +%! assert (isdefinite (A), true); +## Test for positive semi-definite matrix %!test -%! A = [2 -1 0; -1 2 -1; 0 -1 2]; -%! assert (isdefinite (A), 1); +%! A = [1, 0; 0, 0]; +%! assert (isdefinite (A), false); +%! tol = 100*eps; +%! assert (isdefinite (A+5*tol, tol), true); -%!test -%! A = [1 0; 0 0]; -%! assert (isdefinite (A), 0); +%!assert (! isdefinite (magic (3))) %!error isdefinite () %!error isdefinite (1,2,3) -%!error <A must be a Hermitian matrix> isdefinite ([1 2; 3 4]) +%!error <TOL must be a scalar .= 0> isdefinite (1, {1}) +%!error <TOL must be a scalar .= 0> isdefinite (1, [1 1]) +%!error <TOL must be a scalar .= 0> isdefinite (1, -1)