changeset 30923:7ad60a258a2b

Allow "econ" argument to qr() function (bug #62277). * qr.cc (Fqr): Add documentation for "econ" input argument. Add input decoding for string "econ". Change error message for unrecognized input to bound it with double quote characters. Update functional and input validation BIST tests.
author Arun Giridhar <arungiridhar@gmail.com>
date Sat, 09 Apr 2022 14:52:25 -0700
parents cd38f31e9b4b
children 18bf227e5af5
files libinterp/corefcn/qr.cc
diffstat 1 files changed, 28 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/qr.cc	Fri Apr 08 17:44:26 2022 -0400
+++ b/libinterp/corefcn/qr.cc	Sat Apr 09 14:52:25 2022 -0700
@@ -116,6 +116,7 @@
 @deftypefnx {} {@var{X} =} qr (@var{A}, @var{B}) # sparse A
 @deftypefnx {} {[@var{C}, @var{R}] =} qr (@var{A}, @var{B})
 @deftypefnx {} {[@dots{}] =} qr (@dots{}, 0)
+@deftypefnx {} {[@dots{}] =} qr (@dots{}, "econ")
 @deftypefnx {} {[@dots{}] =} qr (@dots{}, "vector")
 @deftypefnx {} {[@dots{}] =} qr (@dots{}, "matrix")
 @cindex QR factorization
@@ -270,14 +271,14 @@
 The default, however, is to return a permutation matrix and this may be
 explicitly specified by using a final argument of @qcode{"matrix"}.
 
-If the final argument is the scalar 0 an @qcode{"economy"} factorization is
-returned.  If the original matrix @var{A} has size MxN and M > N, then the
-@qcode{"economy"} factorization will calculate just N rows in @var{R} and N
-columns in @var{Q} and omit the zeros in @var{R}.  If M @leq{} N, there is no
-difference between the economy and standard factorizations.  When calculating
-an @qcode{"economy"} factorization and @var{A} is dense, the output @var{P} is
-always a vector rather than a matrix.  If @var{A} is sparse, output
-@var{P} is a sparse permutation matrix.
+If the final argument is the scalar 0 or the string @qcode{"econ"}, an
+economy factorization is returned.  If the original matrix @var{A} has size
+MxN and M > N, then the economy factorization will calculate just N rows in
+@var{R} and N columns in @var{Q} and omit the zeros in @var{R}.  If M @leq{}
+N, there is no difference between the economy and standard factorizations.
+When calculating an economy factorization and @var{A} is dense, the output
+@var{P} is always a vector rather than a matrix.  If @var{A} is sparse,
+output @var{P} is a sparse permutation matrix.
 
 Background: The QR factorization has applications in the solution of least
 squares problems
@@ -344,9 +345,14 @@
           std::string str = args(nargin-1).string_value ();
           if (str == "vector")
             vector_p = true;
+          else if (str == "econ")
+            {
+              economy = true;
+              have_b = (nargin > 2);
+            }
           else if (str != "matrix")
-            error ("qr: type for P must be 'matrix' or 'vector', not %s",
-                   str.c_str ());
+            error ("qr: option string must be 'econ' or 'matrix' or " \
+                   "'vector', not \"%s\"", str.c_str ());
           have_b = (nargin > 2);
         }
       else if (! args(nargin-1).is_matrix_type ())
@@ -704,45 +710,55 @@
 %!
 %! [q, r] = qr (a);
 %! [qe, re] = qr (a, 0);
+%! [qe2, re2] = qr (a, "econ");
 %!
 %! assert (q * r, a, sqrt (eps));
 %! assert (qe * re, a, sqrt (eps));
+%! assert (qe2 * re2, a, sqrt (eps));
 
 %!test
 %! a = [0, 2, 1; 2, 1, 2];
 %!
 %! [q, r] = qr (a);
 %! [qe, re] = qr (a, 0);
+%! [qe2, re2] = qr (a, "econ");
 %!
 %! assert (q * r, a, sqrt (eps));
 %! assert (qe * re, a, sqrt (eps));
+%! assert (qe2 * re2, a, sqrt (eps));
 
 %!test
 %! a = [0, 2, 1; 2, 1, 2];
 %!
 %! [q, r, p] = qr (a);  # FIXME: not giving right dimensions.
 %! [qe, re, pe] = qr (a, 0);
+%! [qe2, re2, pe2] = qr (a, "econ");
 %!
 %! assert (q * r, a * p, sqrt (eps));
 %! assert (qe * re, a(:, pe), sqrt (eps));
+%! assert (qe2 * re2, a(:, pe2), sqrt (eps));
 
 %!test
 %! a = [0, 2; 2, 1; 1, 2];
 %!
 %! [q, r] = qr (a);
 %! [qe, re] = qr (a, 0);
+%! [qe2, re2] = qr (a, "econ");
 %!
 %! assert (q * r, a, sqrt (eps));
 %! assert (qe * re, a, sqrt (eps));
+%! assert (qe2 * re2, a, sqrt (eps));
 
 %!test
 %! a = [0, 2; 2, 1; 1, 2];
 %!
 %! [q, r, p] = qr (a);
 %! [qe, re, pe] = qr (a, 0);
+%! [qe2, re2, pe2] = qr (a, "econ");
 %!
 %! assert (q * r, a * p, sqrt (eps));
 %! assert (qe * re, a(:, pe), sqrt (eps));
+%! assert (qe2 * re2, a(:, pe2), sqrt (eps));
 
 %!test
 %! a = [0, 2, 1; 2, 1, 2; 3, 1, 2];
@@ -791,6 +807,8 @@
 
 %!error qr ()
 %!error qr ([1, 2; 3, 4], 0, 2)
+%!error <option string must be .*, not "foo"> qr (magic (3), "foo")
+%!error <option string must be .*, not "foo"> qr (magic (3), rand (3, 1), "foo")
 %!error <too many output arguments for dense A with B>
 %! [q, r, p] = qr (rand (3, 2), rand (3, 1));
 %!error <too many output arguments for dense A with B>