# HG changeset patch # User John W. Eaton # Date 1346781480 14400 # Node ID d048ef58bb72927102aded9aa62510acc860bc44 # Parent 03ef3a183129380da205e92025b05cdec5ec337c# Parent 997e05334f71269f16017ceb06a52cf33feced18 maint: periodic merge of stable to default diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -67,3 +67,4 @@ f947d2922febf12dcd1fb6e21b356756ecb54e55 rc-3-6-2-0 4460c4fb20e6a5d3b1972fa737d4e00eb921545a rc-3-6-2-2 551566201318bf615b27c60ccf9368f4844008bd release-3-6-2 +a95432e7309ca6fc776c02939264bb6d443f3525 release-3-6-3 diff --git a/configure.ac b/configure.ac diff --git a/libinterp/interp-core/sparse-xpow.cc b/libinterp/interp-core/sparse-xpow.cc --- a/libinterp/interp-core/sparse-xpow.cc +++ b/libinterp/interp-core/sparse-xpow.cc @@ -230,6 +230,29 @@ // small real part. But perhaps that's really a problem with the math // library... +// Handle special case of scalar-sparse-matrix .^ sparse-matrix. +// Forwarding to the scalar elem_xpow function and then converting the +// result back to a sparse matrix is a bit wasteful but it does not +// seem worth the effort to optimize -- how often does this case come up +// in practice? + +template +inline octave_value +scalar_xpow (const S& a, const SM& b) +{ + octave_value val = elem_xpow (a, b); + + if (val.is_complex_type ()) + return SparseComplexMatrix (val.complex_matrix_value ()); + else + return SparseMatrix (val.matrix_value ()); +} + +/* +%!assert (sparse (2) .^ [3, 4], sparse ([8, 16])); +%!assert (sparse (2i) .^ [3, 4], sparse ([-0-8i, 16])); +*/ + // -*- 1 -*- octave_value elem_xpow (double a, const SparseMatrix& b) @@ -400,6 +423,9 @@ octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); + if (a.numel () == 1 && b.numel () > 1) + return scalar_xpow (a(0), b); + if (nr != b_nr || nc != b_nc) { gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc); @@ -502,6 +528,9 @@ octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); + if (a.numel () == 1 && b.numel () > 1) + return scalar_xpow (a(0), b); + if (nr != b_nr || nc != b_nc) { gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc); @@ -642,6 +671,9 @@ octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); + if (a.numel () == 1 && b.numel () > 1) + return scalar_xpow (a(0), b); + if (nr != b_nr || nc != b_nc) { gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc); @@ -710,6 +742,9 @@ octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); + if (a.numel () == 1 && b.numel () > 1) + return scalar_xpow (a(0), b); + if (nr != b_nr || nc != b_nc) { gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc); diff --git a/liboctave/operators/mx-inlines.cc b/liboctave/operators/mx-inlines.cc --- a/liboctave/operators/mx-inlines.cc +++ b/liboctave/operators/mx-inlines.cc @@ -1086,7 +1086,7 @@ for (octave_idx_type i = 0; i < n-2; i++) { for (octave_idx_type j = i*m; j < i*m+m; j++) - r[j] = (v[j+m+m] - v[j+m]) + (v[j+m] - v[j]); + r[j] = (v[j+m+m] - v[j+m]) - (v[j+m] - v[j]); } break; default: