Bug #13346: Filter did not work on a simple delay 53/14453/6
Pierre-Aime Agnel [Wed, 23 Apr 2014 15:58:18 +0000 (17:58 +0200)]
Change-Id: Ib28aab8a32a37bed896bd49bdf29648019051e48

scilab/CHANGES_5.5.X
scilab/modules/helptools/etc/images_md5.txt
scilab/modules/helptools/images/_LaTeX_filter.xml_1.png [new file with mode: 0644]
scilab/modules/signal_processing/help/en_US/filters/filter.xml
scilab/modules/signal_processing/macros/filter.sci
scilab/modules/signal_processing/tests/nonreg_tests/bug_13346.dia.ref [new file with mode: 0644]
scilab/modules/signal_processing/tests/nonreg_tests/bug_13346.tst [new file with mode: 0644]
scilab/modules/signal_processing/tests/nonreg_tests/bug_4065.dia.ref
scilab/modules/signal_processing/tests/nonreg_tests/bug_4065.tst
scilab/modules/signal_processing/tests/unit_tests/filter.dia.ref [new file with mode: 0644]
scilab/modules/signal_processing/tests/unit_tests/filter.tst [new file with mode: 0644]

index 91caba1..2db5edd 100644 (file)
@@ -93,6 +93,9 @@ Scilab Bug Fixes
 
 * Bug #13345 fixed - Scilab did not start on Debian Wheezy (GLIBC issue).
 
+* Bug #13346 fixed - Filter did not works for simple delays.
+                     Improved documentation on the function filter.
+
 * Bug #13349 fixed - Double-clicking on a MAT-file in file browser did not load it.
 
 * Bug #13351 fixed - xstringb failed with LaTeX code.
index 31b6074..4b9e6be 100644 (file)
@@ -474,6 +474,7 @@ _LaTeX_erfcx.xml_2.png=5feafbda8ba8a657c647a355fb122b49
 _LaTeX_erfi.xml_1.png=98b6a64c2482c6be60499c854c70a678
 _LaTeX_fft.xml_1.png=30d788e922f7acbb3ef6f5d2d70bb96b
 _LaTeX_fft.xml_2.png=4b7b41681f5cfbcb0af74e4cc3ab99fc
+_LaTeX_filter.xml_1.png=f5eab130f2e7fd10b80a402952421a05
 _LaTeX_floor.xml_ru_RU_1.png=1d5ba78bbbafd3226f371146bc348363
 _LaTeX_grand.xml_1.png=75aef00d49dd8d9dfff15c7a1bb3d0eb
 _LaTeX_grand.xml_2.png=dd59088e24bed7a6af5a6ccd16e58616
diff --git a/scilab/modules/helptools/images/_LaTeX_filter.xml_1.png b/scilab/modules/helptools/images/_LaTeX_filter.xml_1.png
new file mode 100644 (file)
index 0000000..2765aef
Binary files /dev/null and b/scilab/modules/helptools/images/_LaTeX_filter.xml_1.png differ
index bcc1021..ee20428 100644 (file)
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
     * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-    * Copyright (C) 2004-2007 - INRIA - Vincent COUVERT 
-    * 
+    * Copyright (C) 2004-2007 - INRIA - Vincent COUVERT
+    *
     * This file must be used under the terms of the CeCILL.
     * This source file is licensed as described in the file COPYING, which
     * you should have received as part of this distribution.  The terms
-    * are also available at    
+    * are also available at
     * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
     *
     -->
     </refnamediv>
     <refsynopsisdiv>
         <title>Calling Sequence</title>
-        <synopsis>[y,zf] = filter(num,den,x [,zi])</synopsis>
+        <synopsis>[y,zf] = filter(B, A, x [,zi])</synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Arguments</title>
         <variablelist>
             <varlistentry>
-                <term>num</term>
+                <term>B</term>
                 <listitem>
                     <para>real vector : the coefficients of the filter numerator in decreasing power order, or a polynomial.</para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>den</term>
+                <term>A</term>
                 <listitem>
                     <para>real vector : the coefficients of the filter denominator in decreasing power order, or a polynomial.</para>
                 </listitem>
@@ -47,7 +47,7 @@
                         <literal>max(length(a),length(b))-1</literal>: the initial
                         condition relative to a "direct form II transposed" state
                         space representation. The default value is a vector filled
-                        with zeros. 
+                        with zeros.
                     </para>
                 </listitem>
             </varlistentry>
@@ -61,7 +61,7 @@
                 <term>zf</term>
                 <listitem>
                     <para>real row vector : the final state. It can be used to
-                        filter a next batch of the input signal. 
+                        filter a next batch of the input signal.
                     </para>
                 </listitem>
             </varlistentry>
         <para>
             This function filters a data sequence using a digital
             filter using a "direct form II transposed"
-            implementation
+            implementation.
+        </para>
+        <para>
+            The filter canonical form is :
+        </para>
+        <para>
+            <latex>
+                \[
+                H(z) = \frac{B(z)}{A(z)} = \frac{b_0 + b_1 z^{-1} + \dots + b_n z^{-n}}{a_0 + a_1 z^{-1} + \dots + a_n z^{-n}}
+                \]
+            </latex>
+        </para>
+        <para>
+            The algorithm uses the highest degree between <literal>degree(a)</literal> and <literal>degree(b)</literal> as value for <literal>n</literal>.
+        </para>
+        <para>
+            If the polynomial form is used for <varname>B</varname> (resp. for <varname>A</varname>) then a polynomial or a scalar must be used for <varname>A</varname> (resp. <varname>B</varname>).
         </para>
     </refsection>
     <refsection>
         <title>References</title>
         <para>
-            Oppenheim, A. V. and R.W. Schafer. Discrete-Time Signal Processing, Englewood Cliffs, NJ: Prentice-Hall, 1989, pp. 311-312. 
+            Oppenheim, A. V. and R.W. Schafer. Discrete-Time Signal Processing, Englewood Cliffs, NJ: Prentice-Hall, 1989, pp. 311-312.
         </para>
     </refsection>
+    <refsection>
+        <title>Examples</title>
+        <programlisting role="example"><![CDATA[
+            x = [1 zeros(1,9)]
+            h = [0 0 1];
+            res = filter(h, 1, x) //This creates a delay of 2 elements
+
+            z = poly(0, "z");
+            B = 1;
+            A = z^2;
+            // B/A is z^(-2)
+            // the resulting filter is also a delay of 2 elements
+            res = filter(B, A, x)
+
+            //Integrator filter
+            x = ones(1,10)
+            B = 1;
+            A = [1 -1];
+            res = filter(B, A, x)
+            ]]></programlisting>
+    </refsection>
     <refsection role="see also">
         <title>See Also</title>
         <simplelist type="inline">
index d59c095..42a748c 100644 (file)
 // are also available at
 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
 
-function [y,z] = filter(b,a,x,z)
-
+function [y, z] = filter(b, a, x, z)
     //Implements a direct form II transposed implementation of the standard
     //difference equation
 
-    if type(b)==2 then
-        //Convert polynomial to coefficients in decreasing power order
-        b=coeff(b,degree(b):-1:0),
-    else
-        //remove high order coefficients equal to zero
-        i=1;while b(i)==0,i=i+1;end;
-        b=b(i:$);
+    fname = "filter"
+    [lhs, rhs] = argn(0)
+
+    if rhs < 3 | rhs > 4
+        error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"), fname, 3, 4));
     end
 
-    if type(a)==2 then
-        //Convert polynomial to coefficients in decreasing power order
-        a=coeff(a,degree(a):-1:0);
-    else
-        //remove high order coefficients equal to zero
-        i=1;while a(i)==0,i=i+1;end
-        a=a(i:$);
+    if rhs == 3
+        z = 0;
+    end
+
+    type_b = typeof(b);
+    type_a = typeof(a);
+    type_x = typeof(x);
+    type_z = typeof(z);
+
+    if type_b <> "constant" & type_b <> "polynomial"
+        error(msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 1));
+    end
+
+    if type_a <> "constant" & type_a <> "polynomial"
+        error(msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 2));
+    end
+
+    if type_x <> "constant"
+        error(msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 3));
+    end
+
+    if type_z <> "constant"
+        error(msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 4));
+    end
+
+    if ~isreal(b)
+        error(msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 1));
+    end
+
+    if ~isreal(a)
+        error(msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 2));
+    end
+
+    if ~isreal(x)
+        error(msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 3));
+    end
+
+    if ~isreal(z)
+        error(msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 4));
+    end
+
+    if (size(a, "c") <> 1) & (size(a, "r") <> 1)
+        error(msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 1));
+    end
+
+    if (size(b, "c") <> 1) & (size(b, "r") <> 1)
+        error(msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 2));
+    end
+
+    if (size(x, "c") <> 1) & (size(x, "r") <> 1)
+        error(msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 3));
+    end
+
+    if (size(z, "c") <> 1) & (size(z, "r") <> 1)
+        error(msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 4));
+    end
+
+    // User mixes polynomial and vector notation
+    if type_b == "polynomial" & size(a, '*') <> 1
+        error(msprintf(_("%s: Incompatible input arguments #%d and #%d: a polynomial and 1-by-1 matrix or two polynomials expected"), fname, 1, 2));
+    end
+
+    // User mixes polynomial and vector notation
+    if type_a == "polynomial" & size(b, '*') <> 1
+        error(msprintf(_("%s: Incompatible input arguments #%d and #%d: a polynomial and 1-by-1 matrix or two polynomials expected"), fname, 1, 2));
+    end
+
+    if type_b == "polynomial" | type_a == "polynomial"
+        c = b/a;
+        b = numer(c);
+        a = denom(c);
+        deg_b = degree(b);
+        deg_a = degree(a);
+        deg = max(deg_b, deg_a);
+        b = coeff(b, deg:-1:0);
+        a = coeff(a, deg:-1:0);
+    end
+
+    ////remove high order coefficients equal to zero
+    //i = 0; while b($ - i) == 0, i = i + 1; end;
+    //b = b(1:$ - i);
+
+    ////remove high order coefficients equal to zero
+    //i = 1; while a(i) == 0, i = i + 1; end
+    //a = a(i:$);
+
+    if a(1) == 0
+        error(msprintf(_("%s: Wrong input for input argument #%d: First element must not be %s"), fname, 2, "0"));
     end
 
     //force vector orientation
-    b   = matrix(b,-1,1);
-    a   = matrix(a,-1,1);
+    b   = matrix(b, -1, 1);
+    a   = matrix(a, -1, 1);
     mnx = size(x);
-    x   = matrix(x,1,-1);
+    x   = matrix(x, 1, -1);
 
     //normalize
-    b = b/a(1);
-    a = a/a(1);
+    b = b / a(1);
+    a = a / a(1);
 
-    n=max(size(b,"*"),size(a,"*"))-1;
+    n = max(size(b, "*"), size(a, "*"))-1;
     if n > 0 then
-        if argn(2)<4 then
-            z=zeros(n,1);
+        if argn(2) < 4 then
+            z = zeros(n, 1);
         else
-            z=matrix(z,n,1);
+            z = matrix(z, n, 1);
         end
 
         //pad the numerator and denominator if necessary
-        a($+1:(n+1)) = 0;
-        b($+1:(n+1)) = 0;
-
-        //the algorithm below can also be used but is slower if x is long
-        //may be good to write it in C
-        //  for i = 1:size(x,'*')
-        //    y(i) = z(1) + b(1)*x(i);
-        //    z(1:(n-1)) = z(2:n) - a(2:n)*y(i) + b(2:n)*x(i);
-        //    z(n) = b($)*x(i) - a($) * y(i);
-        //  end
+        a($ + 1:(n + 1)) = 0;
+        b($ + 1:(n + 1)) = 0;
 
         //form state space representation
-        A     = [-a(2:$),[eye(n-1,n-1);zeros(1,n-1)] ];
-        B     = b(2:$)-a(2:$)*b(1);//C=eye(1,n);D=b(1);
+        A     = [-a(2:$), [eye(n - 1, n - 1); zeros(1, n - 1)] ];
+        B     = b(2:$) - a(2:$) * b(1); //C = eye(1, n); D = b(1);
+
+        [z, X] = ltitr(A, B, x, z);
+        y     = X(1, :) + b(1) * x;
 
