changeset 26244:58b3107a00bc

Update documentation for movXXX functions (bug #48774). * NEWS: Announce new movXXX functions. * octave.texi: Add new submenu "Statistics on Sliding Windows of Data". * stats.txi: Add @DOCSTRING entries for movfun, movmin, movslice. * scripts/signal/__parse_movargs__.m: Function moved from signal/private/parse_moveargs.m. Use standard Octave copyright block. * movfun.m, movslice.m: Use standard Octave copyright block. Rewrite documentation using more Texinfo features. * scripts/signal/module.mk: Remove movmin.m, add __parse_movargs__.m to. build system. * scripts/statistics/movmin.m: Function moved from scripts/signal/ dir. Use standard Octave copyright block. Rewrite documentation using more Texinfo features. * scripts/statistics/module.mk: Add movmin.m to build system.
author Juan Pablo Carbajal <ajuanpi+dev@gmail.com>
date Sun, 16 Dec 2018 00:13:55 -0800
parents b22a2aa820e6
children af99ea9c325f
files NEWS doc/interpreter/octave.texi doc/interpreter/stats.txi scripts/signal/__parse_movargs__.m scripts/signal/module.mk scripts/signal/movfun.m scripts/signal/movmin.m scripts/signal/movslice.m scripts/signal/private/parse_movargs.m scripts/statistics/module.mk scripts/statistics/movmin.m
diffstat 11 files changed, 249 insertions(+), 174 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Sat Dec 15 20:28:52 2018 -0800
+++ b/NEWS	Sun Dec 16 00:13:55 2018 -0800
@@ -8,6 +8,15 @@
     aforementioned functions by properly overloading the "size"
     function.
 
+ ** A new core function movfun will apply a function to a sliding
+    window of arbitrary size on a full dataset and accumulate the
+    results.  Many common cases have been implemented using the naming
+    scheme movXXX where "XXX" is the function that will be applied.
+    For example, the moving average over a dataset is movmean.
+    New moving window functions:
+    
+    movfun   movmin   movslice
+
  ** The functions issymmetric and ishermitian accept an option "nonskew"
     or "skew" to calculate the symmetric or skew-symmetric property
     of a matrix.  Performance has also been increased.
@@ -175,7 +184,10 @@
       matlab.lang.makeUniqueStrings
       matlab.lang.makeValidName
       movegui
+      movfun
       movie
+      movmin
+      movslice
       openfig
       ordeig
       savefig
--- a/doc/interpreter/octave.texi	Sat Dec 15 20:28:52 2018 -0800
+++ b/doc/interpreter/octave.texi	Sun Dec 16 00:13:55 2018 -0800
@@ -716,6 +716,7 @@
 Statistics
 
 * Descriptive Statistics::
+* Statistics on Sliding Windows of Data::
 * Basic Statistical Functions::
 * Correlation and Regression Analysis::
 * Distributions::
--- a/doc/interpreter/stats.txi	Sat Dec 15 20:28:52 2018 -0800
+++ b/doc/interpreter/stats.txi	Sun Dec 16 00:13:55 2018 -0800
@@ -47,6 +47,7 @@
 
 @menu
 * Descriptive Statistics::
+* Statistics on Sliding Windows of Data::
 * Basic Statistical Functions::
 * Correlation and Regression Analysis::
 * Distributions::
@@ -107,6 +108,20 @@
 
 @DOCSTRING(statistics)
 
+@node Statistics on Sliding Windows of Data
+@section Statistics on Sliding Windows of Data
+
+It is often useful to calculate descriptive statistics over a subsection (i.e., window) of a full dataset.  Octave provides the function @code{movfun} which
+will call an arbitrary function handle with windows of data and accumulate
+the results.  Many of the most commonly desired functions, such as the moving
+average over a window of data (@code{movmean}), are already provided.
+
+@DOCSTRING(movfun)
+
+@DOCSTRING(movslice)
+
+@DOCSTRING(movmin)
+
 @node Basic Statistical Functions
 @section Basic Statistical Functions
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/signal/__parse_movargs__.m	Sun Dec 16 00:13:55 2018 -0800
@@ -0,0 +1,48 @@
+## Copyright (C) 2018 Juan Pablo Carbajal
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+
+## Author: Juan Pablo Carbajal <ajuanpi+dev@gmail.com>
+## Created: 2018-08-13
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{args} =} __parse_movargs__ (@var{varargin})
+##
+## Parse arguments for movXXX functions before passing to @code{movfun}.
+##
+## @seealso{movfun}
+## @end deftypefn
+
+function args = __parse_movargs__ (varargin)
+
+  if (isscalar (varargin))
+    ## Either DIM or NANCOND
+    if (ischar (varargin{1}))
+      args = {"nancond", varargin{1}};
+    else
+      args = {"dim", varargin{1}};
+    endif
+  else
+    ## Name,Value pairs
+    args = varargin;
+  endif
+
+endfunction
+
+
+## No tests needed for internal function
+%!assert (1)
--- a/scripts/signal/module.mk	Sat Dec 15 20:28:52 2018 -0800
+++ b/scripts/signal/module.mk	Sun Dec 16 00:13:55 2018 -0800
@@ -3,13 +3,13 @@
   %reldir%/private
 
 %canon_reldir%_PRIVATE_FCN_FILES = \
