changeset 20031:26fb4bfa4193

blackman, hamming, hanning: Add periodic window option (bug #43305) * blackman.m, hamming.m, hanning.m: Add Matlab compatible option to return the periodic form of the window. Add %!tests for new behavior.
author Mike Miller <mtmiller@ieee.org>
date Sun, 22 Feb 2015 17:39:29 -0500
parents bc3e6e96da81
children 2e556954ced8
files scripts/signal/blackman.m scripts/signal/hamming.m scripts/signal/hanning.m
diffstat 3 files changed, 114 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/signal/blackman.m
+++ b/scripts/signal/blackman.m
@@ -17,9 +17,16 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} blackman (@var{m})
+## @deftypefn  {Function File} {} blackman (@var{m})
+## @deftypefnx {Function File} {} blackman (@var{m}, "periodic")
+## @deftypefnx {Function File} {} blackman (@var{m}, "symmetric")
 ## Return the filter coefficients of a Blackman window of length @var{m}.
 ##
+## If the optional argument @qcode{"periodic"} is given, the periodic form
+## of the window is returned.  This is equivalent to the window of length
+## @var{m}+1 with the last coefficient removed.  The optional argument
+## @qcode{"symmetric"} is equivalent to not specifying a second argument.
+##
 ## For a definition of the Blackman window, see e.g.,
 ## @nospell{A.V. Oppenheim & R. W. Schafer},
 ## @cite{Discrete-Time Signal Processing}.
@@ -28,24 +35,42 @@
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
 ## Description: Coefficients of the Blackman window
 
-function c = blackman (m)
+function c = blackman (m, opt)
 
-  if (nargin != 1)
+  if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
   if (! (isscalar (m) && (m == fix (m)) && (m > 0)))
-    error ("blackman: M has to be an integer > 0");
+    error ("blackman: M must be a positive integer");
+  endif
+
+  periodic = false;
+  if (nargin == 2)
+    switch (opt)
+      case "periodic"
+        periodic = true;
+      case "symmetric"
+        ## Default option, same as no option specified.
+      otherwise
+        error ('blackman: window type must be either "periodic" or "symmetric"');
+    endswitch
   endif
 
   if (m == 1)
     c = 1;
   else
-    m = m - 1;
+    if (! periodic)
+      m = m - 1;
+    endif
     k = (0 : m)' / m;
     c = 0.42 - 0.5 * cos (2 * pi * k) + 0.08 * cos (4 * pi * k);
   endif
 
+  if (periodic)
+    c = c(1:end-1);
+  endif
+
 endfunction
 
 
@@ -59,8 +84,16 @@
 %! assert (A (ceil (N/2)), 1, 1e-6);
 %! assert ([A(1), A(length (A))], zeros (1, 2), 1e-6);
 
+%!assert (blackman (15), blackman (15, "symmetric"));
+%!assert (blackman (16)(1:15), blackman (15, "periodic"));
+%!test
+%! N = 16;
+%! A = blackman (N, "periodic");
+%! assert (A (N/2 + 1), 1, 1e-6);
+
 %!error blackman ()
 %!error blackman (0.5)
 %!error blackman (-1)
 %!error blackman (ones (1,4))
+%!error blackman (1, "invalid");
 
--- a/scripts/signal/hamming.m
+++ b/scripts/signal/hamming.m
@@ -17,9 +17,16 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} hamming (@var{m})
+## @deftypefn  {Function File} {} hamming (@var{m})
+## @deftypefnx {Function File} {} hamming (@var{m}, "periodic")
+## @deftypefnx {Function File} {} hamming (@var{m}, "symmetric")
 ## Return the filter coefficients of a Hamming window of length @var{m}.
 ##
+## If the optional argument @qcode{"periodic"} is given, the periodic form
+## of the window is returned.  This is equivalent to the window of length
+## @var{m}+1 with the last coefficient removed.  The optional argument
+## @qcode{"symmetric"} is equivalent to not specifying a second argument.
+##
 ## For a definition of the Hamming window, see e.g.,
 ## @nospell{A.V. Oppenheim & R. W. Schafer},
 ## @cite{Discrete-Time Signal Processing}.
@@ -28,23 +35,41 @@
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
 ## Description: Coefficients of the Hamming window
 
-function c = hamming (m)
+function c = hamming (m, opt)
 
-  if (nargin != 1)
+  if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
   if (! (isscalar (m) && (m == fix (m)) && (m > 0)))
-    error ("hamming: M has to be an integer > 0");
+    error ("hamming: M must be a positive integer");
+  endif
+
+  periodic = false;
+  if (nargin == 2)
+    switch (opt)
+      case "periodic"
+        periodic = true;
+      case "symmetric"
+        ## Default option, same as no option specified.
+      otherwise
+        error ('hamming: window type must be either "periodic" or "symmetric"');
+    endswitch
   endif
 
   if (m == 1)
     c = 1;
   else
-    m = m - 1;
+    if (! periodic)
+      m = m - 1;
+    endif
     c = 0.54 - 0.46 * cos (2 * pi * (0:m)' / m);
   endif
 
+  if (periodic)
+    c = c(1:end-1);
+  endif
+
 endfunction
 
 
@@ -57,8 +82,16 @@
 %! A = hamming (N);
 %! assert (A (ceil (N/2)), 1);
 
+%!assert (hamming (15), hamming (15, "symmetric"));
+%!assert (hamming (16)(1:15), hamming (15, "periodic"));
+%!test
+%! N = 16;
+%! A = hamming (N, "periodic");
+%! assert (A (N/2 + 1), 1);
+
 %!error hamming ()
 %!error hamming (0.5)
 %!error hamming (-1)
 %!error hamming (ones (1,4))
+%!error hamming (1, "invalid");
 
--- a/scripts/signal/hanning.m
+++ b/scripts/signal/hanning.m
@@ -17,9 +17,16 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} hanning (@var{m})
+## @deftypefn  {Function File} {} hanning (@var{m})
+## @deftypefnx {Function File} {} hanning (@var{m}, "periodic")
+## @deftypefnx {Function File} {} hanning (@var{m}, "symmetric")
 ## Return the filter coefficients of a Hanning window of length @var{m}.
 ##
+## If the optional argument @qcode{"periodic"} is given, the periodic form
+## of the window is returned.  This is equivalent to the window of length
+## @var{m}+1 with the last coefficient removed.  The optional argument
+## @qcode{"symmetric"} is equivalent to not specifying a second argument.
+##
 ## For a definition of the Hanning window, see e.g.,
 ## @nospell{A.V. Oppenheim & R. W. Schafer},
 ## @cite{Discrete-Time Signal Processing}.
@@ -28,23 +35,41 @@
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
 ## Description: Coefficients of the Hanning window
 
-function c = hanning (m)
+function c = hanning (m, opt)
 
-  if (nargin != 1)
+  if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
   if (! (isscalar (m) && (m == fix (m)) && (m > 0)))
-    error ("hanning: M has to be an integer > 0");
+    error ("hanning: M must be a positive integer");
+  endif
+
+  periodic = false;
+  if (nargin == 2)
+    switch (opt)
+      case "periodic"
+        periodic = true;
+      case "symmetric"
+        ## Default option, same as no option specified.
+      otherwise
+        error ('hanning: window type must be either "periodic" or "symmetric"');
+    endswitch
   endif
 
   if (m == 1)
     c = 1;
   else
-    m = m - 1;
+    if (! periodic)
+      m = m - 1;
+    endif
     c = 0.5 - 0.5 * cos (2 * pi * (0 : m)' / m);
   endif
 
+  if (periodic)
+    c = c(1:end-1);
+  endif
+
 endfunction
 
 
@@ -57,8 +82,16 @@
 %! A = hanning (N);
 %! assert (A(ceil (N/2)), 1);
 
+%!assert (hanning (15), hanning (15, "symmetric"));
+%!assert (hanning (16)(1:15), hanning (15, "periodic"));
+%!test
+%! N = 16;
+%! A = hanning (N, "periodic");
+%! assert (A (N/2 + 1), 1);
+
 %!error hanning ()
 %!error hanning (0.5)
 %!error hanning (-1)
 %!error hanning (ones (1,4))
+%!error hanning (1, "invalid");