changeset 13295:96c7143304d9

conv.m: Simplify algorithm and add more input validation and tests * conv.m: Simplify algorithm and add more input validation and tests
author Rik <octave@nomad.inbox5.com>
date Fri, 07 Oct 2011 20:21:09 -0700
parents 7dce7e110511
children 27da11c63d98
files scripts/polynomial/conv.m
diffstat 1 files changed, 44 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/polynomial/conv.m	Fri Oct 07 22:16:07 2011 -0400
+++ b/scripts/polynomial/conv.m	Fri Oct 07 20:21:09 2011 -0700
@@ -19,12 +19,12 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} conv (@var{a}, @var{b})
 ## @deftypefnx {Function File} {} conv (@var{a}, @var{b}, @var{shape})
-## Convolve two vectors.
+## Convolve two vectors @var{a} and @var{b}.
 ##
-## @code{c = conv (@var{a}, @var{b})} returns a vector of length equal to
+## The output convolution is a vector with length equal to
 ## @code{length (@var{a}) + length (@var{b}) - 1}.
-## If @var{a} and @var{b} are the coefficient vectors of two polynomials, the
-## returned value is the coefficient vector of the product polynomial.
+## When @var{a} and @var{b} are the coefficient vectors of two polynomials, the
+## convolution represents the coefficient vector of the product polynomial.
 ##
 ## The optional @var{shape} argument may be
 ##
@@ -50,7 +50,9 @@
   endif
 
   if (! (isvector (a) && isvector (b)))
-    error ("conv: both arguments must be vectors");
+    error ("conv: both arguments A and B must be vectors");
+  elseif (nargin == 3 && ! any (strcmpi (shape, {"full", "same"})))
+    error ('conv: SHAPE argument must be "full" or "same"');
   endif
 
   la = length (a);
@@ -60,40 +62,31 @@
 
   if (ly == 0)
     y = zeros (1, 0);
-  else
-    ## Use the shortest vector as the coefficent vector to filter.
-    ## Preserve the row/column orientation of the longer input.
-    if (la <= lb)
-      if (ly > lb)
-        if (size (b, 1) <= size (b, 2))
-          x = [b, (zeros (1, ly - lb))];
-        else
-          x = [b; (zeros (ly - lb, 1))];
-        endif
-      else
-        x = b;
-      endif
-      y = filter (a, 1, x);
-    else
-      if (ly > la)
-        if (size (a, 1) <= size (a, 2))
-          x = [a, (zeros (1, ly - la))];
-        else
-          x = [a; (zeros (ly - la, 1))];
-        endif
-      else
-        x = a;
-      endif
-      y = filter (b, 1, x);
-    endif
-    if (strcmp (shape, "same"))
-      idx = ceil ((ly - la) / 2);
-      y = y(idx+1:idx+la);
-    endif
+    return;
+  endif
+
+  ## Use shortest vector as the coefficent vector to filter.
+  if (la > lb)
+    [a, b] = deal (b, a);  # Swap vectors 
+    lb = la;
+  endif
+  x = b;
+
+  ## Pad longer vector to convolution length.
+  if (ly > lb)
+    x(end+1:end+ly-lb) = 0;
+  endif
+
+  y = filter (a, 1, x);
+
+  if (strcmp (shape, "same"))
+    idx = ceil ((ly - la) / 2);
+    y = y(idx+1:idx+la);
   endif
 
 endfunction
 
+
 %!test
 %!  x = ones(3,1);
 %!  y = ones(1,3);
@@ -112,35 +105,37 @@
 %!test
 %!  a = 1:10;
 %!  b = 1:3;
-%!  assert (size(conv(a,b)), [1, numel(a)+numel(b)-1])
-%!  assert (size(conv(b,a)), [1, numel(a)+numel(b)-1])
+%!  assert (size (conv(a,b)), [1, numel(a)+numel(b)-1]);
+%!  assert (size (conv(b,a)), [1, numel(a)+numel(b)-1]);
 
+%!test
 %!  a = (1:10).';
 %!  b = 1:3;
-%!  assert (size(conv(a,b)), [numel(a)+numel(b)-1, 1])
-%!  assert (size(conv(b,a)), [numel(a)+numel(b)-1, 1])
+%!  assert (size (conv(a,b)), [numel(a)+numel(b)-1, 1]);
+%!  assert (size (conv(b,a)), [numel(a)+numel(b)-1, 1]);
 
 %!test
 %!  a = 1:10;
 %!  b = (1:3).';
-%!  assert (size(conv(a,b)), [1, numel(a)+numel(b)-1])
-%!  assert (size(conv(b,a)), [1, numel(a)+numel(b)-1])
+%!  assert (size (conv(a,b)), [1, numel(a)+numel(b)-1]);
+%!  assert (size (conv(b,a)), [1, numel(a)+numel(b)-1]);
 
 %!test
 %!  a = 1:10;
 %!  b = 1:3;
-%!  assert (conv(a,b,"full"), conv(a,b))
-%!  assert (conv(b,a,"full"), conv(b,a))
+%!  assert (conv (a,b,"full"), conv (a,b));
+%!  assert (conv (b,a,"full"), conv (b,a));
 
 %!test
 %!  a = 1:10;
 %!  b = 1:3;
-%!  assert (conv(a,b,'same'), [4, 10, 16, 22, 28, 34, 40, 46, 52, 47])
-%!  assert (conv(b,a,'same'), [28, 34, 40])
+%!  assert (conv (a,b,"same"), [4, 10, 16, 22, 28, 34, 40, 46, 52, 47]);
+%!  assert (conv (b,a,"same"), [28, 34, 40]);
 
 %% Test input validation
-%!error conv (1);
-%!error conv (1,2,3,4);
-%!error conv ([1, 2; 3, 4], 3);
-%!error conv (2, []);
+%!error conv (1)
+%!error conv (1,2,3,4)
+%!error conv ([1, 2; 3, 4], 3)
+%!error conv (3, [1, 2; 3, 4])
+%!error conv (2, 3, "XXXX")