-  %reldir%/private/parse_moveargs.m  \
   %reldir%/private/rectangle_lw.m  \
   %reldir%/private/rectangle_sw.m  \
   %reldir%/private/triangle_lw.m  \
   %reldir%/private/triangle_sw.m
 
 %canon_reldir%_FCN_FILES = \
+  %reldir%/__parse_movargs__.m \
   %reldir%/arch_fit.m \
   %reldir%/arch_rnd.m \
   %reldir%/arch_test.m \
@@ -32,7 +32,6 @@
   %reldir%/hurst.m \
   %reldir%/ifftshift.m \
   %reldir%/movfun.m \
-  %reldir%/movmin.m \
   %reldir%/movslice.m \
   %reldir%/periodogram.m \
   %reldir%/sinc.m \
--- a/scripts/signal/movfun.m	Sat Dec 15 20:28:52 2018 -0800
+++ b/scripts/signal/movfun.m	Sun Dec 16 00:13:55 2018 -0800
@@ -1,120 +1,140 @@
 ## Copyright (C) 2018 Juan Pablo Carbajal
 ##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
 ## (at your option) any later version.
 ##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ## GNU General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
 
 ## Author: Juan Pablo Carbajal <ajuanpi+dev@gmail.com>
 ## Created: 2018-08-09
 
 ## -*- texinfo -*-
-## @defun {@var{y} =} movfun (@var{fun}, @var{x}, @var{wlen})
-## @defunx {@var{y} =} movfun (@dots{}, @var{property}, @var{value})
-## Apply function @var{fun} to a moving window on @var{x}
+## @deftypefn  {} {@var{y} =} movfun (@var{fun}, @var{x}, @var{wlen})
+## @deftypefnx {} {@var{y} =} movfun (@var{fun}, @var{x}, @var{[@var{nb}, @var{na}}])
+## @deftypefnx {} {@var{y} =} movfun (@dots{}, @var{property}, @var{value})
+## Apply function @var{fun} to a moving window of length @var{wlen} on data
+## @var{x}.
 ##
-## If @var{wlen} is a scalar, the function @var{fun} is applied to a moving 
-## window of length @var{wlen}. In this case @var{wlen} must be an odd number.
-## If @var{wlen} is an array with 2 elements, the function is applied to a 
-## moving window @code{-wlen(1):wlen(2)} which always includes the middle point.
+## If @var{wlen} is a scalar, the function @var{fun} is applied to a moving
+## window of length @var{wlen}.  In this case @var{wlen} must be an odd number.
+## If @var{wlen} is an array with two elements @w{@code{[@var{nb}, @var{na}]}},
+## the function is applied to a moving window @code{-@var{nb}:@var{na}}.  This
+## window includes @var{nb} number of elements @strong{before} the current
+## element and @var{na} number of elements @strong{after} the current element.
+## The current element is always included.
 ##
-## The function works along the first non-singleton dimension unless the property
-## @asis{'dim'} is set.
-##
-## The input @var{x} is reshaped into a @var{wlen}-by-n matrix and @var{fun}
-## is called o this matrix. Therefore @var{fun} must take a single array input 
-## argument and apply the computation column-wise.
+## During calculations the data input @var{x} is reshaped into a 2-dimensional
+## @var{wlen}-by-@var{N} matrix and @var{fun} is called on this new matrix.
+## Therefore, @var{fun} must accept an array input argument and apply the
+## computation on the columns of that array.
 ##
-## The output of @var{fun} can a 1-dimensional array of length @var{ndim}.
-## In this case, the output of @var{fun} when applied to a column vector must 
-## be a @strong{row} array of length @var{ndim}.
-## When applied to a 2-dimensional array with @var{n} columns, there are two 
-## formats that work:
-## @var{fun} can return an @var{n}-by-@var{ndim} array.
-## See @code{demo ('movfun', 5)} for an example of this case.
-## Alternatively, @var{fun} can return a row array of length
-## @code{@var{ndim} * @var{n}}, where the output of @var{fun} applied to the 
-## i-th column should be in the values @code{i:@var{n}:(@var{ndim}*@var{n})}.
-## This is useful when concatenating functions into arrays, or when using
-## @command{nthargout}.
-## ## See @code{demo ('movfun', 6)} for an example of this case.
+## When applied to a column vector of length @var{n}, the function @var{fun}
+## must return a @strong{row} vector of length @var{n}.
+## When applied to an array (possibly multi-dimensional) with @var{n} columns,
+## @var{fun} may return a result in either of two formats: @w{Format 1)}
+## an array of size 1-by-@var{n}-by-@var{dim3}-by-@dots{}-by-@var{dimN}.  This
+## is the typical output format from Octave core functions.  Type
+## @code{demo ("movfun", 5)} for an example of this use case.
+## @w{Format 2)} a row vector of length
+## @code{@var{n} * @var{numel_higher_dims}} where @var{numel_higher_dims} is
+## @w{@code{prod (size (@var{x})(3:end))}}.  The output of @var{fun} for the
+## i-th input column must be found in the output at indices
+## @code{i:@var{n}:(@var{n}*@var{numel_higher_dims})}.
+## This format is useful when concatenating functions into arrays, or when
+## using @code{nthargout}.  Type @code{demo ("movfun", 6)} for an example of
+## this case.
 ##
-## If the input @var{x} is a @var{N}-by-@var{M} array, and @var{fun} returns
-## @var{K} values per input column, then the output @var{y} is a 
-## @var{N}-by-@var{M}-by-@var{K} array. All singleton dimensions are squeezed.
-## Thus, if @var{M} is 1, then @var{y} is @var{N}-by-@var{K}. If in addition 
-## @var{K} is also 1, @var{y} has the same size as the input @var{x}.
-##
-## The results on the first and last @var{wlen} elements (the boundaries) is
-## controlled by the boundary conditions property @asis{'Endpoints'}. Possible
-## values are:
+## The calculation can be controlled by specifying @var{property}/@var{value}
+## pairs.  Valid properties are
 ##
 ## @table @asis
 ##
-## @item 'open'
-## (Default) The function is applied to shorter windows at the extrema of the array,
-## e.g. for a window of length 3, @code{@var{x}(1) = @var{fun} (@var{x}(1:2))}, and
-## @code{@var{x}(end) = @var{fun} (@var{x}(end-1:end))}
+## @item @qcode{"dim"}
+## Operate along the dimension specified, rather than the default of the first
+## non-singleton dimension.
+##
+## @item @qcode{"Endpoints"}
+##
+## This property controls how results are calculated at the boundaries
+## (@w{endpoints}) of the window.  Possible values are:
+##
+## @table @asis
+## @item @qcode{"shrink"}  (default)
+## The window is truncated at the beginning and end of the array to include
+## only valid elements.  For example, with a window of length 3,
+## @code{@var{y}(1) = @var{fun} (@var{x}(1:2))}, and
+## @code{@var{y}(end) = @var{fun} (@var{x}(end-1:end))}.
 ##
-## @item 'periodic'
-## The window is wraped around so that
-## @code{@var{x}(1) = @var{fun} ([@var{x}(end-@var{k}:end) @var{x}(1:@var{k})])}, where
-## @var{k} is the radius of the window (for symmetric windows, 
-## @code{@var{k} = (@var{wlen} - 1) / 2)}
+## @item @qcode{"periodic"}
+## The window is wrapped around so that
+## @code{@var{y}(1) = @var{fun} ([@var{x}(end-@var{k}:end),
+## @var{x}(1:@var{k})])}, where @var{k} is the radius of the window.  For
+## example, with a window of length 3, 
+## @code{@var{y}(1) = @var{fun} ([@var{x}(end-1:end), @var{x}(1)])},
 ##
-## @item 'zero'
-## The array is pre- and post-padded with zeros to exactly contain the window.
+## @item @qcode{"zero"}
+## The array is pre-padded and post-padded with zeros to exactly contain the
+## window.  For example, with a window of length 3,
+## @code{@var{y}(1) = @var{fun} ([0, @var{x}(1:2)])}, and
+## @code{@var{y}(end) = @var{fun} ([@var{x}(end-1:end), 0])}.
 ##
-## @item 'same'
-## The resulting array @var{y} has the same values as @var{x} at the boundaries.
+## @item @qcode{"same"}
+## The resulting array @var{y} has the same values as @var{x} at the
+## boundaries.
 ##
-## @item 'discard'
-## The resulting array @var{y} is NaN at the boundaries.
+## @item @qcode{"fill"}
+## The resulting array @var{y} has @code{NaN} at the boundaries.
 ##
 ## @end table
 ##
 ## Note that for some of these values, the window size at the boundaries is not
-## the same as in the middle part, and @var{fun} needs to work on these cases.
-##
-## Other optional properties are:
-##
-## @table @asis
+## the same as in the middle part, and @var{fun} must work with these cases.
 ##
-## @item 'nancond'
-## Indicating whether @code{nan} or @code{NA} values should be omitted (value: 
-## @asis{'omitnan'}), or included (value: @asis{'includenan'}) in the arguments 
-## passed to @var{func}. The default is @asis{'omitnan'}.
+## @item @qcode{"nancond"}
+## Controls whether @code{NaN} or @code{NA} values should be excluded (value:
+## @qcode{"omitnan"}), or included (value: @qcode{"includenan"}) in the
+## arguments passed to @var{fun}.  The default is @qcode{"omitnan"}.
 ##
-## @item 'outdim'
-## A row array that allow for the selection of output dimensions. This is useful
-## only when @var{fun} returns an array dimension of @var{ndim}. The default is 
-## to return all output dimensions.
+## @item @qcode{"outdim"}
+## A row vector that selects which dimensions of the calculation will appear
+## in the output @var{y}.  This is only useful when @var{fun} returns an
+## N-dimensinoal array in @w{Format 1}.  The default is to return all output
+## dimensions.
 ##
 ## @end table
 ##
-## @strong{Programming tip}: the property 'outdim' is implemented to save memory
-## in case the output is highly dimensional or a wrapper to the base function 
-## that selects the desired outputs is too costly. The easiest way to select 
-## output dimension if memory is not an issue is to filter the result of 
-## @command{movfun}. If code complexity is not an issue one can create a 
-## wrapper, e.g. using anonymous functions. For example, if @code{basefunc} is 
-## the function returning a @var{K}-dimensional row output and we wish dimension
-## @var{D}, we could pass the following wrapper to @command{movfun}:
+## Programming Note: The property @qcode{"outdim"} can be used to save memory
+## when the output of @var{fun} has many dimensions, or when a wrapper to the
+## base function that selects the desired outputs is too costly.  When memory
+## is not an issue, the easiest way to select output dimensions is to first
+## calculate the complete result with @code{movfun} and then filter that result
+## with indexing.  If code complexity is not an issue then a wrapper can be
+## created using anonymous functions.  For example, if @code{basefun}
+## is a function returning a @var{K}-dimensional row output, and only
+## dimension @var{D} is desired, then the following wrapper could be used.
+##
 ## @example
