changeset 18971:5556ddfb841b

spdiags.m: Treat sub/super-diagonals the same as Matlab. Distinguish between M >= N and M < N cases when placing diagonals. * spdiags.m: Add test for M >= N or M < N. When M >= N, sub-diagonals are taken from the first entries in a column while super-diagonals are taken from the last entries in a column. This is reversed for M < N. Add %!tests for new behavior. Add seealso link to diag() in docstring.
author Rik <rik@octave.org>
date Sun, 25 May 2014 13:13:17 -0700
parents 888f8ce79bbe
children 0728f7b6b1a2
files scripts/sparse/spdiags.m
diffstat 1 files changed, 48 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/sparse/spdiags.m
+++ b/scripts/sparse/spdiags.m
@@ -51,6 +51,7 @@
 ## @end group
 ## @end example
 ##
+## @seealso{diag}
 ## @end deftypefn
 
 function [B, d] = spdiags (v, d, m, n)
@@ -82,11 +83,21 @@
       endif
       dv = diag (v, dn);
       len = rows (dv);
-      if (dn < 0)
-        offset = Brows - len + 1;
-        B(offset:Brows, k) = dv;
+      ## Put sub/super-diagonals in the right place based on matrix size (MxN)
+      if (nr >= nc)
+        if (dn > 0)
+          offset = Brows - len + 1;
+          B(offset:Brows, k) = dv;
+        else
+          B(1:len, k) = dv;
+        endif
       else
-        B(1:len, k) = dv;
+        if (dn < 0)
+          offset = Brows - len + 1;
+          B(offset:Brows, k) = dv;
+        else
+          B(1:len, k) = dv;
+        endif
       endif
     endfor
 
@@ -99,7 +110,11 @@
   else
     ## Create new matrix of size mxn using v,d
     [j, i, v] = find (v);
-    offset = max (min (d(:), n-m), 0);
+    if (m >= n)
+      offset = max (min (d(:), n-m), 0);
+    else
+      offset = d(:);
+    endif
     j = j(:) + offset(i(:));
     i = j - d(:)(i(:));
     idx = i > 0 & i <= m & j > 0 & j <= n;
@@ -113,20 +128,42 @@
 %!test
 %! [B,d] = spdiags (magic (3));
 %! assert (d, [-2 -1 0 1 2]');
-%! assert (B, [0 0 8 1 6
-%!             0 3 5 7 0
-%!             4 9 2 0 0]);
+%! assert (B, [4 3 8 0 0
+%!             0 9 5 1 0
+%!             0 0 2 7 6]);
+%! B = spdiags (magic (3), [-2 1]);
+%! assert (B, [4 0; 0 1; 0 7]);
 
-%! B = spdiags (magic (3), [-2 1]);
-%! assert (B, [0 1; 0 7; 4 0]);
+## Test zero filling for supra- and super-diagonals
+%!test
+%! ## Case 1: M = N
+%! A = sparse (zeros (3,3));
+%! A(1,3) = 13;
+%! A(3,1) = 31;
+%! [B, d] = spdiags (A);
+%! assert (d, [-2 2]');
+%! assert (B, [31 0; 0 0; 0 13]);
+%! assert (spdiags (B, d, 3,3), A)
 
 %!test
-%! ## Test zero filling for supra- and super-diagonals
+%! ## Case 1: M > N
+%! A = sparse (zeros (4,3));
+%! A(1,3) = 13;
+%! A(3,1) = 31;
+%! [B, d] = spdiags (A);
+%! assert (d, [-2 2]');
+%! assert (B, [31 0; 0 0; 0 13]);
+%! assert (spdiags (B, d, 4,3), A)
+
+%!test
+%! ## Case 1: M < N
+%! A = sparse (zeros (3,4));
 %! A(1,3) = 13;
 %! A(3,1) = 31;
 %! [B, d] = spdiags (A);
 %! assert (d, [-2 2]');
 %! assert (B, [0 13; 0 0; 31 0]);
+%! assert (spdiags (B, d, 3,4), A)
 
 %!assert (spdiags (zeros (1,0),1,1,1), sparse (0))
 %!assert (spdiags (zeros (0,1),1,1,1), sparse (0))