]> Creatis software - CreaPhase.git/blob - octave_packages/signal-1.1.3/buffer.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / signal-1.1.3 / buffer.m
1 ## Copyright (C) 2008 David Bateman <adb014@gmail.com>
2 ##
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
6 ## version.
7 ##
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
11 ## details.
12 ##
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/>.
15
16 ## -*- texinfo -*-
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
20 ##
21 ## @table @asis
22 ## @item @var{x}
23 ## The data to be buffered. 
24 ##
25 ## @item @var{n}
26 ## The number of rows in the produced data buffer. This is an positive
27 ## integer value and must be supplied.
28 ##
29 ## @item @var{p}
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.
32 ##
33 ## @item @var{opt}
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}. 
39 ## 
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
42 ## column of @var{y}.
43 ##
44 ## The default value for @var{opt} the vector @code{zeros (1, @var{p})}
45 ## in the case of an overlap, or 0 otherwise.
46 ## @end table
47 ##
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.
52 ##
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.
55 ## @end deftypefn
56
57 function [y, z, opt] = buffer (x, n, p, opt)
58
59   if (nargin < 2 || nargin > 4)
60     print_usage ();
61   endif
62   if  (!isscalar (n) || n != floor (n))
63     error ("buffer: n must be an inetger");
64   endif
65   if (nargin < 3)
66     p = 0;
67   elseif (!isscalar (p) || p != floor (p) || p >= n)
68     error ("buffer: p must be an inetger less than n");
69   endif
70   if (nargin <  4)
71     if (p < 0)
72       opt = 0;
73     else
74       opt = zeros (1, p);
75     endif
76   endif
77
78   if (rows (x) == 1)
79     isrowvec = true;
80   else
81     isrowvec = false;
82   endif
83
84   if (p < 0)
85     if (isscalar (opt) && opt == floor (opt) && opt >= 0 && opt <= -p)
86       lopt = opt;
87     else
88       error ("buffer: expecting fourth argument to be and integer between 0 and -p");
89     endif
90   else
91     lopt = 0;
92   endif
93
94   x = x (:);
95   l = length (x);
96   m = ceil ((l - lopt) / (n - p));
97   y = zeros (n - p, m);
98   y (1 : l - lopt) = x (lopt + 1 : end);
99   if (p < 0)
100     y (end + p + 1 : end, :) = [];
101   elseif (p > 0)
102     if (ischar (opt))
103       if (strcmp (opt, "nodelay"))
104         y = [y ; zeros(p, m)]; 
105         if (p > n / 2)
106           is = n - p + 1;
107           in = n - p;
108           ie = is + in - 1;
109           off = 1;
110           while (in > 0)
111             y (is : ie, 1 : end - off) = y (1 : in, 1 + off : end);
112             off++;
113             is = ie + 1;
114             ie = ie + in;
115             if (ie > n)
116               ie = n;
117             endif
118             in = ie - is + 1;
119           endwhile
120           [i, j] = ind2sub([n-p, m], l);
121           if (all ([i, j] == [n-p, m]))
122             off --;
123           endif
124           y (:, end - off + 2 : end) = [];
125         else
126           y (end - p + 1 : end, 1 : end - 1) = y (1 : p, 2 : end);
127           if (sub2ind([n-p, m], p, m) >= l)
128             y (:, end) = [];
129           endif
130         endif
131       else
132         error ("buffer: unexpected string argument");
133       endif
134     elseif (isvector (opt))
135       if (length (opt) == p)
136         lopt = p;
137         y = [zeros(p, m); y]; 
138         in = p;
139         off = 1;
140         while (in > 0)
141           y (1 : in, off) = opt(off:end);
142           off++;
143           in = in - n + p;
144         endwhile
145         if (p > n / 2)
146           in = n - p;
147           ie = p;
148           is = p - in + 1;
149           off = 1;
150           while (ie > 0)
151             y (is : ie, 1 + off : end) = ...
152               y (end - in + 1 : end, 1 : end - off);
153             off++;
154             ie = is - 1;
155             is = is - in;
156             if (is < 1)
157               is = 1;
158             endif
159             in = ie - is + 1;
160           endwhile
161         else
162           y (1 : p, 2 : end) = y (end - p + 1 : end, 1 : end - 1);
163         endif
164       else
165         error ("buffer: opt vector must be of length p");
166       endif
167     else
168       error ("buffer: unrecognized fourth argument");
169     endif
170   endif
171   if (nargout > 1)
172     if (p >= 0)
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);
176         y (:, end) = [];
177       else
178         z = zeros (0, 1);
179       endif
180     else
181       [i, j] = ind2sub (size (y) + [-p, 0], l - lopt);
182       if (i < size (y, 1))
183         z = y (1: i, end);
184         y (:, end) = [];
185       else
186         z = zeros (0, 1);
187       endif
188     endif
189     if (isrowvec)
190       z = z.';
191     endif
192     if (p < 0)
193       opt = max(0, size (y, 2) * (n - p) + opt - l);
194     elseif (p > 0)
195       opt = y(end-p+1:end)(:);
196     else
197       opt = [];
198     endif 
199   endif
200 endfunction
201
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))
220
221 %!test
222 %! [y, z] = buffer(1:12,4);
223 %! assert (y, reshape(1:12,4,3));
224 %! assert (z, zeros (1,0));
225
226 %!test
227 %! [y, z] = buffer(1:11,4);
228 %! assert (y, reshape(1:8,4,2));
229 %! assert (z, [9, 10, 11]);
230
231 %!test
232 %! [y, z] = buffer([1:12]',4);
233 %! assert (y, reshape(1:12,4,3));
234 %! assert (z, zeros (0,1));
235
236 %!test
237 %! [y, z] = buffer([1:11]',4);
238 %! assert (y, reshape(1:8,4,2));
239 %! assert (z, [9; 10; 11]);
240
241 %!test
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]);
245 %! assert (opt, 0);
246
247 %!test
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));
251 %! assert (opt, 2);
252
253 %!test
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]);
257 %! assert (opt, 0);
258
259 %!test
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));
263 %! assert (opt, 2);
264
265 %!test 
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]);
270
271 %!test 
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]);