speedup filter function 77/19477/4
Antoine ELIAS [Tue, 10 Oct 2017 08:11:44 +0000 (10:11 +0200)]
test_run("signal_processing", ["filter", "bug_13346", "bug_4065", "bug_4249", "lev"])

Change-Id: I494eb7dc2fb48539a90cbfeb983ce7c7cb3557ff

scilab/modules/signal_processing/Makefile.am
scilab/modules/signal_processing/Makefile.in
scilab/modules/signal_processing/includes/signal_gw.hxx
scilab/modules/signal_processing/macros/%_filter.sci [moved from scilab/modules/signal_processing/macros/filter.sci with 71% similarity]
scilab/modules/signal_processing/sci_gateway/cpp/sci_filter.cpp [new file with mode: 0644]
scilab/modules/signal_processing/sci_gateway/cpp/signal_processing_gw.vcxproj
scilab/modules/signal_processing/sci_gateway/cpp/signal_processing_gw.vcxproj.filters
scilab/modules/signal_processing/sci_gateway/signal_processing_gateway.xml
scilab/modules/signal_processing/tests/unit_tests/filter.dia.ref [deleted file]
scilab/modules/signal_processing/tests/unit_tests/filter.tst

index cfa4d3d..1829ec3 100644 (file)
@@ -75,7 +75,8 @@ GATEWAY_CPP_SOURCES = \
     sci_gateway/cpp/sci_corr.cpp \
     sci_gateway/cpp/sci_delip.cpp \
     sci_gateway/cpp/sci_fft.cpp \
-    sci_gateway/cpp/sci_syredi.cpp
+    sci_gateway/cpp/sci_syredi.cpp \
+    sci_gateway/cpp/sci_filter.cpp
 
 GATEWAY_C_SOURCES = \
     sci_gateway/c/sci_remez.c \
index 257a641..c6b4838 100644 (file)
@@ -215,7 +215,8 @@ am__objects_5 =  \
        sci_gateway/cpp/libscisignal_processing_la-sci_corr.lo \
        sci_gateway/cpp/libscisignal_processing_la-sci_delip.lo \
        sci_gateway/cpp/libscisignal_processing_la-sci_fft.lo \
-       sci_gateway/cpp/libscisignal_processing_la-sci_syredi.lo
+       sci_gateway/cpp/libscisignal_processing_la-sci_syredi.lo \
+       sci_gateway/cpp/libscisignal_processing_la-sci_filter.lo
 am_libscisignal_processing_la_OBJECTS = $(am__objects_4) \
        $(am__objects_5)
 libscisignal_processing_la_OBJECTS =  \
@@ -682,7 +683,8 @@ GATEWAY_CPP_SOURCES = \
     sci_gateway/cpp/sci_corr.cpp \
     sci_gateway/cpp/sci_delip.cpp \
     sci_gateway/cpp/sci_fft.cpp \
-    sci_gateway/cpp/sci_syredi.cpp
+    sci_gateway/cpp/sci_syredi.cpp \
+    sci_gateway/cpp/sci_filter.cpp
 
 GATEWAY_C_SOURCES = \
     sci_gateway/c/sci_remez.c \
@@ -1073,6 +1075,9 @@ sci_gateway/cpp/libscisignal_processing_la-sci_fft.lo:  \
 sci_gateway/cpp/libscisignal_processing_la-sci_syredi.lo:  \
        sci_gateway/cpp/$(am__dirstamp) \
        sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
+sci_gateway/cpp/libscisignal_processing_la-sci_filter.lo:  \
+       sci_gateway/cpp/$(am__dirstamp) \
+       sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
 
 libscisignal_processing.la: $(libscisignal_processing_la_OBJECTS) $(libscisignal_processing_la_DEPENDENCIES) $(EXTRA_libscisignal_processing_la_DEPENDENCIES) 
        $(AM_V_CXXLD)$(CXXLINK) -rpath $(pkglibdir) $(libscisignal_processing_la_OBJECTS) $(libscisignal_processing_la_LIBADD) $(LIBS)
@@ -1099,6 +1104,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_corr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_delip.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_fft.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_filter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_rpem.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_syredi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/c/$(DEPDIR)/libscisignal_processing_algo_la-conv2.Plo@am__quote@
@@ -1230,6 +1236,13 @@ sci_gateway/cpp/libscisignal_processing_la-sci_syredi.lo: sci_gateway/cpp/sci_sy
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscisignal_processing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sci_gateway/cpp/libscisignal_processing_la-sci_syredi.lo `test -f 'sci_gateway/cpp/sci_syredi.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_syredi.cpp
 
+sci_gateway/cpp/libscisignal_processing_la-sci_filter.lo: sci_gateway/cpp/sci_filter.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscisignal_processing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sci_gateway/cpp/libscisignal_processing_la-sci_filter.lo -MD -MP -MF sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_filter.Tpo -c -o sci_gateway/cpp/libscisignal_processing_la-sci_filter.lo `test -f 'sci_gateway/cpp/sci_filter.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_filter.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_filter.Tpo sci_gateway/cpp/$(DEPDIR)/libscisignal_processing_la-sci_filter.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='sci_gateway/cpp/sci_filter.cpp' object='sci_gateway/cpp/libscisignal_processing_la-sci_filter.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscisignal_processing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sci_gateway/cpp/libscisignal_processing_la-sci_filter.lo `test -f 'sci_gateway/cpp/sci_filter.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_filter.cpp
+
 .f.o:
        $(AM_V_F77)$(F77COMPILE) -c -o $@ $<
 
index 7aa0dbe..9e68571 100644 (file)
@@ -40,5 +40,6 @@ CPP_GATEWAY_PROTOTYPE_EXPORT(sci_corr, EXTERN_SIGNAL_PROCESSING_GW);
 CPP_GATEWAY_PROTOTYPE_EXPORT(sci_delip, EXTERN_SIGNAL_PROCESSING_GW);
 CPP_GATEWAY_PROTOTYPE_EXPORT(sci_fft, EXTERN_SIGNAL_PROCESSING_GW);
 CPP_GATEWAY_PROTOTYPE_EXPORT(sci_syredi, EXTERN_SIGNAL_PROCESSING_GW);
+CPP_GATEWAY_PROTOTYPE_EXPORT(sci_filter, EXTERN_SIGNAL_PROCESSING_GW);
 
 #endif /* !__SIGNAL_GW_HXX__ */
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-function [y, z] = filter(b, a, x, z)
-    //Implements a direct form II transposed implementation of the standard
-    //difference equation
-
+function [y, z] = %_filter(b, a, x, z)
     fname = "filter"
     [lhs, rhs] = argn(0)
 
@@ -62,11 +59,11 @@ function [y, z] = filter(b, a, x, 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)
+    if (size(b, "c") <> 1) & (size(b, "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)
+    if (size(a, "c") <> 1) & (size(a, "r") <> 1)
         error(msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 2));
     end
 
@@ -99,53 +96,10 @@ function [y, z] = filter(b, a, x, z)
         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 value for input argument #%d: First element must not be %s.\n"), fname, 2, "0"));
-    end
-
-    //force vector orientation
-    b   = matrix(b, -1, 1);
-    a   = matrix(a, -1, 1);
-    mnx = size(x);
-    x   = matrix(x, 1, -1);
-
-    //normalize
-    b = b / a(1);
-    a = a / a(1);
-
-    n = max(size(b, "*"), size(a, "*"))-1;
-    if n > 0 then
-        if argn(2) < 4 then
-            z = zeros(n, 1);
-        else
-            z = matrix(z, n, 1);
-        end
-
-        //pad the numerator and denominator if necessary
-        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);
-
-        [z, X] = ltitr(A, B, x, z);
-        y     = X(1, :) + b(1) * x;
-
+    if rhs == 4 then
+        [y, z] = filter(b, a, x, z);
     else
-        y     = b(1) * x;
-        z     = [];
+        [y, z] = filter(b, a, x);
     end
-    //make y orientation similar to the x one
-    y = matrix(y, mnx);
 
 endfunction
-
diff --git a/scilab/modules/signal_processing/sci_gateway/cpp/sci_filter.cpp b/scilab/modules/signal_processing/sci_gateway/cpp/sci_filter.cpp
new file mode 100644 (file)
index 0000000..d568079
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2017 - ESI - Antoine ELIAS
+ *
+ * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ */
+
+/*
+
+Copyright (C) 1996-2017 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+Octave is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Based on Tony Richardson's filter.m.
+//
+// Originally translated to C++ by KH (Kurt.Hornik@wu-wien.ac.at)
+// with help from Fritz Leisch and Andreas Weingessel on Oct 20, 1994.
+//
+// Rewritten to use templates to handle both real and complex cases by
+// jwe, Wed Nov  1 19:15:29 1995.
+
+#include "signal_gw.hxx"
+#include "double.hxx"
+#include "polynom.hxx"
+#include "function.hxx"
+#include "overload.hxx"
+
+extern "C"
+{
+#include "sci_malloc.h"
+#include "localization.h"
+#include "Scierror.h"
+}
+
+const char fname[] = "filter";
+
+static void clean_filter(types::Double* a, bool alloc_a, types::Double* b, bool alloc_b)
+{
+    if (alloc_a)
+    {
+        a->killMe();
+    }
+
+    if (alloc_b)
+    {
+        b->killMe();
+    }
+}
+
+static types::Double* filter(types::Double* b, types::Double* a, types::Double* x, types::Double* si)
+{
+    bool alloc_a = false;
+    bool alloc_b = false;
+
+    int size_a = a->getSize();
+    int size_b = b->getSize();
+
+    int len = std::max(size_a, size_b);
+
+    int dims[2] = {1, len};
+
+    //uniformize
+    types::Double* new_a = a->resize(dims, 2)->getAs<types::Double>();
+    if (new_a != a)
+    {
+        alloc_a = true;
+    }
+
+    types::Double* new_b = b->resize(dims, 2)->getAs<types::Double>();
+    if (new_b != b)
+    {
+        alloc_b = true;
+    }
+
+    double* pa = new_a->get();
+    double* pb = new_b->get();
+    double* px = x->get();
+
+    double norm = pa[0];
+
+    if (norm == 0)
+    {
+        clean_filter(new_a, alloc_a, new_b, alloc_b);
+        Scierror(999, _("%s: Wrong value for input argument #%d: First element must not be %s.\n"), fname, 2, "0");
+        return nullptr;
+    }
+
+    int size_x = x->getSize();
+
+    int rows_si = si->getRows();
+
+    if (rows_si != len - 1)
+    {
+        clean_filter(new_a, alloc_a, new_b, alloc_b);
+        Scierror(999, "%s: first dimension of SI must be of length max (length (a), length (b)) - 1 (%d) (%d)", fname, rows_si, size_x);
+        return nullptr;
+    }
+
+    if (size_x == 0)
+    {
+        clean_filter(new_a, alloc_a, new_b, alloc_b);
+        return x;
+    }
+
+    if (norm != 1)
+    {
+        if (alloc_a == false)
+        {
+            new_a = new_a->clone();
+        }
+
+        if (alloc_b == false)
+        {
+            new_b = new_b->clone();
+        }
+
+        pa = new_a->get();
+        pb = new_b->get();
+        alloc_a = true;
+        alloc_b = true;
+
+        for (int i = 0; i < len; ++i)
+        {
+            pa[i] /= norm;
+            pb[i] /= norm;
+        }
+    }
+
+    if (size_a <= 1 && rows_si <= 0)
+    {
+        types::Double* ret = x->clone();
+        double* pret = ret->get();
+        int s = ret->getSize();
+        for (int i = 0; i < s; ++i)
+        {
+            pret[i] *= pb[0];
+        }
+
+        clean_filter(new_a, alloc_a, new_b, alloc_b);
+        return ret;
+    }
+
+    types::Double* y = new types::Double(x->getRows(), x->getCols());
+
+    double* py = y->get();
+    double* psi = si->get();
+    if (size_a > 1)
+    {
+        if (rows_si > 0)
+        {
+            for (int i = 0; i < size_x; ++i)
+            {
+                py[i] = psi[0] + pb[0] * px[i];
+                for (int j = 0; j < rows_si - 1; ++j)
+                {
+                    psi[j] = psi[j + 1] - pa[j + 1] * py[i] + pb[j + 1] * px[i];
+                }
+
+                psi[rows_si - 1] = pb[rows_si] * px[i] - pa[rows_si] * py[i];
+            }
+        }
+        else
+        {
+            for (int i = 0; i < size_x; ++i)
+            {
+                py[i] = psi[0] + pb[0] * px[i];
+                psi[0] = pb[rows_si] * px[i] - pa[rows_si] * py[i];
+            }
+
+        }
+    }
+    else
+    {
+        for (int i = 0; i < size_x; ++i)
+        {
+            py[i] = psi[0] + pb[0] * px[i];
+
+            if (rows_si > 1)
+            {
+                for (int j = 0; j < rows_si - 1; j++)
+                {
+                    psi[j] = psi[j + 1] + pb[j + 1] * px[i];
+                }
+
+                psi[rows_si - 1] = pb[rows_si] * px[i];
+            }
+            else
+            {
+                psi[0] = pb[1] * px[i];
+            }
+        }
+    }
+
+
+    clean_filter(new_a, alloc_a, new_b, alloc_b);
+    return y;
+}
+/*--------------------------------------------------------------------------*/
+types::Function::ReturnValue sci_filter(types::typed_list &in, int _iRetCount, types::typed_list &out)
+{
+    int iRhs = (int)in.size();
+
+    bool alloc_si = false;
+    types::Double* b = nullptr;
+    types::Double* a = nullptr;
+    types::Double* x = nullptr;
+    types::Double* si = nullptr;
+
+    if (iRhs < 3 || iRhs > 4)
+    {
+        Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), fname, 3, 4);
+        return types::Function::Error;
+    }
+
+    types::InternalType::ScilabId type_b = in[0]->getId();
+    types::InternalType::ScilabId type_a = in[1]->getId();
+    types::InternalType::ScilabId type_x = in[2]->getId();
+    types::InternalType::ScilabId type_si = types::InternalType::IdDouble;
+
+    if (iRhs > 3)
+    {
+        type_si = in[3]->getId();
+    }
+
+    if (type_b  != types::InternalType::IdDouble && type_b  != types::InternalType::IdScalarDouble ||
+        type_a  != types::InternalType::IdDouble && type_a  != types::InternalType::IdScalarDouble ||
+        type_x  != types::InternalType::IdDouble && type_x  != types::InternalType::IdScalarDouble ||
+        type_si != types::InternalType::IdDouble && type_si != types::InternalType::IdScalarDouble)
+    {
+        return Overload::call(L"%_filter", in, _iRetCount, out);
+    }
+
+    b = in[0]->getAs<types::Double>();
+    a = in[1]->getAs<types::Double>();
+    x = in[2]->getAs<types::Double>();
+
+    if (iRhs > 3)
+    {
+        si = in[3]->getAs<types::Double>();
+    }
+    else
+    {
+        alloc_si = true;
+        int size_a = a->getSize();
+        int size_b = b->getSize();
+        int len = std::max(size_a, size_b) - 1;
+        int leadDim = x->getRows() == 1 ? 1 : 0;
+
+        int si_dims[2] = {x->getRows(), x->getCols()};
+        for (int i = leadDim; i > 0; i--)
+        {
+            si_dims[i] = si_dims[i - 1];
+        }
+
+        si_dims[0] = len;
+
+        si = new types::Double(2, si_dims);
+        si->setZeros();
+    }
+
+    if (b->isVector() == false)
+    {
+        Scierror(999, _("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 1);
+        return types::Function::Error;
+    }
+
+    if (a->isVector() == false)
+    {
+        Scierror(999, _("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 2);
+        return types::Function::Error;
+    }
+
+    if (x->isVector() == false)
+    {
+        Scierror(999, _("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 3);
+        return types::Function::Error;
+    }
+
+    if (iRhs > 3 && si->isVector() == false)
+    {
+        Scierror(999, _("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 4);
+        return types::Function::Error;
+    }
+
+    types::Double* ret = filter(b, a, x, si);
+    if (_iRetCount != 2 && alloc_si)
+    {
+        si->killMe();
+    }
+
+    if (ret == nullptr)
+    {
+        return types::Function::Error;
+    }
+
+    out.push_back(ret);
+    if (_iRetCount == 2)
+    {
+        out.push_back(si);
+    }
+    return types::Function::OK;
+}
\ No newline at end of file
index 379d43e..5f17010 100644 (file)
@@ -208,6 +208,7 @@ lib /DEF:"$(ProjectDir)elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
     <ClCompile Include="..\c\sci_remez.c" />
     <ClCompile Include="sci_delip.cpp" />
     <ClCompile Include="sci_fft.cpp" />
+    <ClCompile Include="sci_filter.cpp" />
     <ClCompile Include="sci_rpem.cpp" />
     <ClCompile Include="sci_corr.cpp" />
     <ClCompile Include="sci_syredi.cpp" />
index 1a7bb85..c3e44ea 100644 (file)
@@ -56,6 +56,9 @@
     <ClCompile Include="..\c\sci_conv2.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="sci_filter.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Library Include="..\..\..\..\bin\libintl.lib" />
index 763d1aa..93b27d7 100644 (file)
@@ -31,4 +31,5 @@
     <gateway name="sci_remez"   function="remez"    type="0" />
     <gateway name="sci_syredi"  function="syredi"   type="1" />
     <gateway name="sci_conv2"   function="conv2"    type="0" />
+    <gateway name="sci_filter"  function="filter"   type="1" />
 </module>
diff --git a/scilab/modules/signal_processing/tests/unit_tests/filter.dia.ref b/scilab/modules/signal_processing/tests/unit_tests/filter.dia.ref
deleted file mode 100644 (file)
index eed2184..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-// =============================================================================
-// 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.\n"), 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.\n"), 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 value for input argument #%d: First element must not be %s.\n"), fname, 2, "0");
-assert_checkerror(func_call, err_msg);
-B = %s^3 + %s + 1;
-A = %s;
-err_msg = msprintf(_("%s: Wrong value for input argument #%d: First element must not be %s.\n"), 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);
index f3a1852..b21bdff 100644 (file)
@@ -8,6 +8,7 @@
 // <-- unit tests for function filter  -->
 //
 // <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
 
 //==============================================================================
 // Error handling tests
@@ -64,12 +65,12 @@ 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);
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 2);
 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);
+err_msg = msprintf(_("%s: Wrong size for input argument #%d: Vector expected.\n"), fname, 1);
 assert_checkerror(func_call, err_msg);
 
 B = B(1, :);