*Bug #8099 fixed - the cumprod function did not simplify the result when it is complex. 23/8823/5
Adeline CARNIS [Mon, 27 Aug 2012 12:32:35 +0000 (14:32 +0200)]
Change-Id: If8229caf043996356d984e6983ccbd4b20f3986a

scilab/CHANGES_5.5.X
scilab/modules/elementary_functions/tests/nonreg_tests/bug_8099.dia.ref [new file with mode: 0644]
scilab/modules/elementary_functions/tests/nonreg_tests/bug_8099.tst [new file with mode: 0644]
scilab/modules/overloading/macros/%p_simp.sci
scilab/modules/polynomials/sci_gateway/fortran/sci_f_psimp.f
scilab/modules/polynomials/tests/unit_tests/simp.dia.ref [new file with mode: 0644]
scilab/modules/polynomials/tests/unit_tests/simp.tst [new file with mode: 0644]

index 9c880a3..d0fc865 100644 (file)
@@ -311,6 +311,8 @@ Bug Fixes
 
 * Bug #8098 fixed - cumsum could not be applied to rational matrices.
 
+* Bug #8099 fixed - cumsum did not always simplify the result.
+
 * Bug #8162 fixed - Area of stability of plzr was wrong for continuous systems (+unit test added).
 
 * Bug #8211 fixed - 'parameters' module demonstration finalized.
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8099.dia.ref b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8099.dia.ref
new file mode 100644 (file)
index 0000000..59731e6
--- /dev/null
@@ -0,0 +1,20 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 8099 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=8099
+//
+// <-- Short Description -->
+// the cumprod function did not simplify the result when it is complex.
+c = cumprod([1/%z %z/(%i+2*%z)]);
+res = [1/%z, 1/(%i+2*%z)];
+assert_checkequal(c(2), res(2));
+assert_checkequal(c(3), res(3));
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8099.tst b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8099.tst
new file mode 100644 (file)
index 0000000..76652c7
--- /dev/null
@@ -0,0 +1,21 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 8099 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=8099
+//
+// <-- Short Description -->
+// the cumprod function did not simplify the result when it is complex.
+
+c = cumprod([1/%z %z/(%i+2*%z)]);
+res = [1/%z, 1/(%i+2*%z)];
+assert_checkequal(c(2), res(2));
+assert_checkequal(c(3), res(3));
index b8d1ace..f86867e 100644 (file)
@@ -1,12 +1,55 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) INRIA
-//
+// Copyright (C) - 2012
+// 
 // 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
 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
 
-function [num,den]=%p_simp(num,den)
+function [n,d]=%p_simp(num,den)
     // implement complex case
+    // Check the variable name
+    var_name_num = varn(num);
+    var_name_den = varn(den);
+
+    if var_name_num <> var_name_den then
+        error(msprintf(gettext("%s: Wrong value for input argument #%d and #%d: Variable name of numerator and denominator must be the same.\n"), "simp", 1, 2));
+    end
+
+    [m1, m2] = size(num);
+    n = zeros(m1, m2);
+    d = n;
+
+    for k = 1:m1
+        for l = 1:m2
+            tmp_n = num(k, l)
+            tmp_d = den(k, l)
+            if imag(tmp_n) == 0 & imag(tmp_d) == 0 then
+                [tmp_n, tmp_d] = simp(real(tmp_n), real(tmp_d))
+            else
+                rn = roots(tmp_n);
+                rd = roots(tmp_d);
+                if length(rd) > length(rn) then
+                    r = rn;
+                else
+                    r = rd
+                end
+                for i = 1:length(r)
+                    if abs(horner(tmp_n, r(i))) < sqrt(%eps) then
+                        pol = poly(r(i), var_name_num, "roots");
+                        tmp_n = pdiv(tmp_n, pol);
+                        tmp_d = pdiv(tmp_d, pol);
+                        if real(tmp_n) == 0 & real(tmp_d) == 0 then
+                            tmp_n = imag(tmp_n);
+                            tmp_d = imag(tmp_d);
+                        end
+                    end
+                end
+            end
+            n(k,l) = tmp_n
+            d(k,l) = tmp_d
+        end
+    end
 endfunction
index 0bab577..bf009f1 100644 (file)
@@ -143,7 +143,16 @@ c     determine max of the degrees
 c     preserve adress of the beginning of a and b coefficients
 
       lar=la
+      numx0 = stk(la)
+      numx1 = stk(la+1)
+      numx2 = stk(la+2)
+      numx3 = stk(la+3)
+
       lbr=lb
+      denx0 = stk(lb)
+      denx1 = stk(lb+1)
+      denx2 = stk(lb+2)
+      denx3 = stk(lb+3)
 c     allocate memory for intermediate results
       law=lw
       lbw=law+na+1
