changeset 15286:d048ef58bb72

maint: periodic merge of stable to default
author John W. Eaton <jwe@octave.org>
date Tue, 04 Sep 2012 13:58:00 -0400
parents 03ef3a183129 (current diff) 997e05334f71 (diff)
children ae9079bbc627
files .hgtags configure.ac libinterp/interp-core/sparse-xpow.cc liboctave/operators/mx-inlines.cc
diffstat 3 files changed, 37 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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 <class S, class SM>
+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);
--- 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: