1########################################################################
2##
3## Copyright (C) 2018-2021 The Octave Project Developers
4##
5## See the file COPYRIGHT.md in the top-level directory of this
6## distribution or <https://octave.org/copyright/>.
7##
8## This file is part of Octave.
9##
10## Octave is free software: you can redistribute it and/or modify it
11## under the terms of the GNU General Public License as published by
12## the Free Software Foundation, either version 3 of the License, or
13## (at your option) any later version.
14##
15## Octave is distributed in the hope that it will be useful, but
16## WITHOUT ANY WARRANTY; without even the implied warranty of
17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18## GNU General Public License for more details.
19##
20## You should have received a copy of the GNU General Public License
21## along with Octave; see the file COPYING.  If not, see
22## <https://www.gnu.org/licenses/>.
23##
24########################################################################
25
26## -*- texinfo -*-
27## @deftypefn  {} {@var{slcidx} =} movslice (@var{N}, @var{wlen})
28## @deftypefnx {} {[@var{slcidx}, @var{C}, @var{Cpre}, @var{Cpost}, @var{win}] =} movslice (@dots{})
29## Generate indices to slice a vector of length @var{N} in to windows
30## of length @var{wlen}.
31##
32## FIXME: Document inputs N, wlen
33##
34## FIXME: Document outputs slcidx, C, Cpre, Cpost, win.
35## @seealso{movfun}
36## @end deftypefn
37
38function [slcidx, C, Cpre, Cpost, win] = movslice (N, wlen)
39
40  if (nargin != 2)
41    print_usage ();
42  endif
43
44  ## Validate N
45  if (! (isscalar (N) && isindex (N)))
46    error ("movslice: N must be a positive integer");
47  endif
48
49  ## Validate window length
50  if (! (isnumeric (wlen) && all (wlen >= 0) && fix (wlen) == wlen))
51    error ("Octave:invalid-input-arg",
52           "movslice: WLEN must be a scalar or 2-element array of integers >= 0");
53  endif
54  if (isscalar (wlen))
55    ## Check for proper window length
56    if (wlen == 1)
57      error ("Octave:invalid-input-arg", "movslice: WLEN must be > 1");
58    endif
59  elseif (numel (wlen) == 2)
60    ## wlen = [nb, na].  No further validation here.
61  else
62    error ("Octave:invalid-input-arg",
63           "movslice: WLEN must be a scalar or 2-element array of integers >= 0");
64  endif
65  if (max (wlen) > N)
66    error ("Octave:invalid-input-arg", ...
67           "movslice: window length WLEN (%d) must be shorter than length along DIM (%d)", ...
68           max (wlen), N);
69  endif
70
71  if (isscalar (wlen))
72    if (mod (wlen, 2) == 1)
73      ## Symmetric window
74      nb = na = (wlen - 1) / 2;
75      wlen = [nb, na];
76    else
77      ## Asymmetric window
78      nb = wlen / 2;
79      na = nb - 1;
80      wlen = [nb, na];
81    endif
82  endif
83
84  Cpre  = 1:wlen(1);              # centers that can't fit the pre-window
85  Cnf   = N - wlen(2) + 1;        # first center that can't fit the post-window
86  Cpost = Cnf:N;                  # centers that can't fit centered post-window
87  C     = (wlen(1) + 1):(Cnf - 1);
88  win   = (-wlen(1):wlen(2)).';
89  slcidx = C + win;
90
91endfunction
92
93
94## FIXME: Need functional BIST tests
95
96## Test input validation
97%!error movslice ()
98%!error movslice (1)
99%!error movslice (1,2,3)
100%!error <N must be a positive integer> movslice ([1 2], 1)
101%!error <N must be a positive integer> movslice (0, 1)
102%!error <WLEN must be .* array of integers> movslice (1, {1})
103%!error <WLEN must be .* array of integers .= 0> movslice (1, -1)
104%!error <WLEN must be .* array of integers> movslice (1, 1.5)
105%!error <WLEN must be . 1> movslice (1, 1)
106%!error <WLEN must be a scalar or 2-element array> movslice (1, [1, 2, 3])
107%!error <WLEN \(3\) must be shorter than length along DIM \(1\)>
108%! movslice (1, 3);
109%!error <WLEN \(4\) must be shorter than length along DIM \(1\)>
110%! movslice (1, [4, 1]);
111%!error <WLEN \(5\) must be shorter than length along DIM \(1\)>
112%! movslice (1, [1, 5]);
113