@@ -168,6 +177,16 @@ c     .  copy overwrite initial polynomials with simplified ones
          call dcopy(nnum,stk(law),1,stk(la1),1)
          call dcopy(nden,stk(lbw),1,stk(lb1),1)
 
+         numx0 = stk(la1)
+         numx1 = stk(la1+1)
+         numx2 = stk(la1+2)
+         numx3 = stk(la1+3)
+
+         denx0 = stk(lb1)
+         denx1 = stk(lb1+1)
+         denx2 = stk(lb1+2)
+         denx3 = stk(lb1+3)
+
          la=la+na+1
          lb=lb+nb+1
          la1=la1+nnum
diff --git a/scilab/modules/polynomials/tests/unit_tests/simp.dia.ref b/scilab/modules/polynomials/tests/unit_tests/simp.dia.ref
new file mode 100644 (file)
index 0000000..e81ac4c
--- /dev/null
@@ -0,0 +1,167 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// =============================== polynomes ===================================
+// =============================== real ========================================
+s = poly(0,'s');
+num = 2 * s^2  + 1;
+den = 3 * s;
+expectedN = 2 * s^2 + 1;
+expectedD = 3 * s;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = 3 * s^3 + 4 * s^2 - s;
+den = 2 *s + 1;
+expectedN = 3 * s^3 + 4 * s^2 - s;
+expectedD = 2 *s + 1;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+den = 2 * s;
+expectedN = 3 * s^2 + 4* s - 1;
+expectedD = 2 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = 5 * %z^2 + 4 * %z;
+den = 2 * %z;
+expectedN = 5 * %z + 4;
+expectedD = 2 * %z^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = [s, 2 * s^2];
+den = [s, s];
+expectedN = [1, 2 * s];
+expectedD = [1 1].*s^0;
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = [s; 2 * s^2];
+den = [s; s];
+expectedN = [1; 2 * s];
+expectedD = [1; 1].* s^0;
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = [2 * s, 4 * s^3; s^2, s];
+den = [s, s^2; s^3, s];
+expectedN = [2, 4 * s; 1, 1];
+expectedD = [1, 1;s 1];
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = (s + 1) * (s + 2);
+den = s + 1;
+expectedN = s + 2;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkalmostequal(roots(res(2)), roots(expectedN), %eps)
+ ans  =
+  T  
+assert_checkequal(res(3), expectedD);
+num = s + 1;
+den = 2 * (s + 1);
+expectedN = 0.5 * s^0;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+// =============================== complex =====================================
+s = poly(0,'s');
+num = 2 * %i * s^2  + 1;
+den = 3 * %z;
+assert_checkfalse(execstr("[n, d] = simp(num, den)", "errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong value for input argument #%d and #%d: Variable name of numerator and denominator must be the same.\n"), "simp", 1, 2);
+assert_checkerror("[n, d] = simp(num, den)", refMsg);
+assert_checkfalse(execstr("num/den", "errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong value for input argument #%d and #%d: Variable name of numerator and denominator must be the same.\n"), "simp", 1, 2);
+assert_checkerror("num/den", refMsg);
+den = 3*s;
+res = num/den;
+expectedN = 2 *%i * s^2 + 1;
+expectedD = 3 * s;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = 3 * s^3 +4 * s^2 - s;
+den = 2 * %i *s + 1;
+expectedN = 3 * s^3 +4 * s^2 - s;
+expectedD = 2 * %i *s + 1;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+den = 2 * %i * s;
+expectedN = 3 * s^2 +4 * s - 1;
+expectedD = 2 * %i * %s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = 5 * %z^2 + 4 * %i * %z;
+den = 2 * %z;
+expectedN = 5 * %z + 4 * %i;
+expectedD = 2 * %z^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = [s, 2 * s^2];
+den = [%i * s, s];
+expectedN = [1, 2 * s];
+expectedD = [%i, 1].*s^0;
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = [s; 2 * s^2];
+den = [%i * s; s];
+expectedN = [1; 2 * s];
+expectedD = [%i; 1]*s^0;
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = [2 * s, 4 * %i * s^3; s^2, s];
+den = [%i * s, s^2; s^3, s];
+expectedN = [2, 4 * %i * s; 1, 1];
+expectedD = [%i, 1; s, 1];
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = (s + 1) * (s + 2 * %i);
+den = s + 1;
+expectedN = s + 2 * %i;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = (%i * s + 2) * (s + 1);
+den = (%i * s + 2);
+expectedN = s + 1;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = (%i * s + 2) * (s + 2);
+den = s + 2;
+expectedN = %i * s + 2;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = %i * s + 1;
+den = 2 * (%i * s + 1);
+expectedN = 1 * s^0;
+expectedD = 2 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+num = %i * s + 4;
+den = %i * (%i * s + 4);
+expectedN = %i*%s^0;
+expectedD = -1;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkalmostequal(coeff(res(3)), expectedD, %eps);
diff --git a/scilab/modules/polynomials/tests/unit_tests/simp.tst b/scilab/modules/polynomials/tests/unit_tests/simp.tst
new file mode 100644 (file)
index 0000000..f310044
--- /dev/null
@@ -0,0 +1,189 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+
+// =============================== polynomes ===================================
+// =============================== real ========================================
+s = poly(0,'s');
+num = 2 * s^2  + 1;
+den = 3 * s;
+expectedN = 2 * s^2 + 1;
+expectedD = 3 * s;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = 3 * s^3 + 4 * s^2 - s;
+den = 2 *s + 1;
+expectedN = 3 * s^3 + 4 * s^2 - s;
+expectedD = 2 *s + 1;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+den = 2 * s;
+expectedN = 3 * s^2 + 4* s - 1;
+expectedD = 2 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = 5 * %z^2 + 4 * %z;
+den = 2 * %z;
+expectedN = 5 * %z + 4;
+expectedD = 2 * %z^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = [s, 2 * s^2];
+den = [s, s];
+expectedN = [1, 2 * s];
+expectedD = [1 1].*s^0;
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = [s; 2 * s^2];
+den = [s; s];
+expectedN = [1; 2 * s];
+expectedD = [1; 1].* s^0;
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = [2 * s, 4 * s^3; s^2, s];
+den = [s, s^2; s^3, s];
+expectedN = [2, 4 * s; 1, 1];
+expectedD = [1, 1;s 1];
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = (s + 1) * (s + 2);
+den = s + 1;
+expectedN = s + 2;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkalmostequal(roots(res(2)), roots(expectedN), %eps)
+assert_checkequal(res(3), expectedD);
+
+num = s + 1;
+den = 2 * (s + 1);
+expectedN = 0.5 * s^0;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+// =============================== complex =====================================
+s = poly(0,'s');
+num = 2 * %i * s^2  + 1;
+den = 3 * %z;
+assert_checkfalse(execstr("[n, d] = simp(num, den)", "errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong value for input argument #%d and #%d: Variable name of numerator and denominator must be the same.\n"), "simp", 1, 2);
+assert_checkerror("[n, d] = simp(num, den)", refMsg);
+
+assert_checkfalse(execstr("num/den", "errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong value for input argument #%d and #%d: Variable name of numerator and denominator must be the same.\n"), "simp", 1, 2);
+assert_checkerror("num/den", refMsg);
+
+den = 3*s;
+res = num/den;
+expectedN = 2 *%i * s^2 + 1;
+expectedD = 3 * s;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = 3 * s^3 +4 * s^2 - s;
+den = 2 * %i *s + 1;
+expectedN = 3 * s^3 +4 * s^2 - s;
+expectedD = 2 * %i *s + 1;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+den = 2 * %i * s;
+expectedN = 3 * s^2 +4 * s - 1;
+expectedD = 2 * %i * %s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = 5 * %z^2 + 4 * %i * %z;
+den = 2 * %z;
+expectedN = 5 * %z + 4 * %i;
+expectedD = 2 * %z^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = [s, 2 * s^2];
+den = [%i * s, s];
+expectedN = [1, 2 * s];
+expectedD = [%i, 1].*s^0;
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = [s; 2 * s^2];
+den = [%i * s; s];
+expectedN = [1; 2 * s];
+expectedD = [%i; 1]*s^0;
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = [2 * s, 4 * %i * s^3; s^2, s];
+den = [%i * s, s^2; s^3, s];
+expectedN = [2, 4 * %i * s; 1, 1];
+expectedD = [%i, 1; s, 1];
+res = num./den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = (s + 1) * (s + 2 * %i);
+den = s + 1;
+expectedN = s + 2 * %i;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+
+num = (%i * s + 2) * (s + 1);
+den = (%i * s + 2);
+expectedN = s + 1;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = (%i * s + 2) * (s + 2);
+den = s + 2;
+expectedN = %i * s + 2;
+expectedD = 1 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = %i * s + 1;
+den = 2 * (%i * s + 1);
+expectedN = 1 * s^0;
+expectedD = 2 * s^0;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkequal(res(3), expectedD);
+
+num = %i * s + 4;
+den = %i * (%i * s + 4);
+expectedN = %i*%s^0;
+expectedD = -1;
+res = num/den;
+assert_checkequal(res(2), expectedN);
+assert_checkalmostequal(coeff(res(3)), expectedD, %eps);