changeset 11082:4558aad4c41d

conv.m: handle "same" shape argument
author John W. Eaton <jwe@octave.org>
date Thu, 07 Oct 2010 03:09:07 -0400
parents f9284142a060
children bb8bf77f2242
files scripts/ChangeLog scripts/polynomial/conv.m
diffstat 2 files changed, 60 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Thu Oct 07 02:00:05 2010 -0400
+++ b/scripts/ChangeLog	Thu Oct 07 03:09:07 2010 -0400
@@ -1,3 +1,8 @@
+2010-10-07  John W. Eaton  <jwe@octave.org>
+
+	* polynomial/conv.m: Handle optional third argument.  New
+	tests.  Update doc string.
+
 2010-10-06  Ben Abbott <bpabbott@mac.com>
 
 	* image/image.m: Allow x/ydata to imply a flip of the image.
--- a/scripts/polynomial/conv.m	Thu Oct 07 02:00:05 2010 -0400
+++ b/scripts/polynomial/conv.m	Thu Oct 07 03:09:07 2010 -0400
@@ -18,13 +18,27 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} conv (@var{a}, @var{b})
+## @deftypefn {Function File} {} conv (@var{a}, @var{b}, @var{shape})
 ## Convolve two vectors.
 ##
 ## @code{y = conv (a, b)} returns a vector of length equal to
 ## @code{length (a) + length (b) - 1}.
 ## If @var{a} and @var{b} are polynomial coefficient vectors, @code{conv}
 ## returns the coefficients of the product polynomial.
+##
+## The optional @var{shape} parameter may be
+##
+## @table @asis\n\
+## @item @var{shape} = "full"
+## Return the full convolution.
+## \n\
+## @item @var{shape} = "same"
+## Return central part of the convolution with the same size as @var{a}.
+## @end table
+##
+## @noindent
+## By default, @var{shape} is @samp{"full"}.
+##
 ## @seealso{deconv, poly, roots, residue, polyval, polyderiv, polyint}
 ## @end deftypefn
 
@@ -32,9 +46,9 @@
 ## Created: June 1994
 ## Adapted-By: jwe
 
-function y = conv (a, b)
+function y = conv (a, b, shape = "full")
 
-  if (nargin != 2)
+  if (nargin < 2 || nargin > 3)
     print_usage ();
   endif
 
@@ -47,30 +61,38 @@
 
   ly = la + lb - 1;
 
-  ## 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))];
+  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; (zeros (ly - lb, 1))];
+        x = b;
       endif
+      y = filter (a, 1, x);
     else
-      x = b;
+      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
-    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;
+    if (strcmp (shape, "same"))
+      idx = ceil ((ly - la) / 2);
+      y = y(idx+1:idx+la);
     endif
-    y = filter (b, 1, x);
   endif
 
 endfunction
@@ -99,6 +121,11 @@
 %!  assert (size(conv(b,a)), [1, numel(a)+numel(b)-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])
+
 %!  a = (1:10).';
 %!  b = 1:3;
 %!  assert (size(conv(a,b)), [numel(a)+numel(b)-1, 1])
@@ -106,6 +133,12 @@
 
 %!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])
+
+%!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])