1 ## Copyright (C) 2008 David Bateman <adb014@gmail.com>
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
17 ## @deftypefn {Function File} {@var{y} = } buffer (@var{x}, @var{n}, @var{p}, @var{opt})
18 ## @deftypefnx {Function File} {[@var{y}, @var{z}, @var{opt}] = } buffer (@dots{})
19 ## Buffer a signal into a data frame. The arguments to @code{buffer} are
23 ## The data to be buffered.
26 ## The number of rows in the produced data buffer. This is an positive
27 ## integer value and must be supplied.
30 ## An integer less than @var{n} that specifies the under- or overlap
31 ## between column in the data frame. The default value of @var{p} is 0.
34 ## In the case of an overlap, @var{opt} can be either a vector of length
35 ## @var{p} or the string 'nodelay'. If @var{opt} is a vector, then the
36 ## first @var{p} entries in @var{y} will be filled with these values. If
37 ## @var{opt} is the string 'nodelay', then the first value of @var{y}
38 ## corresponds to the first value of @var{x}.
40 ## In the can of an underlap, @var{opt} must be an integer between 0 and
41 ## @code{-@var{p}}. The represents the initial underlap of the first
44 ## The default value for @var{opt} the vector @code{zeros (1, @var{p})}
45 ## in the case of an overlap, or 0 otherwise.
48 ## In the case of a single output argument, @var{y} will be padded with
49 ## zeros to fill the missing values in the data frame. With two output
50 ## arguments @var{z} is the remaining data that has not been used in the
51 ## current data frame.
53 ## Likewise, the output @var{opt} is the overlap, or underlap that might
54 ## be used for a future call to @code{code} to allow continuous buffering.
57 function [y, z, opt] = buffer (x, n, p, opt)
59 if (nargin < 2 || nargin > 4)
62 if (!isscalar (n) || n != floor (n))
63 error ("buffer: n must be an inetger");
67 elseif (!isscalar (p) || p != floor (p) || p >= n)
68 error ("buffer: p must be an inetger less than n");
85 if (isscalar (opt) && opt == floor (opt) && opt >= 0 && opt <= -p)
88 error ("buffer: expecting fourth argument to be and integer between 0 and -p");
96 m = ceil ((l - lopt) / (n - p));
98 y (1 : l - lopt) = x (lopt + 1 : end);
100 y (end + p + 1 : end, :) = [];
103 if (strcmp (opt, "nodelay"))
104 y = [y ; zeros(p, m)];
111 y (is : ie, 1 : end - off) = y (1 : in, 1 + off : end);
120 [i, j] = ind2sub([n-p, m], l);
121 if (all ([i, j] == [n-p, m]))
124 y (:, end - off + 2 : end) = [];
126 y (end - p + 1 : end, 1 : end - 1) = y (1 : p, 2 : end);
127 if (sub2ind([n-p, m], p, m) >= l)
132 error ("buffer: unexpected string argument");
134 elseif (isvector (opt))
135 if (length (opt) == p)
137 y = [zeros(p, m); y];
141 y (1 : in, off) = opt(off:end);
151 y (is : ie, 1 + off : end) = ...
152 y (end - in + 1 : end, 1 : end - off);
162 y (1 : p, 2 : end) = y (end - p + 1 : end, 1 : end - 1);
165 error ("buffer: opt vector must be of length p");
168 error ("buffer: unrecognized fourth argument");
173 [i, j] = ind2sub (size(y), l + lopt + p * (size (y, 2) - 1));
174 if (any ([i, j] != size (y)))
175 z = y (1 + p : i, end);
181 [i, j] = ind2sub (size (y) + [-p, 0], l - lopt);
193 opt = max(0, size (y, 2) * (n - p) + opt - l);
195 opt = y(end-p+1:end)(:);
202 %!error (buffer(1:10, 4.1))
203 %!assert (buffer(1:10, 4), reshape([1:10,0,0],[4,3]))
204 %!assert (buffer(1:10, 4, 1), reshape([0:3,3:6,6:9,9,10,0,0],[4,4]))
205 %!assert (buffer(1:10, 4, 2), reshape ([0,0:2,1:4,3:6,5:8,7:10],[4,5]))
206 %!assert (buffer(1:10, 4, 3), [0,0,0:7;0,0:8;0:9;1:10])
207 %!error (buffer(1:10, 4, 3.1))
208 %!error (buffer(1:10, 4, 4))
209 %!assert (buffer(1:10, 4, -1), reshape([1:4,6:9],[4,2]))
210 %!assert (buffer(1:10, 4, -2), reshape([1:4,7:10],[4,2]))
211 %!assert (buffer(1:10, 4, -3), reshape([1:4,8:10,0],[4,2]))
212 %!assert (buffer(1:10, 4, 1, 11), reshape([11,1:3,3:6,6:9,9,10,0,0],[4,4]))
213 %!error (buffer(1:10, 4, 1, [10,11]))
214 %!assert (buffer(1:10, 4, 1, 'nodelay'), reshape([1:4,4:7,7:10],[4,3]))
215 %!error (buffer(1:10, 4, 1, 'badstring'))
216 %!assert (buffer(1:10, 4, 2,'nodelay'), reshape ([1:4,3:6,5:8,7:10],[4,4]))
217 %!assert (buffer(1:10, 4, 3, [11,12,13]),[11,12,13,1:7;12,13,1:8;13,1:9;1:10])
218 %!assert (buffer(1:10, 4, 3, 'nodelay'),[1:8;2:9;3:10;4:10,0])
219 %!assert (buffer(1:11,4,-2,1),reshape([2:5,8:11],4,2))
222 %! [y, z] = buffer(1:12,4);
223 %! assert (y, reshape(1:12,4,3));
224 %! assert (z, zeros (1,0));
227 %! [y, z] = buffer(1:11,4);
228 %! assert (y, reshape(1:8,4,2));
229 %! assert (z, [9, 10, 11]);
232 %! [y, z] = buffer([1:12]',4);
233 %! assert (y, reshape(1:12,4,3));
234 %! assert (z, zeros (0,1));
237 %! [y, z] = buffer([1:11]',4);
238 %! assert (y, reshape(1:8,4,2));
239 %! assert (z, [9; 10; 11]);
242 %! [y,z,opt] = buffer(1:15,4,-2,1);
243 %! assert (y, reshape([2:5,8:11],4,2));
244 %! assert (z, [14, 15]);
248 %! [y,z,opt] = buffer(1:11,4,-2,1);
249 %! assert (y, reshape([2:5,8:11],4,2));
250 %! assert (z, zeros (1,0));
254 %! [y,z,opt] = buffer([1:15]',4,-2,1);
255 %! assert (y, reshape([2:5,8:11],4,2));
256 %! assert (z, [14; 15]);
260 %! [y,z,opt] = buffer([1:11]',4,-2,1);
261 %! assert (y, reshape([2:5,8:11],4,2));
262 %! assert (z, zeros (0, 1));
266 %! [y,z,opt] = buffer([1:11],5,2,[-1,0]);
267 %! assert (y, reshape ([-1:3,2:6,5:9],[5,3]));
268 %! assert (z, [10, 11]);
269 %! assert (opt, [8; 9]);
272 %! [y,z,opt] = buffer([1:11]',5,2,[-1,0]);
273 %! assert (y, reshape ([-1:3,2:6,5:9],[5,3]));
274 %! assert (z, [10; 11]);
275 %! assert (opt, [8; 9]);