# HG changeset patch # User Arun Giridhar # Date 1663678802 14400 # Node ID a1318deb45840063d4f2b48c353dbeaa99f70f8d # Parent 95fa3182f00ce043808a96a2fcbca584c998f34b sparse-xpow.cc: Improve consistency between sparse and full matrices (bug #63080) sparse-xpow.cc: Return 0x0 matrix for empty inputs of all sizes. Return early for all-zeros matrix with positive power. Add FIXME for all-zeros matrix with negative power. Add BISTs. diff -r 95fa3182f00c -r a1318deb4584 libinterp/corefcn/sparse-xpow.cc --- a/libinterp/corefcn/sparse-xpow.cc Mon Sep 19 13:14:16 2022 +0200 +++ b/libinterp/corefcn/sparse-xpow.cc Tue Sep 20 09:00:02 2022 -0400 @@ -66,12 +66,13 @@ octave_idx_type nr = a.rows (); octave_idx_type nc = a.cols (); + if (nr == 0 || nc == 0) + return SparseMatrix(); + + // If we are here, A is not empty ==> A needs to be square. if (nr != nc) error ("for A^b, A must be a square matrix. Use .^ for elementwise power."); - if (nr == 0 && nc == 0) - return a; - if (! xisint (b)) error ("use full(a) ^ full(b)"); @@ -100,6 +101,9 @@ double rcond = 0.0; MatrixType mattyp (a); + // FIXME: This causes an error if the input sparse matrix is all-zeros. + // That behavior is inconsistent with A ^ b when A is a full all-zeros + // matrix, which just returns Inf of the same size with a warning. atmp = a.inverse (mattyp, info, rcond, 1); if (info == -1) @@ -108,6 +112,9 @@ else atmp = a; + if (atmp.nnz() == 0) // Fast return for all-zeros matrix + return atmp; + SparseMatrix result (atmp); btmp--; @@ -172,7 +179,11 @@ octave_idx_type nr = a.rows (); octave_idx_type nc = a.cols (); - if (nr == 0 || nc == 0 || nr != nc) + if (nr == 0 || nc == 0) + return SparseMatrix(); + + // If we are here, A is not empty ==> A needs to be square. + if (nr != nc) error ("for A^b, A must be a square matrix. Use .^ for elementwise power."); if (! xisint (b)) @@ -211,6 +222,9 @@ else atmp = a; + if (atmp.nnz() == 0) // Fast return for all-zeros matrix + return atmp; + SparseComplexMatrix result (atmp); btmp--; @@ -301,6 +315,30 @@ /* %!assert (sparse (2) .^ [3, 4], sparse ([8, 16])) %!assert <47775> (sparse (2i) .^ [3, 4], sparse ([-0-8i, 16])) + +%!test <*63080> +%! Z = sparse ([]); +%! A = sparse (zeros (0, 2)); +%! B = sparse (zeros (2, 0)); +%! assert (Z ^ 1, Z); +%! assert (Z ^ 0, Z); +%! assert (Z ^ -1, Z); +%! assert (A ^ 1, Z); +%! assert (A ^ 0, Z); +%! assert (A ^ -1, Z); +%! assert (B ^ 1, Z); +%! assert (B ^ 0, Z); +%! assert (B ^ -1, Z); + +%!test <*63080> +%! A = sparse (zeros (2, 2)); +%! assert (A ^ 1, A); +%! assert (A ^ 0, sparse (eye (2, 2))); + +%!test <63080> +%! A = sparse (zeros (2, 2)); +%! assert (A ^ -1, sparse (inf (2, 2))); + */ // -*- 1 -*- @@ -803,4 +841,5 @@ return result; } + OCTAVE_NAMESPACE_END