-## @code{@var{fun} = @@(x)basefunc (x)(:,size(x,2) * (@var{D}-1) + (1:size(x,2)))}
+## @group
+## @var{fun} = @@(x) basefun (x)(:,size(x,2) * (@var{D}-1) + (1:size(x,2)));
+## @var{y} = movfun (@@fun, @dots{});
+## @end group
 ## @end example
 ##
-## @seealso{movslice, prepad, postpad, permute, reshape, reshapemod}
-## @end defun
+## @seealso{movslice, prepad, postpad, permute, reshape}
+## @end deftypefn
 
+## FIXME: variable names in function prototype should match documentation.
 function Y = movfun (func, X, wlen, varargin)
   persistent dispatch;
 
@@ -289,6 +309,7 @@
   y = nan (length (idxp), odim);
 endfunction
 
+
 %!demo
 %! t  = 2 * pi * linspace (0,1,100).';
 %! x  = sin (3 * t);
@@ -510,4 +531,3 @@
 %!error(movfun(@(x)[min(x) max(x)], (1:10).', 3, 'Outdim', 3)) % outdim > dim
 %!assert(size(movfun(@(x)[min(x) max(x)], (1:10).', 3)), [10 2])
 %!assert(size(movfun(@(x)[min(x) max(x)], cumsum(ones(10,5),2), 3)), [10 5 2])
-
--- a/scripts/signal/movmin.m	Sat Dec 15 20:28:52 2018 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-## Copyright (C) 2018 Juan Pablo Carbajal
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-## Author: Juan Pablo Carbajal <ajuanpi+dev@gmail.com>
-## Created: 2018-08-13
-
-## -*- texinfo -*-
-## @defun {@var{y} =} movmin (@var{x}, @var{wlen})
-## @defunx {@var{y} =} movmin (@dots{}, @var{dim})
-## @defunx {@var{y} =} movmin (@dots{}, @var{nanstr})
-## @defunx {@var{y} =} movmin (@dots{}, @var{property}, @var{value})
-## Minimum of @var{x} over sliding window of length @var{wlen}.
-##
-## This is equivalent to
-## @code{movfun (@@min, @var{x}, @var{wlen}, args@{:@}}
-## where @code{args = @{'dim', @var{dim}, 'nancond', @var{nanstr}, @dots{}@}}
-##
-## Property @asis{'SamplePoints'} are not implemented yet
-##
-## @seealso{movfun}
-## @end defun
-
-function y = movmin (x, wlen, varargin)
-  y = movfun (@min, x, wlen, parse_movargs(varargin{:}){:});
-endfunction
--- a/scripts/signal/movslice.m	Sat Dec 15 20:28:52 2018 -0800
+++ b/scripts/signal/movslice.m	Sun Dec 16 00:13:55 2018 -0800
@@ -1,42 +1,54 @@
 ## Copyright (C) 2018 Juan Pablo Carbajal
 ##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
 ## (at your option) any later version.
 ##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ## GNU General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
 
 ## Author: Juan Pablo Carbajal <ajuanpi+dev@gmail.com>
 ## Created: 2018-12-08
 
 ## -*- texinfo -*-
-## @defun {@var{slc} =} movslice (@var{N}, @var{wlen})
-## @defunx {[@dots{} @var{c} @var{pre} @var{pos} @var{w}] =} movslice (@dots{})
-## Generate indices to slice a 1D array of length @var{N} in windows @var{wlen}
+## @deftypefn  {} {@var{slcidx} =} movslice (@var{N}, @var{wlen})
+## @deftypefnx {} {[@var{slcidx}, @var{c}, @var{pre}, @var{pos}, @var{w}] =} movslice (@dots{})
+## Generate indices to slice a vector of length @var{N} in to windows
+## of length @var{wlen}.
+##
+## FIXME: Document inputs N, wlen
 ##
-## TODO
-## @seealso{movfun, reshapemod}
-## @end defun
+## FIXME: Document outputs slcidx, c, pre, pos, w
+## @seealso{movfun}
+## @end deftypefn
 
-function [I, C, Cpre, Cpos, win] = movslice (N, wlen)
-  # TODO asymmetric window
+## FIXME: variable names in function prototype should match documentation.
+function [slcidx, C, Cpre, Cpos, win] = movslice (N, wlen)
+
+  ## FIXME: Input validation for N, wlen
+  ## FIXME: Eventually add asymmetric window
   if (isscalar (wlen))
     hwlen = (wlen - 1) / 2;
     wlen = [hwlen hwlen];
   endif
 
-  Cpre = 1:wlen(1);               % centers that can't fit the pre-window
-  Cnf  = N - wlen(2) + 1;         % first center that can't fit the post-window
-  Cpos = Cnf:N;                   % centers that can't fit post-window
+  Cpre = 1:wlen(1);               # centers that can't fit the pre-window
+  Cnf  = N - wlen(2) + 1;         # first center that can't fit the post-window
+  Cpos = Cnf:N;                   # centers that can't fit post-window
   C    = (wlen(1) + 1):(Cnf - 1);
   win  = (-wlen(1):wlen(2)).';
-  I    = C + win;
+  slcidx = C + win;
+
 endfunction
 
+
+## FIXME: Need BIST tests
--- a/scripts/signal/private/parse_movargs.m	Sat Dec 15 20:28:52 2018 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-## Copyright (C) 2018 Juan Pablo Carbajal
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-## Author: Juan Pablo Carbajal <ajuanpi+dev@gmail.com>
-## Created: 2018-08-13
-
-## -*- texinfo -*-
-## @defun {@var{y} =} parse_movargs (@var{x})
-## Parse arguments in compatibility with other software.
-##
-## Undocumented private function
-## @end defun
-
-function args = parse_movargs (varargin)
-  if (numel (varargin) == 1) # scalar was given --> dim or nancond
-    if (ischar (varargin{1})) # --> nancond
-      args = {'nancond', varargin{1}};
-    else # --> dim
-      args = {'dim', varargin{1}};
-    endif
-  else # Name,Value pairs
-    args = varargin;
-  endif
-endfunction
--- a/scripts/statistics/module.mk	Sat Dec 15 20:28:52 2018 -0800
+++ b/scripts/statistics/module.mk	Sun Dec 16 00:13:55 2018 -0800
@@ -24,6 +24,7 @@
   %reldir%/median.m \
   %reldir%/mode.m \
   %reldir%/moment.m \
+  %reldir%/movmin.m \
   %reldir%/prctile.m \
   %reldir%/quantile.m \
   %reldir%/range.m \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/statistics/movmin.m	Sun Dec 16 00:13:55 2018 -0800
@@ -0,0 +1,40 @@
+## Copyright (C) 2018 Juan Pablo Carbajal
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+
+## Author: Juan Pablo Carbajal <ajuanpi+dev@gmail.com>
+## Created: 2018-08-13
+
+## -*- texinfo -*-
+## @deftypefn  {} {@var{y} =} movmin (@var{x}, @var{wlen})
+## @deftypefnx {} {@var{y} =} movmin (@var{x}, [@var{na}, @var{nb}])
+## @deftypefnx {} {@var{y} =} movmin (@dots{}, @var{dim})
+## @deftypefnx {} {@var{y} =} movmin (@dots{}, @var{nanstr})
+## @deftypefnx {} {@var{y} =} movmin (@dots{}, @var{property}, @var{value})
+## Minimum of @var{x} over a sliding window of length @var{wlen}.
+##
+## FIXME: Need explanation of all options.  Write once and then replicate.
+##
+## @seealso{movfun}
+## @end deftypefn
+
+function y = movmin (x, wlen, varargin)
+  y = movfun (@min, x, wlen, __parse_movargs__ (varargin{:}){:});
+endfunction
+
+
+## FIXME: Need BIST tests