changeset 31377:b0dc52c6a9ee

maint: merge away extra head.
author Rik <rik@octave.org>
date Mon, 31 Oct 2022 10:03:20 -0700
parents ad8a4102f910 (current diff) f2515895e3b6 (diff)
children 8dc9508b8364
files
diffstat 3 files changed, 60 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS.7.md	Mon Oct 31 10:01:50 2022 -0700
+++ b/etc/NEWS.7.md	Mon Oct 31 10:03:20 2022 -0700
@@ -23,6 +23,7 @@
 - Fix incorrect `lambda` outputs for `lsqnonneg` and `pqpnonneg` (bug #63178).
 - `addtodate.m`: Fix wrong month returned when subtracting a month from some end-of-month dates (bug #60671).
 - `var.m`: Fix some Inf and NaN inputs returning 0 instead of NaN (bug #63203)
+- `var.m`: Fix automatic broadcasting error for sparse and diagonal matrix inputs with vector weighting (bug #63291).
 - `legend.m`: Fix error with `contour` plot containing `clabel`s (bug #63262).
 - `dec2bin.m`: Fix input validation (bug #63089).
 - `glpk.m`: Avoid using `isfinite` on potentially sparse input.
--- a/libinterp/corefcn/schur.cc	Mon Oct 31 10:01:50 2022 -0700
+++ b/libinterp/corefcn/schur.cc	Mon Oct 31 10:03:20 2022 -0700
@@ -69,7 +69,8 @@
 @cindex Schur decomposition
 Compute the Schur@tie{}decomposition of @var{A}.
 
-The Schur@tie{}decomposition is defined as
+The Schur@tie{}decomposition is an eigendecomposition of a square matrix
+@var{A} defined as
 @tex
 $$
  S = U^T A U
@@ -100,34 +101,32 @@
 @ifnottex
 @code{2 x 2}
 @end ifnottex
-along the diagonal.  The diagonal elements of @var{S}
-(or the eigenvalues of the
-@tex
-$2 \times 2$
-@end tex
-@ifnottex
-@code{2 x 2}
-@end ifnottex
-blocks, when appropriate) are the eigenvalues of @var{A} and @var{S}.
+along the diagonal.
 
-The default for real matrices is a real Schur@tie{}decomposition.
-A complex decomposition may be forced by passing the flag
-@qcode{"complex"}.
+The default for real matrices is a real Schur@tie{}decomposition.  A complex
+decomposition may be forced by passing the flag @qcode{"complex"}.
 
 The eigenvalues are optionally ordered along the diagonal according to the
-value of @var{opt}.  @code{@var{opt} = "a"} indicates that all eigenvalues
-with negative real parts should be moved to the leading block of @var{S}
-(used in @code{are}), @code{@var{opt} = "d"} indicates that all
-eigenvalues with magnitude less than one should be moved to the leading
-block of @var{S} (used in @code{dare}), and @code{@var{opt} = "u"}, the
-default, indicates that no ordering of eigenvalues should occur.  The
-leading @var{k} columns of @var{U} always span the @var{A}-invariant
+value of @var{opt}:
+
+@table @asis
+@item @qcode{@var{opt} = "a"}
+Move eigenvalues with negative real parts to the leading block of @var{S}.
+Mnemonic: @qcode{"a"} for Algebraic @nospell{Riccati} Equations, where this
+ordering is useful.
+
+@item @qcode{@var{opt} = "d"}
+Move eigenvalues with magnitude less than one to the leading block of @var{S}.
+Mnemonic: @qcode{"d"} for Discrete Algebraic @nospell{Riccati} Equations,
+where this ordering is useful.
+
+@item @qcode{@var{opt} = "u"}
+Unordered.  No particular ordering of eigenvalues (default).
+@end table
+
+The leading @var{k} columns of @var{U} always span the @var{A}-invariant
 subspace corresponding to the @var{k} leading eigenvalues of @var{S}.
-
-The Schur@tie{}decomposition is used to compute eigenvalues of a square
-matrix, and has applications in the solution of algebraic @nospell{Riccati}
-equations in control (see @code{are} and @code{dare}).
-@seealso{rsf2csf, ordschur, ordeig, lu, chol, hess, qr, qz, svd}
+@seealso{rsf2csf, ordschur, ordeig, lu, chol, hess, qr, qz, svd, eig}
 @end deftypefn */)
 {
   int nargin = args.length ();
--- a/scripts/statistics/var.m	Mon Oct 31 10:01:50 2022 -0700
+++ b/scripts/statistics/var.m	Mon Oct 31 10:03:20 2022 -0700
@@ -224,8 +224,14 @@
         w = reshape (w, newdims);
       endif
       den = sum (w);
-      mu = sum (w .* x, dim) ./ den;
-      v = sum (w .* ((x - mu) .^ 2), dim) ./ den;
+
+      ## FIXME: Use bsxfun, rather than broadcasting, until broadcasting
+      ##        supports diagonal and sparse matrices (Bugs #41441, #35787).
+      mu = sum (bsxfun (@times, w , x), dim) ./ den;
+      v = sum (bsxfun (@times, w, ...
+                            bsxfun (@minus, x, mu) .^ 2), dim) ./ den;
+      ## mu = sum (w .* x, dim) ./ den; # automatic broadcasting
+      ## v = sum (w .* ((x - mu) .^ 2), dim) ./ den;
     endif
   endif
 
@@ -417,6 +423,33 @@
 %! assert (v, [2, 2, NaN]);
 %! assert (m, [2, 4, NaN]);
 
+## Test sparse/diagonal inputs
+%!test <*63291>
+%! [v, m] = var (2 * eye (2));
+%! assert (v, [2, 2]);
+%! assert (m, [1, 1]);
+%!test <*63291>
+%! [v, m] = var (4 * eye (2), [1, 3]);
+%! assert (v, [3, 3]);
+%! assert (m, [1, 3]);
+%!test <*63291>
+%! [v, m] = var (sparse (2 * eye (2)));
+%! assert (full (v), [2, 2]);
+%! assert (full (m), [1, 1]);
+%!test <*63291>
+%! [v, m] = var (sparse (4 * eye (2)), [1, 3]);
+%! assert (full (v), [3, 3]);
+%! assert (full (m), [1, 3]);
+
+%!test <63291>
+%! [v, m] = var (sparse (eye (2)));
+%! assert (issparse (v));
+%! assert (issparse (m));
+%!test <63291>
+%! [v, m] = var (sparse (eye (2)), [1, 3]);
+%! assert (issparse (v));
+%! assert (issparse (m));
+
 ## Test input validation
 %!error <Invalid call> var ()
 %!error <X must be a numeric> var (['A'; 'B'])