41 #if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
78 if (norm == static_cast<T> (0.0))
80 error (
"filter: the first element of A must be nonzero");
85 if (dim < 0 || dim > x_dims.
length ())
87 error (
"filter: DIM must be a valid dimension");
96 if (si_len != ab_len - 1)
98 error (
"filter: first dimension of SI must be of length max (length (a), length (b)) - 1");
104 error (
"filter: dimensionality of SI and X must agree");
110 if (si_dims(i) != x_dims(i-1))
112 error (
"filter: dimensionality of SI and X must agree");
118 if (si_dims(i) != x_dims(i))
120 error (
"filter: dimensionality of SI and X must agree");
128 if (norm != static_cast<T> (1.0))
134 if (a_len <= 1 && si_len <= 0)
140 for (
int i = 0; i < dim; i++)
141 x_stride *= x_dims(i);
148 x_offset = num * x_len;
153 while (x_offset >= x_stride)
155 x_offset -= x_stride;
158 x_offset += x_offset2 * x_stride * x_len;
167 const T *pa = a.
data ();
168 const T *pb = b.
data ();
169 const T *px = x.
data ();
175 i++, idx += x_stride)
177 py[idx] = psi[0] + pb[0] * px[idx];
185 psi[j] = psi[j+1] - pa[j+1] * py[idx] + pb[j+1] * px[idx];
188 psi[si_len-1] = pb[si_len] * px[idx] - pa[si_len] * py[idx];
194 psi[0] = pb[si_len] * px[idx] - pa[si_len] * py[idx];
203 const T *pb = b.
data ();
204 const T *px = x.
data ();
210 i++, idx += x_stride)
212 py[idx] = psi[0] + pb[0] * px[idx];
220 psi[j] = psi[j+1] + pb[j+1] * px[idx];
223 psi[si_len-1] = pb[si_len] * px[idx];
229 psi[0] = pb[1] * px[idx];
238 #if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
265 while (dim < x_dims.
length () && x_dims(dim) <= 1)
269 if (dim == x_dims.
length ())
272 else if (dim < 0 || dim > x_dims.
length ())
274 error (
"filter: DIM must be a valid dimension");
283 for (
int i = dim; i > 0; i--)
284 si_dims(i) = si_dims(i-1);
289 return filter (b, a, x, si, dim);
294 @deftypefn {Built-in Function} {@var{y} =} filter (@var{b}, @var{a}, @var{x})\n\
295 @deftypefnx {Built-in Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si})\n\
296 @deftypefnx {Built-in Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, [], @var{dim})\n\
297 @deftypefnx {Built-in Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si}, @var{dim})\n\
298 Apply a 1-D digital filter to the data @var{x}.\n\
300 @code{filter} returns the solution to the following linear, time-invariant\n\
301 difference equation:\n\
304 \\sum_{k=0}^N a_{k+1} y_{n-k} = \\sum_{k=0}^M b_{k+1} x_{n-k}, \\qquad\n\
309 @c Set example in small font to prevent overfull line\n\
314 SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k) for 1<=n<=length(x)\n\
324 N=length(a)-1 and M=length(b)-1.\n\
327 $a \\in \\Re^{N-1}$, $b \\in \\Re^{M-1}$, and $x \\in \\Re^P$.\n\
329 The result is calculated over the first non-singleton dimension of @var{x}\n\
330 or over @var{dim} if supplied.\n\
332 An equivalent form of the equation is:\n\
335 y_n = -\\sum_{k=1}^N c_{k+1} y_{n-k} + \\sum_{k=0}^M d_{k+1} x_{n-k}, \\qquad\n\
340 @c Set example in small font to prevent overfull line\n\
345 y(n) = - SUM c(k+1) y(n-k) + SUM d(k+1) x(n-k) for 1<=n<=length(x)\n\
355 c = a/a(1) and d = b/a(1).\n\
358 $c = a/a_1$ and $d = b/a_1$.\n\
361 If the fourth argument @var{si} is provided, it is taken as the\n\
362 initial state of the system and the final state is returned as\n\
363 @var{sf}. The state vector is a column vector whose length is\n\
364 equal to the length of the longest coefficient vector minus one.\n\
365 If @var{si} is not supplied, the initial state vector is set to all\n\
368 In terms of the Z Transform, @var{y} is the result of passing the\n\
369 discrete-time signal @var{x} through a system characterized by the following\n\
370 rational system function:\n\
373 H(z) = {\\displaystyle\\sum_{k=0}^M d_{k+1} z^{-k}\n\
374 \\over 1 + \\displaystyle\\sum_{k+1}^N c_{k+1} z^{-k}}\n\
384 H(z) = ---------------------\n\
386 1 + SUM c(k+1) z^(-k)\n\
392 @seealso{filter2, fftfilt, freqz}\n\
397 int nargin = args.
length ();
399 if (nargin < 3 || nargin > 5)
405 const char *errmsg =
"filter: arguments a and b must be vectors";
412 dim = args(4).nint_value () - 1;
413 if (dim < 0 || dim >= x_dims.
length ())
415 error (
"filter: DIM must be a valid dimension");
423 while (dim < x_dims.
length () && x_dims(dim) <= 1)
427 if (dim == x_dims.
length ())
431 bool isfloat = (args(0).is_single_type ()
432 || args(1).is_single_type ()
433 || args(2).is_single_type ()
434 || (nargin >= 4 && args(3).is_single_type ()));
436 if (args(0).is_complex_type ()
437 || args(1).is_complex_type ()
438 || args(2).is_complex_type ()
439 || (nargin >= 4 && args(3).is_complex_type ()))
452 if (nargin == 3 || args(3).is_empty ())
460 for (
int i = dim; i > 0; i--)
461 si_dims(i) = si_dims(i-1);
468 si = args(3).float_complex_array_value ();
500 if (nargin == 3 || args(3).is_empty ())
508 for (
int i = dim; i > 0; i--)
509 si_dims(i) = si_dims(i-1);
516 si = args(3).complex_array_value ();
551 if (nargin == 3 || args(3).is_empty ())
559 for (
int i = dim; i > 0; i--)
560 si_dims(i) = si_dims(i-1);
567 si = args(3).float_array_value ();
599 if (nargin == 3 || args(3).is_empty ())
607 for (
int i = dim; i > 0; i--)
608 si_dims(i) = si_dims(i-1);
615 si = args(3).array_value ();
OCTINTERP_API void print_usage(void)
octave_idx_type numel(void) const
Number of elements in the array.
octave_idx_type length(void) const
#define DEFUN(name, args_name, nargout_name, doc)
void error(const char *fmt,...)
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
bool is_vector(void) const
MArray< double > filter(MArray< double > &, MArray< double > &, MArray< double > &, int dim)
const T * data(void) const
double norm(const ColumnVector &v)
void resize(const dim_vector &dv, const T &rfv)
octave_idx_type length(void) const
Number of elements in the array.
const T * fortran_vec(void) const
MArray< T > reshape(const dim_vector &new_dims) const
F77_RET_T const double * x