-        [z,X] = ltitr(A,B,x,z);
-        y     = X(1,:)+b(1)*x;
-        //y=C*X+D*x
     else
-        y     = b(1)*x;
+        y     = b(1) * x;
         z     = [];
     end
     //make y orientation similar to the x one
-    y=matrix(y,mnx);
+    y = matrix(y, mnx);
 
 endfunction
 
diff --git a/scilab/modules/signal_processing/tests/nonreg_tests/bug_13346.dia.ref b/scilab/modules/signal_processing/tests/nonreg_tests/bug_13346.dia.ref
new file mode 100644 (file)
index 0000000..86da94a
--- /dev/null
@@ -0,0 +1,20 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//<-- CLI SHELL MODE -->
+// <-- Non-regression test for bug 13346 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=13346
+//
+// <-- Short Description -->
+// Filter did not work on a simple delay
+X = [1, zeros(1,9)];
+delayed_X = zeros(1,10); delayed_X(3) = 1;
+A = 1;
+B = [0 0 1];
+res = filter(B, A, X);
+assert_checkalmostequal(res, delayed_X);
diff --git a/scilab/modules/signal_processing/tests/nonreg_tests/bug_13346.tst b/scilab/modules/signal_processing/tests/nonreg_tests/bug_13346.tst
new file mode 100644 (file)
index 0000000..1039b3c
--- /dev/null
@@ -0,0 +1,24 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+//<-- CLI SHELL MODE -->
+// <-- Non-regression test for bug 13346 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=13346
+//
+// <-- Short Description -->
+// Filter did not work on a simple delay
+
+X = [1, zeros(1,9)];
+delayed_X = zeros(1,10); delayed_X(3) = 1;
+
+A = 1;
+B = [0 0 1];
+
+res = filter(B, A, X);
+assert_checkalmostequal(res, delayed_X);
index 37f0c57..fb7f053 100644 (file)
@@ -12,4 +12,5 @@
 // <-- Short Description -->
 //   When filter is used with polynomials as arguments num and den, the degree 0 monomial is ignored.
 Num=1;Den=1+%z;u=[1,2,3,4,5];
-if or(filter(Num,Den,u)<>filter(Num,[1 1],u)) then bugmes();quit;end
+if or(filter(Num,Den,u)<>filter([0 1],[1 1],u)) then bugmes();quit;end
+if or(filter(%z,Den,u)<>filter(1,[1 1],u)) then bugmes();quit;end
index 3ab8813..e26c8bb 100644 (file)
@@ -1,6 +1,6 @@
 // =============================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2009 - INRIA - Serge Steer 
+// Copyright (C) 2009 - INRIA - Serge Steer
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
@@ -13,5 +13,6 @@
 // <-- Short Description -->
 //   When filter is used with polynomials as arguments num and den, the degree 0 monomial is ignored.
 Num=1;Den=1+%z;u=[1,2,3,4,5];
-if or(filter(Num,Den,u)<>filter(Num,[1 1],u)) then pause,end
+if or(filter(Num,Den,u)<>filter([0 1],[1 1],u)) then pause,end
+if or(filter(%z,Den,u)<>filter(1,[1 1],u)) then pause,end
 
diff --git a/scilab/modules/signal_processing/tests/unit_tests/filter.dia.ref b/scilab/modules/signal_processing/tests/unit_tests/filter.dia.ref
new file mode 100644 (file)
index 0000000..8b9968e
--- /dev/null
@@ -0,0 +1,129 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- unit tests for function filter  -->
+//
+// <-- CLI SHELL MODE -->
+//==============================================================================
+// Error handling tests
+//==============================================================================
+fname = "filter";
+func_call = "filter(B, A, x)";
+// Type checks
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 1);
+B = "test";
+A = [0 1];
+x = [1, zeros(1,99)];
+assert_checkerror(func_call, err_msg);
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 2);
+B = [0 0 1];
+A = "test";
+assert_checkerror(func_call, err_msg);
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 3);
+B = [0 0 1];
+A = [1 0 1];
+x = "test";
+assert_checkerror(func_call, err_msg);
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 4);
+x = [1, zeros(1,99)];
+z = "test";
+func_call = "filter(B, A, x, z)";
+assert_checkerror(func_call, err_msg);
+// Values are real
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 1);
+z = 0;
+B = %i;
+assert_checkerror(func_call, err_msg);
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 2);
+A = 2 * %i;
+B = [0 0 1];
+assert_checkerror(func_call, err_msg);
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 3);
+A = [1 0 1];
+x = [%i 1 3 4];
+assert_checkerror(func_call, err_msg);
+x = [1 zeros(1, 99)];
+z = %i;
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 4);
+assert_checkerror(func_call, err_msg);
+// Check vector values
+A = [A; A];
+z = 0;
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 1);
+assert_checkerror(func_call, err_msg);
+A = A(1, :);
+B = [B; B];
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 2);
+assert_checkerror(func_call, err_msg);
+B = B(1, :);
+x = [x; x];
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 3);
+assert_checkerror(func_call, err_msg);
+x = x(1, :);
+z = [1 2; 3 4];
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 4);
+assert_checkerror(func_call, err_msg);
+// User mixes polynomial and vector notation
+z = 0;
+B = %s^3 + %s + 1;
+A = [1 0];
+err_msg = msprintf(_("%s: Incompatible input arguments #%d and #%d: a polynomial and 1-by-1 matrix or two polynomials expected"), fname, 1, 2);
+assert_checkerror(func_call, err_msg);
+A = B;
+B = [1 1];
+err_msg = msprintf(_("%s: Incompatible input arguments #%d and #%d: a polynomial and 1-by-1 matrix or two polynomials expected"), fname, 1, 2);
+assert_checkerror(func_call, err_msg);
+// Denominator must have first coefficient not equal to 0
+A = [0 0 1];
+err_msg = msprintf(_("%s: Wrong input for input argument #%d: First element must not be %s"), fname, 2, "0");
+assert_checkerror(func_call, err_msg);
+B = %s^3 + %s + 1;
+A = %s;
+err_msg = msprintf(_("%s: Wrong input for input argument #%d: First element must not be %s"), fname, 2, "0");
+assert_checkerror(func_call, err_msg);
+//==============================================================================
+// Nominal behaviour
+//==============================================================================
+// Integrator y(n) = y(n - 1) + x(n)
+// Filter is 1/(1 - 1 * z**-1)
+B = 1;
+A = [1 -1];
+x = [1 1 1 1 1];
+y = [1 2 3 4 5];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+// Same behaviour with a polynomial
+B = %s;
+A = %s - 1;
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+// Integrator with delay y(n) = y(n-1) + x(n-1)
+// Filter is z**-1 / (1 + z**-1)
+B = 1;
+y = [0 1 2 3 4];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+B = [0 1];
+A = [1 -1];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+// Derivator y(n) = x(n) - x(n-1)
+// Filter is 1 - z**-1
+B = [1 -1];
+A = 1;
+x = [1 3 5 3 1];
+y = [1 2 2 -2 -2];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+// Complex filter y(n) = 2 * y(n-1) - 3 * y(n-2) + x(n-2) - 2 * x(n-1) + x(n)
+// Filter is (1 - 2z**-1 + z**-2) / (1 - 2z**-1 + 3z**-2)
+B = [1 -2 1];
+A = [1 -2 3];
+x = [1 2 -1 1 -1];
+y = [1 2 -3 -7 -9];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
diff --git a/scilab/modules/signal_processing/tests/unit_tests/filter.tst b/scilab/modules/signal_processing/tests/unit_tests/filter.tst
new file mode 100644 (file)
index 0000000..9b8d291
--- /dev/null
@@ -0,0 +1,155 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- unit tests for function filter  -->
+//
+// <-- CLI SHELL MODE -->
+
+//==============================================================================
+// Error handling tests
+//==============================================================================
+
+fname = "filter";
+func_call = "filter(B, A, x)";
+
+// Type checks
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 1);
+B = "test";
+A = [0 1];
+x = [1, zeros(1,99)];
+assert_checkerror(func_call, err_msg);
+
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 2);
+B = [0 0 1];
+A = "test";
+assert_checkerror(func_call, err_msg);
+
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 3);
+B = [0 0 1];
+A = [1 0 1];
+x = "test";
+assert_checkerror(func_call, err_msg);
+
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 4);
+x = [1, zeros(1,99)];
+z = "test";
+func_call = "filter(B, A, x, z)";
+assert_checkerror(func_call, err_msg);
+
+// Values are real
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 1);
+z = 0;
+B = %i;
+assert_checkerror(func_call, err_msg);
+
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix or polynomial expected.\n"), fname, 2);
+A = 2 * %i;
+B = [0 0 1];
+assert_checkerror(func_call, err_msg);
+
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 3);
+A = [1 0 1];
+x = [%i 1 3 4];
+assert_checkerror(func_call, err_msg);
+
+x = [1 zeros(1, 99)];
+z = %i;
+err_msg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 4);
+assert_checkerror(func_call, err_msg);
+
+// Check vector values
+A = [A; A];
+z = 0;
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 1);
+assert_checkerror(func_call, err_msg);
+
+A = A(1, :);
+B = [B; B];
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 2);
+assert_checkerror(func_call, err_msg);
+
+B = B(1, :);
+x = [x; x];
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 3);
+assert_checkerror(func_call, err_msg);
+
+x = x(1, :);
+z = [1 2; 3 4];
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 4);
+assert_checkerror(func_call, err_msg);
+
+// User mixes polynomial and vector notation
+z = 0;
+B = %s^3 + %s + 1;
+A = [1 0];
+err_msg = msprintf(_("%s: Incompatible input arguments #%d and #%d: a polynomial and 1-by-1 matrix or two polynomials expected"), fname, 1, 2);
+assert_checkerror(func_call, err_msg);
+
+A = B;
+B = [1 1];
+err_msg = msprintf(_("%s: Incompatible input arguments #%d and #%d: a polynomial and 1-by-1 matrix or two polynomials expected"), fname, 1, 2);
+assert_checkerror(func_call, err_msg);
+
+// Denominator must have first coefficient not equal to 0
+A = [0 0 1];
+err_msg = msprintf(_("%s: Wrong input for input argument #%d: First element must not be %s"), fname, 2, "0");
+assert_checkerror(func_call, err_msg);
+
+B = %s^3 + %s + 1;
+A = %s;
+err_msg = msprintf(_("%s: Wrong input for input argument #%d: First element must not be %s"), fname, 2, "0");
+assert_checkerror(func_call, err_msg);
+
+//==============================================================================
+// Nominal behaviour
+//==============================================================================
+
+// Integrator y(n) = y(n - 1) + x(n)
+// Filter is 1/(1 - 1 * z**-1)
+B = 1;
+A = [1 -1];
+x = [1 1 1 1 1];
+
+y = [1 2 3 4 5];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+
+// Same behaviour with a polynomial
+B = %s;
+A = %s - 1;
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+
+// Integrator with delay y(n) = y(n-1) + x(n-1)
+// Filter is z**-1 / (1 + z**-1)
+B = 1;
+y = [0 1 2 3 4];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+
+B = [0 1];
+A = [1 -1];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+
+// Derivator y(n) = x(n) - x(n-1)
+// Filter is 1 - z**-1
+B = [1 -1];
+A = 1;
+x = [1 3 5 3 1];
+y = [1 2 2 -2 -2];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);
+
+// Complex filter y(n) = 2 * y(n-1) - 3 * y(n-2) + x(n-2) - 2 * x(n-1) + x(n)
+// Filter is (1 - 2z**-1 + z**-2) / (1 - 2z**-1 + 3z**-2)
+B = [1 -2 1];
+A = [1 -2 3];
+x = [1 2 -1 1 -1];
+y = [1 2 -3 -7 -9];
+res = filter(B, A, x);
+assert_checkalmostequal(res, y);