filter.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 // Based on Tony Richardson's filter.m.
00024 //
00025 // Originally translated to C++ by KH (Kurt.Hornik@wu-wien.ac.at)
00026 // with help from Fritz Leisch and Andreas Weingessel on Oct 20, 1994.
00027 //
00028 // Rewritten to use templates to handle both real and complex cases by
00029 // jwe, Wed Nov  1 19:15:29 1995.
00030 
00031 #ifdef HAVE_CONFIG_H
00032 #include <config.h>
00033 #endif
00034 
00035 #include "quit.h"
00036 
00037 #include "defun-dld.h"
00038 #include "error.h"
00039 #include "oct-obj.h"
00040 
00041 #if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
00042 extern MArray<double>
00043 filter (MArray<double>&, MArray<double>&, MArray<double>&, int dim);
00044 
00045 extern MArray<Complex>
00046 filter (MArray<Complex>&, MArray<Complex>&, MArray<Complex>&, int dim);
00047 
00048 extern MArray<float>
00049 filter (MArray<float>&, MArray<float>&, MArray<float>&, int dim);
00050 
00051 extern MArray<FloatComplex>
00052 filter (MArray<FloatComplex>&, MArray<FloatComplex>&, MArray<FloatComplex>&, int dim);
00053 #endif
00054 
00055 template <class T>
00056 MArray<T>
00057 filter (MArray<T>& b, MArray<T>& a, MArray<T>& x, MArray<T>& si,
00058         int dim = 0)
00059 {
00060   MArray<T> y;
00061 
00062   octave_idx_type a_len  = a.length ();
00063   octave_idx_type b_len  = b.length ();
00064 
00065   octave_idx_type ab_len = a_len > b_len ? a_len : b_len;
00066 
00067   // FIXME: The two lines below should be unecessary because
00068   //        this template is called with a and b as column vectors
00069   //        already.  However the a.resize line is currently (2011/04/26)
00070   //        necessary to stop bug #33164.
00071   b.resize (dim_vector (ab_len, 1), 0.0);
00072   if (a_len > 1)
00073     a.resize (dim_vector (ab_len, 1), 0.0);
00074 
00075   T norm = a (0);
00076 
00077   if (norm == static_cast<T>(0.0))
00078     {
00079       error ("filter: the first element of A must be non-zero");
00080       return y;
00081     }
00082 
00083   dim_vector x_dims = x.dims ();
00084   if (dim < 0 || dim > x_dims.length ())
00085     {
00086       error ("filter: DIM must be a valid dimension");
00087       return y;
00088     }
00089 
00090   octave_idx_type x_len = x_dims(dim);
00091 
00092   dim_vector si_dims = si.dims ();
00093   octave_idx_type si_len = si_dims(0);
00094 
00095   if (si_len != ab_len - 1)
00096     {
00097       error ("filter: first dimension of SI must be of length max (length (a), length (b)) - 1");
00098       return y;
00099     }
00100 
00101   if (si_dims.length () != x_dims.length ())
00102     {
00103       error ("filter: dimensionality of SI and X must agree");
00104       return y;
00105     }
00106 
00107   for (octave_idx_type i = 1; i < dim; i++)
00108     {
00109       if (si_dims(i) != x_dims(i-1))
00110         {
00111           error ("filter: dimensionality of SI and X must agree");
00112           return y;
00113         }
00114     }
00115   for (octave_idx_type i = dim+1; i < x_dims.length (); i++)
00116     {
00117       if (si_dims(i) != x_dims(i))
00118         {
00119           error ("filter: dimensionality of SI and X must agree");
00120           return y;
00121         }
00122     }
00123 
00124   if (x_len == 0)
00125     return x;
00126 
00127   if (norm != static_cast<T>(1.0))
00128     {
00129       a = a / norm;
00130       b = b / norm;
00131     }
00132 
00133   if (a_len <= 1 && si_len <= 0)
00134     return b(0) * x;
00135 
00136   y.resize (x_dims, 0.0);
00137 
00138   int x_stride = 1;
00139   for (int i = 0; i < dim; i++)
00140     x_stride *= x_dims(i);
00141 
00142   octave_idx_type x_num = x_dims.numel () / x_len;
00143   for (octave_idx_type num = 0; num < x_num; num++)
00144     {
00145       octave_idx_type x_offset;
00146       if (x_stride == 1)
00147         x_offset = num * x_len;
00148       else
00149         {
00150           octave_idx_type x_offset2 = 0;
00151           x_offset = num;
00152           while (x_offset >= x_stride)
00153             {
00154               x_offset -= x_stride;
00155               x_offset2++;
00156             }
00157           x_offset += x_offset2 * x_stride * x_len;
00158         }
00159       octave_idx_type si_offset = num * si_len;
00160 
00161       if (a_len > 1)
00162         {
00163           T *py = y.fortran_vec ();
00164           T *psi = si.fortran_vec ();
00165 
00166           const T *pa = a.data ();
00167           const T *pb = b.data ();
00168           const T *px = x.data ();
00169 
00170           psi += si_offset;
00171 
00172           for (octave_idx_type i = 0, idx = x_offset; i < x_len; i++, idx += x_stride)
00173             {
00174               py[idx] = psi[0] + pb[0] * px[idx];
00175 
00176               if (si_len > 0)
00177                 {
00178                   for (octave_idx_type j = 0; j < si_len - 1; j++)
00179                     {
00180                       OCTAVE_QUIT;
00181 
00182                       psi[j] = psi[j+1] - pa[j+1] * py[idx] + pb[j+1] * px[idx];
00183                     }
00184 
00185                   psi[si_len-1] = pb[si_len] * px[idx] - pa[si_len] * py[idx];
00186                 }
00187               else
00188                 {
00189                   OCTAVE_QUIT;
00190 
00191                   psi[0] = pb[si_len] * px[idx] - pa[si_len] * py[idx];
00192                 }
00193             }
00194         }
00195       else if (si_len > 0)
00196         {
00197           T *py = y.fortran_vec ();
00198           T *psi = si.fortran_vec ();
00199 
00200           const T *pb = b.data ();
00201           const T *px = x.data ();
00202 
00203           psi += si_offset;
00204 
00205           for (octave_idx_type i = 0, idx = x_offset; i < x_len; i++, idx += x_stride)
00206             {
00207               py[idx] = psi[0] + pb[0] * px[idx];
00208 
00209               if (si_len > 1)
00210                 {
00211                   for (octave_idx_type j = 0; j < si_len - 1; j++)
00212                     {
00213                       OCTAVE_QUIT;
00214 
00215                       psi[j] = psi[j+1] + pb[j+1] * px[idx];
00216                     }
00217 
00218                   psi[si_len-1] = pb[si_len] * px[idx];
00219                 }
00220               else
00221                 {
00222                   OCTAVE_QUIT;
00223 
00224                   psi[0] = pb[1] * px[idx];
00225                 }
00226             }
00227         }
00228     }
00229 
00230   return y;
00231 }
00232 
00233 #if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
00234 extern MArray<double>
00235 filter (MArray<double>&, MArray<double>&, MArray<double>&,
00236         MArray<double>&, int dim);
00237 
00238 extern MArray<Complex>
00239 filter (MArray<Complex>&, MArray<Complex>&, MArray<Complex>&,
00240         MArray<Complex>&, int dim);
00241 
00242 extern MArray<float>
00243 filter (MArray<float>&, MArray<float>&, MArray<float>&,
00244         MArray<float>&, int dim);
00245 
00246 extern MArray<FloatComplex>
00247 filter (MArray<FloatComplex>&, MArray<FloatComplex>&, MArray<FloatComplex>&,
00248         MArray<FloatComplex>&, int dim);
00249 #endif
00250 
00251 template <class T>
00252 MArray<T>
00253 filter (MArray<T>& b, MArray<T>& a, MArray<T>& x, int dim = -1)
00254 {
00255   dim_vector x_dims = x.dims();
00256 
00257   if (dim < 0)
00258     {
00259       // Find first non-singleton dimension
00260       while (dim < x_dims.length () && x_dims(dim) <= 1)
00261         dim++;
00262 
00263       // All dimensions singleton, pick first dimension
00264       if (dim == x_dims.length ())
00265         dim = 0;
00266     }
00267   else
00268     if (dim < 0 || dim > x_dims.length ())
00269       {
00270         error ("filter: DIM must be a valid dimension");
00271         return MArray<T> ();
00272       }
00273 
00274   octave_idx_type a_len = a.length ();
00275   octave_idx_type b_len = b.length ();
00276 
00277   octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
00278   dim_vector si_dims = x.dims ();
00279   for (int i = dim; i > 0; i--)
00280     si_dims(i) = si_dims(i-1);
00281   si_dims(0) = si_len;
00282 
00283   MArray<T> si (si_dims, T (0.0));
00284 
00285   return filter (b, a, x, si, dim);
00286 }
00287 
00288 DEFUN_DLD (filter, args, nargout,
00289   "-*- texinfo -*-\n\
00290 @deftypefn  {Loadable Function} {y =} filter (@var{b}, @var{a}, @var{x})\n\
00291 @deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si})\n\
00292 @deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, [], @var{dim})\n\
00293 @deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si}, @var{dim})\n\
00294 Return the solution to the following linear, time-invariant difference\n\
00295 equation:\n\
00296 @tex\n\
00297 $$\n\
00298 \\sum_{k=0}^N a_{k+1} y_{n-k} = \\sum_{k=0}^M b_{k+1} x_{n-k}, \\qquad\n\
00299  1 \\le n \\le P\n\
00300 $$\n\
00301 @end tex\n\
00302 @ifnottex\n\
00303 @c Set example in small font to prevent overfull line\n\
00304 \n\
00305 @smallexample\n\
00306 @group\n\
00307    N                   M\n\
00308   SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k)      for 1<=n<=length(x)\n\
00309   k=0                 k=0\n\
00310 @end group\n\
00311 @end smallexample\n\
00312 \n\
00313 @end ifnottex\n\
00314 \n\
00315 @noindent\n\
00316 where\n\
00317 @ifnottex\n\
00318  N=length(a)-1 and M=length(b)-1.\n\
00319 @end ifnottex\n\
00320 @tex\n\
00321  $a \\in \\Re^{N-1}$, $b \\in \\Re^{M-1}$, and $x \\in \\Re^P$.\n\
00322 @end tex\n\
00323 over the first non-singleton dimension of @var{x} or over @var{dim} if\n\
00324 supplied.  An equivalent form of this equation is:\n\
00325 @tex\n\
00326 $$\n\
00327 y_n = -\\sum_{k=1}^N c_{k+1} y_{n-k} + \\sum_{k=0}^M d_{k+1} x_{n-k}, \\qquad\n\
00328  1 \\le n \\le P\n\
00329 $$\n\
00330 @end tex\n\
00331 @ifnottex\n\
00332 @c Set example in small font to prevent overfull line\n\
00333 \n\
00334 @smallexample\n\
00335 @group\n\
00336             N                   M\n\
00337   y(n) = - SUM c(k+1) y(n-k) + SUM d(k+1) x(n-k)  for 1<=n<=length(x)\n\
00338            k=1                 k=0\n\
00339 @end group\n\
00340 @end smallexample\n\
00341 \n\
00342 @end ifnottex\n\
00343 \n\
00344 @noindent\n\
00345 where\n\
00346 @ifnottex\n\
00347  c = a/a(1) and d = b/a(1).\n\
00348 @end ifnottex\n\
00349 @tex\n\
00350 $c = a/a_1$ and $d = b/a_1$.\n\
00351 @end tex\n\
00352 \n\
00353 If the fourth argument @var{si} is provided, it is taken as the\n\
00354 initial state of the system and the final state is returned as\n\
00355 @var{sf}.  The state vector is a column vector whose length is\n\
00356 equal to the length of the longest coefficient vector minus one.\n\
00357 If @var{si} is not supplied, the initial state vector is set to all\n\
00358 zeros.\n\
00359 \n\
00360 In terms of the Z Transform, y is the result of passing the discrete-\n\
00361 time signal x through a system characterized by the following rational\n\
00362 system function:\n\
00363 @tex\n\
00364 $$\n\
00365 H(z) = {\\displaystyle\\sum_{k=0}^M d_{k+1} z^{-k}\n\
00366         \\over 1 + \\displaystyle\\sum_{k+1}^N c_{k+1} z^{-k}}\n\
00367 $$\n\
00368 @end tex\n\
00369 @ifnottex\n\
00370 \n\
00371 @example\n\
00372 @group\n\
00373              M\n\
00374             SUM d(k+1) z^(-k)\n\
00375             k=0\n\
00376   H(z) = ----------------------\n\
00377                N\n\
00378           1 + SUM c(k+1) z^(-k)\n\
00379               k=1\n\
00380 @end group\n\
00381 @end example\n\
00382 \n\
00383 @end ifnottex\n\
00384 @seealso{filter2, fftfilt, freqz}\n\
00385 @end deftypefn")
00386 {
00387   octave_value_list retval;
00388 
00389   int nargin  = args.length ();
00390 
00391   if (nargin < 3 || nargin > 5)
00392     {
00393       print_usage ();
00394       return retval;
00395     }
00396 
00397   const char *errmsg = "filter: arguments a and b must be vectors";
00398 
00399   int dim;
00400   dim_vector x_dims = args(2).dims ();
00401 
00402   if (nargin == 5)
00403     {
00404       dim = args(4).nint_value() - 1;
00405       if (dim < 0 || dim >= x_dims.length ())
00406         {
00407           error ("filter: DIM must be a valid dimension");
00408           return retval;
00409         }
00410     }
00411   else
00412     {
00413       // Find first non-singleton dimension
00414       dim = 0;
00415       while (dim < x_dims.length () && x_dims(dim) <= 1)
00416         dim++;
00417 
00418       // All dimensions singleton, pick first dimension
00419       if (dim == x_dims.length ())
00420         dim = 0;
00421     }
00422 
00423   bool isfloat = (args(0).is_single_type ()
00424                   || args(1).is_single_type ()
00425                   || args(2).is_single_type ()
00426                   || (nargin >= 4 && args(3).is_single_type ()));
00427 
00428   if (args(0).is_complex_type ()
00429       || args(1).is_complex_type ()
00430       || args(2).is_complex_type ()
00431       || (nargin >= 4 && args(3).is_complex_type ()))
00432     {
00433       if (isfloat)
00434         {
00435           FloatComplexColumnVector b (args(0).float_complex_vector_value ());
00436           FloatComplexColumnVector a (args(1).float_complex_vector_value ());
00437 
00438           FloatComplexNDArray x (args(2).float_complex_array_value ());
00439 
00440           if (! error_state)
00441             {
00442               FloatComplexNDArray si;
00443 
00444               if (nargin == 3 || args(3).is_empty ())
00445                 {
00446                   octave_idx_type a_len = a.length ();
00447                   octave_idx_type b_len = b.length ();
00448 
00449                   octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
00450 
00451                   dim_vector si_dims = x.dims ();
00452                   for (int i = dim; i > 0; i--)
00453                     si_dims(i) = si_dims(i-1);
00454                   si_dims(0) = si_len;
00455 
00456                   si.resize (si_dims, 0.0);
00457                 }
00458               else
00459                 {
00460                   si = args(3).float_complex_array_value ();
00461 
00462                   if (si.is_vector () && x.is_vector ())
00463                     si = si.reshape (dim_vector (si.numel (), 1));
00464                 }
00465 
00466               if (! error_state)
00467                 {
00468                   FloatComplexNDArray y (filter (b, a, x, si, dim));
00469 
00470                   if (nargout == 2)
00471                     retval(1) = si;
00472 
00473                   retval(0) = y;
00474                 }
00475               else
00476                 error (errmsg);
00477             }
00478           else
00479             error (errmsg);
00480         }
00481       else
00482         {
00483           ComplexColumnVector b (args(0).complex_vector_value ());
00484           ComplexColumnVector a (args(1).complex_vector_value ());
00485 
00486           ComplexNDArray x (args(2).complex_array_value ());
00487 
00488           if (! error_state)
00489             {
00490               ComplexNDArray si;
00491 
00492               if (nargin == 3 || args(3).is_empty ())
00493                 {
00494                   octave_idx_type a_len = a.length ();
00495                   octave_idx_type b_len = b.length ();
00496 
00497                   octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
00498 
00499                   dim_vector si_dims = x.dims ();
00500                   for (int i = dim; i > 0; i--)
00501                     si_dims(i) = si_dims(i-1);
00502                   si_dims(0) = si_len;
00503 
00504                   si.resize (si_dims, 0.0);
00505                 }
00506               else
00507                 {
00508                   si = args(3).complex_array_value ();
00509 
00510                   if (si.is_vector () && x.is_vector ())
00511                     si = si.reshape (dim_vector (si.numel (), 1));
00512                 }
00513 
00514               if (! error_state)
00515                 {
00516                   ComplexNDArray y (filter (b, a, x, si, dim));
00517 
00518                   if (nargout == 2)
00519                     retval(1) = si;
00520 
00521                   retval(0) = y;
00522                 }
00523               else
00524                 error (errmsg);
00525             }
00526           else
00527             error (errmsg);
00528         }
00529     }
00530   else
00531     {
00532       if (isfloat)
00533         {
00534           FloatColumnVector b (args(0).float_vector_value ());
00535           FloatColumnVector a (args(1).float_vector_value ());
00536 
00537           FloatNDArray x (args(2).float_array_value ());
00538 
00539           if (! error_state)
00540             {
00541               FloatNDArray si;
00542 
00543               if (nargin == 3 || args(3).is_empty ())
00544                 {
00545                   octave_idx_type a_len = a.length ();
00546                   octave_idx_type b_len = b.length ();
00547 
00548                   octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
00549 
00550                   dim_vector si_dims = x.dims ();
00551                   for (int i = dim; i > 0; i--)
00552                     si_dims(i) = si_dims(i-1);
00553                   si_dims(0) = si_len;
00554 
00555                   si.resize (si_dims, 0.0);
00556                 }
00557               else
00558                 {
00559                   si = args(3).float_array_value ();
00560 
00561                   if (si.is_vector () && x.is_vector ())
00562                     si = si.reshape (dim_vector (si.numel (), 1));
00563                 }
00564 
00565               if (! error_state)
00566                 {
00567                   FloatNDArray y (filter (b, a, x, si, dim));
00568 
00569                   if (nargout == 2)
00570                     retval(1) = si;
00571 
00572                   retval(0) = y;
00573                 }
00574               else
00575                 error (errmsg);
00576             }
00577           else
00578             error (errmsg);
00579         }
00580       else
00581         {
00582           ColumnVector b (args(0).vector_value ());
00583           ColumnVector a (args(1).vector_value ());
00584 
00585           NDArray x (args(2).array_value ());
00586 
00587           if (! error_state)
00588             {
00589               NDArray si;
00590 
00591               if (nargin == 3 || args(3).is_empty ())
00592                 {
00593                   octave_idx_type a_len = a.length ();
00594                   octave_idx_type b_len = b.length ();
00595 
00596                   octave_idx_type si_len = (a_len > b_len ? a_len : b_len) - 1;
00597 
00598                   dim_vector si_dims = x.dims ();
00599                   for (int i = dim; i > 0; i--)
00600                     si_dims(i) = si_dims(i-1);
00601                   si_dims(0) = si_len;
00602 
00603                   si.resize (si_dims, 0.0);
00604                 }
00605               else
00606                 {
00607                   si = args(3).array_value ();
00608 
00609                   if (si.is_vector () && x.is_vector ())
00610                     si = si.reshape (dim_vector (si.numel (), 1));
00611                 }
00612 
00613               if (! error_state)
00614                 {
00615                   NDArray y (filter (b, a, x, si, dim));
00616 
00617                   if (nargout == 2)
00618                     retval(1) = si;
00619 
00620                   retval(0) = y;
00621                 }
00622               else
00623                 error (errmsg);
00624             }
00625           else
00626             error (errmsg);
00627         }
00628     }
00629 
00630   return retval;
00631 }
00632 
00633 template MArray<double>
00634 filter (MArray<double>&, MArray<double>&, MArray<double>&,
00635         MArray<double>&, int dim);
00636 
00637 template MArray<double>
00638 filter (MArray<double>&, MArray<double>&, MArray<double>&, int dim);
00639 
00640 template MArray<Complex>
00641 filter (MArray<Complex>&, MArray<Complex>&, MArray<Complex>&,
00642         MArray<Complex>&, int dim);
00643 
00644 template MArray<Complex>
00645 filter (MArray<Complex>&, MArray<Complex>&, MArray<Complex>&, int dim);
00646 
00647 template MArray<float>
00648 filter (MArray<float>&, MArray<float>&, MArray<float>&,
00649         MArray<float>&, int dim);
00650 
00651 template MArray<float>
00652 filter (MArray<float>&, MArray<float>&, MArray<float>&, int dim);
00653 
00654 template MArray<FloatComplex>
00655 filter (MArray<FloatComplex>&, MArray<FloatComplex>&, MArray<FloatComplex>&,
00656         MArray<FloatComplex>&, int dim);
00657 
00658 template MArray<FloatComplex>
00659 filter (MArray<FloatComplex>&, MArray<FloatComplex>&, MArray<FloatComplex>&, int dim);
00660 
00661 /*
00662 %!shared a, b, x, r
00663 %!test
00664 %!  a = [1 1];
00665 %!  b = [1 1];
00666 %!  x = zeros (1,10); x(1) = 1;
00667 %!  assert(filter(b,   [1], x  ), [1 1 0 0 0 0 0 0 0 0]);
00668 %!  assert(filter(b,   [1], x.'), [1 1 0 0 0 0 0 0 0 0].');
00669 %!  assert(filter(b.', [1], x  ), [1 1 0 0 0 0 0 0 0 0]  );
00670 %!  assert(filter(b.', [1], x.'), [1 1 0 0 0 0 0 0 0 0].');
00671 %!  assert(filter([1], a,   x  ), [+1 -1 +1 -1 +1 -1 +1 -1 +1 -1]  );
00672 %!  assert(filter([1], a,   x.'), [+1 -1 +1 -1 +1 -1 +1 -1 +1 -1].');
00673 %!  assert(filter([1], a.', x  ), [+1 -1 +1 -1 +1 -1 +1 -1 +1 -1]  );
00674 %!  assert(filter([1], a.', x.'), [+1 -1 +1 -1 +1 -1 +1 -1 +1 -1].');
00675 %!  assert(filter(b,   a,   x  ), [1 0 0 0 0 0 0 0 0 0]  );
00676 %!  assert(filter(b.', a,   x  ), [1 0 0 0 0 0 0 0 0 0]  );
00677 %!  assert(filter(b,   a.', x  ), [1 0 0 0 0 0 0 0 0 0]  );
00678 %!  assert(filter(b.', a,   x  ), [1 0 0 0 0 0 0 0 0 0]  );
00679 %!  assert(filter(b,   a,   x.'), [1 0 0 0 0 0 0 0 0 0].');
00680 %!  assert(filter(b.', a,   x.'), [1 0 0 0 0 0 0 0 0 0].');
00681 %!  assert(filter(b,   a.', x.'), [1 0 0 0 0 0 0 0 0 0].');
00682 %!  assert(filter(b.', a,   x.'), [1 0 0 0 0 0 0 0 0 0].');
00683 %!
00684 %!test
00685 %!  r = sqrt(1/2)*(1+i);
00686 %!  a = a*r;
00687 %!  b = b*r;
00688 %!  assert(filter(b, [1], x   ), r*[1 1 0 0 0 0 0 0 0 0]   );
00689 %!  assert(filter(b, [1], r*x ), r*r*[1 1 0 0 0 0 0 0 0 0] );
00690 %!  assert(filter(b, [1], x.' ), r*[1 1 0 0 0 0 0 0 0 0].' );
00691 %!  assert(filter(b, a,   x   ),   [1 0 0 0 0 0 0 0 0 0]   );
00692 %!  assert(filter(b, a,   r*x ), r*[1 0 0 0 0 0 0 0 0 0]   );
00693 %!
00694 %!shared a, b, x, y, so
00695 %!test
00696 %!  a = [1,1]; b = [1,1];
00697 %!  x = zeros (1,10); x(1) = 1;
00698 %!  [y, so] = filter (b, [1], x, [-1]);
00699 %!  assert(y, [0 1 0 0 0 0 0 0 0 0]);
00700 %!  assert(so,0);
00701 %!
00702 %!test
00703 %!  x  = zeros (10,3); x(1,1)=-1; x(1,2)=1;
00704 %!  y0 = zeros (10,3); y0(1:2,1)=-1; y0(1:2,2)=1;
00705 %!  y = filter (b, [1], x);
00706 %!  assert(y,y0);
00707 %!
00708 %!test
00709 %!  a = [1,1]; b=[1,1];
00710 %!  x = zeros (4,4,2); x(1,1:4,1) = +1; x(1,1:4,2) = -1;
00711 %!  y0 = zeros (4,4,2); y0(1:2,1:4,1) = +1; y0(1:2,1:4,2) = -1;
00712 %!  y = filter (b, [1], x);
00713 %!  assert(y, y0);
00714 %!
00715 %!assert(filter (1, ones(10,1)/10, []), []);
00716 %!assert(filter (1, ones(10,1)/10, zeros(0,10)), zeros(0,10));
00717 %!assert(filter (1, ones(10,1)/10, single (1:5)), repmat (single (10), 1, 5));
00718 %% Test using initial conditions
00719 %!assert(filter([1, 1, 1], [1, 1], [1 2], [1, 1]), [2 2]);
00720 %!assert(filter([1, 1, 1], [1, 1], [1 2], [1, 1]'), [2 2]);
00721 %!assert(filter([1, 3], [1], [1 2; 3 4; 5 6], [4, 5]), [5 7; 6 10; 14 18]);
00722 %!error (filter([1, 3], [1], [1 2; 3 4; 5 6], [4, 5]'));
00723 %!assert(filter([1, 3, 2], [1], [1 2; 3 4; 5 6], [1 0 0; 1 0 0], 2), [2 6; 3 13; 5 21]);
00724 %% Test of DIM parameter
00725 %!test
00726 %! x = ones (2, 1, 3, 4);
00727 %! x(1,1,:,:) = [1 2 3 4; 5 6 7 8; 9 10 11 12];
00728 %! y0 = [1 1 6 2 15 3 2 1 8 2 18 3 3 1 10 2 21 3 4 1 12 2 24 3];
00729 %! y0 = reshape (y0, size (x));
00730 %! y = filter([1 1 1], 1, x, [], 3);
00731 %! assert (y, y0);
00732 
00733 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines