* Bug #12679 fixed - Polynomials: argument check for gcd and lcm 07/11707/2
Paul BIGNIER [Thu, 13 Jun 2013 08:05:02 +0000 (10:05 +0200)]
Change-Id: I400feeb0683ef4c422496e071f1bb614a59a4239

scilab/CHANGES_5.5.X
scilab/modules/elementary_functions/help/en_US/discrete/gcd.xml
scilab/modules/elementary_functions/help/en_US/discrete/lcm.xml
scilab/modules/elementary_functions/help/fr_FR/discrete/gcd.xml
scilab/modules/elementary_functions/help/fr_FR/discrete/lcm.xml
scilab/modules/polynomials/macros/gcd.sci
scilab/modules/polynomials/macros/lcm.sci
scilab/modules/polynomials/tests/nonreg_tests/bug_12679.dia.ref [new file with mode: 0644]
scilab/modules/polynomials/tests/nonreg_tests/bug_12679.tst [new file with mode: 0644]

index 55ad19e..a7ba394 100644 (file)
@@ -381,4 +381,8 @@ Bug fixes
 
 * Bug #12678 fixed - nthroot() now accepts vector/matrix as second argument.
 
-* Bug #12686 fixed - Fixed error returned by 'diff()'.
+* Bug #12679 fixed - Argument type check added in gcd and lcm.
+
+* Bug #12686 fixed - Error returned by diff() fixed.
+
+
index cedba03..f2ef0be 100644 (file)
@@ -17,7 +17,7 @@
     </refnamediv>
     <refsynopsisdiv>
         <title>Calling Sequence</title>
-        <synopsis>[pgcd, U]=gcd(p)</synopsis>
+        <synopsis>[pgcd, U] = gcd(p)</synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Arguments</title>
@@ -26,7 +26,7 @@
                 <term>p</term>
                 <listitem>
                     <para>
-                        a polynomial row vector <literal>p=[p1, ..., pn]</literal> or
+                        a polynomial row vector <literal>p = [p1, ..., pn]</literal> (type equal to 2) or
                         an integer row vector (type equal to 8).
                     </para>
                 </listitem>
     <refsection>
         <title>Description</title>
         <para>
-            <code>[pgcd, U]=gcd(p)</code> computes the gcd of components of <varname>p</varname> (<varname>pgcd</varname>) and an
+            <code>[pgcd, U] = gcd(p)</code> computes the gcd of components of <varname>p</varname> (<varname>pgcd</varname>) and a
             unimodular matrix (with polynomial inverse) <varname>U</varname>, with minimal degree such that
         </para>
         <para>
-            <literal>p*U=[0 ... 0 pgcd]</literal>.
+            <literal>p*U = [0 ... 0 pgcd]</literal>.
         </para>
         <para>
-            In mathematics, an <emphasis role='italic'>unimodular</emphasis> matrix
+            In mathematics, a <emphasis role='italic'>unimodular</emphasis> matrix
             <literal>U</literal> is a square integer matrix having
             determinant <literal>+1</literal> or <literal>-1</literal>.
         </para>
@@ -62,8 +62,6 @@ V=int32([2^2*3^5, 2^3*3^2,2^2*3^4*5]);
 [thegcd,U]=gcd(V)
 V*U
 
-gcd([15 20])
-
 gcd(uint8([15 20]))
 
 gcd([iconvert(15,4) iconvert(20,4)])
index 610c4f5..17e1064 100644 (file)
@@ -26,7 +26,7 @@
                 <term>p</term>
                 <listitem>
                     <para>
-                        a polynomial row vector <literal>p = [p1, ..., pn]</literal> or
+                        a polynomial row vector <literal>p = [p1, ..., pn]</literal> (type equal to 2) or
                         an integer row vector (type equal to 8).
                     </para>
                 </listitem>
@@ -34,7 +34,7 @@
             <varlistentry>
                 <term>fact</term>
                 <listitem>
-                    <para>a polynomial vector or an integer vector (type equal to 8).</para>
+                    <para>a polynomial vector or an integer vector.</para>
                 </listitem>
             </varlistentry>
             <varlistentry>
     <refsection>
         <title>Description</title>
         <para>
-            <code>pp=lcm(p)</code> computes the lcm <varname>pp</varname> of polynomial vector <varname>p</varname>.
+            <code>pp = lcm(p)</code> computes the lcm <varname>pp</varname> of polynomial vector <varname>p</varname>.
         </para>
         <para>
-            <code>[pp, fact]=lcm(p)</code> computes in addition the vector <varname>fact</varname> such that:
+            <code>[pp, fact] = lcm(p)</code> computes in addition the vector <varname>fact</varname> such that:
         </para>
         <para>
-            <code>p.*fact=pp*ones(p)</code>.
+            <code>p.*fact = pp*ones(p)</code>.
         </para>
     </refsection>
     <refsection>
index f8c0ec4..64ca27a 100644 (file)
@@ -6,7 +6,7 @@
     </refnamediv>
     <refsynopsisdiv>
         <title>Séquence d'appel</title>
-        <synopsis>[pgcd,U]=gcd(p)</synopsis>
+        <synopsis>[pgcd, U] = gcd(p)</synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Paramètres</title>
@@ -15,7 +15,7 @@
                 <term>p  </term>
                 <listitem>
                     <para>
-                        vecteur ligne de polynômes <literal>p=[p1,..,pn] ou d'entiers (type égal à 8)</literal>
+                        vecteur ligne de polynômes <literal>p = [p1,..,pn] (type égal à 2) ou d'entiers (type égal à 8)</literal>
                     </para>
                 </listitem>
             </varlistentry>
@@ -27,7 +27,7 @@
             Calcule le PGCD des termes de <literal>p</literal> et une matrice unimodulaire (avec le polynôme inverse) <literal>U</literal>, de degré minimal tels que
         </para>
         <para>
-            <literal>p*U=[0 ... 0 pgcd]</literal>
+            <literal>p*U = [0 ... 0 pgcd]</literal>
         </para>
     </refsection>
     <refsection>
@@ -44,8 +44,6 @@ V=int32([2^2*3^5, 2^3*3^2,2^2*3^4*5]);
 [thegcd,U]=gcd(V)
 V*U
 
-gcd([15 20])
-
 gcd(uint8([15 20]))
 
 gcd([iconvert(15,4) iconvert(20,4)])
index 69cb57a..dd7b99e 100644 (file)
@@ -8,7 +8,7 @@
     </refnamediv>
     <refsynopsisdiv>
         <title>Séquence d'appel</title>
-        <synopsis>[pp,fact]=lcm(p)</synopsis>
+        <synopsis>[pp, fact] = lcm(p)</synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Paramètres</title>
@@ -16,7 +16,7 @@
             <varlistentry>
                 <term>p  </term>
                 <listitem>
-                    <para>vecteur de polynômes ou d'entiers (type égal à 8)
+                    <para>vecteur de polynômes (type égal à 2) ou d'entiers (type égal à 8)
                     </para>
                 </listitem>
             </varlistentry>
     <refsection>
         <title>Description</title>
         <para>
-            <literal>pp=lcm(p)</literal> calcule le PPCM <literal>pp</literal>  du vecteur
+            <literal>pp = lcm(p)</literal> calcule le PPCM <literal>pp</literal>  du vecteur
             <literal>p</literal> au sens des polynômes ou des entiers.
         </para>
         <para>
-            <literal>[pp,fact]=lcm(p)</literal> calcule de plus le vecteur <literal>fact</literal> tel que :
+            <literal>[pp, fact] = lcm(p)</literal> calcule de plus le vecteur <literal>fact</literal> tel que :
         </para>
         <para>
-            <literal>p.*fact=pp*ones(p)</literal>
+            <literal>p.*fact = pp*ones(p)</literal>
         </para>
     </refsection>
     <refsection>
index c217d60..c7d4750 100644 (file)
@@ -8,37 +8,45 @@
 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 
 
-function [x,uu]=gcd(p)
+function [x, uu] = gcd(p)
     //Given a polynomial vector p, [pgcd,u]=gcd(p) computes the gcd
     //of components and a unimodular matrix (with polynomial inverse) u,
     //with minimal degree such that [p1 p2]*u=[0 ... 0 pgcd]
     //!
+
+    if (type(p)<>2 & type(p)<>8) then
+        error(msprintf(_("%s: Wrong type for argument #%d: Integer array or Polynomial expected.\n"), "gcd", 1));
+    end
+
     [lhs,rhs]=argn(0)
     if type(p)==8 then
-        if lhs==2 then [x,uu]=%i_gcd(p),else x=%i_gcd(p),end
-        return,
+        if lhs==2 then [x,uu]=%i_gcd(p), else x=%i_gcd(p), end
+        return
+    elseif ~isreal(p) then
+        error(msprintf(_("%s: Wrong type for argument #%d: Real Polynomial expected.\n"), "gcd", 1));
     end
 
-    [m,n]=size(p)
-    mn=m*n
-    p=matrix(p,1,mn)
-    x=p(1);
-    uu=1
-    for l=2:mn,
-        [x,u]=bezout(x,p(l)),
+    [m, n] = size(p)
+    mn = m*n
+    p = matrix(p, 1, mn)
+    x = p(1);
+    uu = 1
+    for l = 2:mn,
+        [x, u] = bezout(x, p(l)),
         if lhs==2 then
-            uu=[uu(:,1:l-2) uu(:,l-1)*u(1,[2 1])];uu(l,l-1:l)=u(2,[2 1]);
+            uu = [uu(:, 1:l-2) uu(:, l-1)*u(1, [2 1])]; uu(l, l-1:l) = u(2, [2 1]);
         end
     end,
-    if lhs==1 then return,end
-    for l=mn:-1:2
-        pivot=uu(l,l-1);
-        for k=l:mn
-            [r,q]=pdiv(uu(l,k),pivot)
+    if lhs==1 then return end
+    for l = mn:-1:2
+        pivot = uu(l, l-1);
+        for k = l:mn
+            [r, q] = pdiv(uu(l, k), pivot)
             if coeff(q)<>0 then
-                uu(1:l-1,k)=uu(1:l-1,k)-q*uu(1:l-1,l-1)
-                uu(l,k)=r;
+                uu(1:l-1, k) = uu(1:l-1, k)-q*uu(1:l-1, l-1)
+                uu(l, k) = r;
             end
         end
     end
+
 endfunction
index a764e82..74ebe34 100644 (file)
@@ -8,24 +8,32 @@
 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 
 
-function [p,fact]=lcm(p)
+function [p, fact] = lcm(p)
     //p=lcm(p) computes the lcm of polynomial vector p
     //[pp,fact]=lcm(p) computes besides the vector fact of factors
     //such that  p.*fact=pp*ones(p)
     //!
+
+    if (type(p)<>2 & type(p)<>8) then
+        error(msprintf(_("%s: Wrong type for argument #%d: Integer array or Polynomial expected.\n"), "lcm", 1));
+    end
+
     if type(p)==8 then
-        if argn(1)==2 then [p,fact]=%i_lcm(p),else p=%i_lcm(p),end
-        return,
+        if argn(1)==2 then [p, fact] = %i_lcm(p), else p = %i_lcm(p), end
+        return
+    elseif ~isreal(p) then
+        error(msprintf(_("%s: Wrong type for argument #%d: Real Polynomial expected.\n"), "lcm", 1));
     end
 
-    [m,n]=size(p),
-    p=matrix(p,m*n,1),
-    p0=p(1);fact=1;
-    for l=2:m*n,
-        [u,v]=simp(p0,p(l)),
-        p0=p0*v,
-        fact=[v*fact,u],
+    [m, n] = size(p),
+    p = matrix(p, m*n, 1),
+    p0 = p(1); fact = 1;
+    for l = 2:m*n,
+        [u, v] = simp(p0, p(l)),
+        p0 = p0*v,
+        fact = [v*fact, u],
     end,
-    fact=matrix(fact,m,n),
-    p=p0;
+    fact = matrix(fact, m, n),
+    p = p0;
+
 endfunction
diff --git a/scilab/modules/polynomials/tests/nonreg_tests/bug_12679.dia.ref b/scilab/modules/polynomials/tests/nonreg_tests/bug_12679.dia.ref
new file mode 100644 (file)
index 0000000..d12bca7
--- /dev/null
@@ -0,0 +1,56 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2010 - DIGITEO - Allan CORNET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- Non-regression test for bug 12679 -->
+//
+// <-- CLI SHELL MODE -->
+// <-- ENGLISH IMPOSED -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=12679
+//
+// <-- Short Description -->
+// Checks on gcd() and lcm() arguments
+// Run with test_run('polynomials', 'bug_12679', ['no_check_error_output'])
+////////////////// gcd
+// Normal behavior, with polynomials
+s = poly(0, 's');
+p = [s, s*(s+1)^2, 2*s^2+s^3];
+[pgcd, u] = gcd(p);
+assert_checkequal(p*u, [0 0 s]);
+// Complex polynomials should yield an error
+s = poly(%i, 's');
+p = [s, s*(s+1)^2,2*s^2+s^3];
+refMsg = msprintf(_("%s: Wrong type for argument #%d: Real Polynomial expected.\n"), "gcd", 1);
+assert_checkerror("[pgcd, u] = gcd(p);", refMsg);
+// Normal behavior, with integers
+V = int32([2^2*3^5, 2^3*3^2, 2^2*3^4*5]);
+[thegcd, U] = gcd(V);
+assert_checkequal(V*U, int32([0 0 36]));
+assert_checkequal(gcd(uint8([15 20])), uint8(5));
+assert_checkequal(gcd([iconvert(15, 4) iconvert(20, 4)]), int32(5));
+assert_checkequal(gcd(iconvert([15 20], 4)), int32(5));
+// Trying to use doubles should yield an error
+refMsg2 = msprintf(_("%s: Wrong type for argument #%d: Integer array or Polynomial expected.\n"), "gcd", 1);
+assert_checkerror("gcd([15 20]);", refMsg2);
+////////////////// lcm
+// Normal behavior, with polynomials
+s = poly(0, 's');
+p = [s, s*(s+1)^2, s^2*(s+2)];
+[pp, fact] = lcm(p);
+assert_checkequal(pp, [2*s^2 + 5*s^3 + 4*s^4 + s^5]);
+// Complex polynomials should yield an error
+s = poly(%i, 's');
+p = [s, s*(s+1)^2, s^2*(s+2)];
+refMsg3 = msprintf(_("%s: Wrong type for argument #%d: Real Polynomial expected.\n"), "lcm", 1);
+assert_checkerror("[pp, fact] = lcm(p);", refMsg3);
+// Normal behavior, with integers
+V = int32([2^2*3^5, 2^3*3^2, 2^2*3^4*5]);
+assert_checkequal(lcm(V), int32(9720));
+// Trying to use doubles should yield an error
+refMsg4 = msprintf(_("%s: Wrong type for argument #%d: Integer array or Polynomial expected.\n"), "lcm", 1);
+assert_checkerror("lcm([15 20]);", refMsg4);
diff --git a/scilab/modules/polynomials/tests/nonreg_tests/bug_12679.tst b/scilab/modules/polynomials/tests/nonreg_tests/bug_12679.tst
new file mode 100644 (file)
index 0000000..2f22a39
--- /dev/null
@@ -0,0 +1,62 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2010 - DIGITEO - Allan CORNET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- Non-regression test for bug 12679 -->
+//
+// <-- CLI SHELL MODE -->
+// <-- ENGLISH IMPOSED -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=12679
+//
+// <-- Short Description -->
+// Checks on gcd() and lcm() arguments
+
+// Run with test_run('polynomials', 'bug_12679', ['no_check_error_output'])
+
+////////////////// gcd
+// Normal behavior, with polynomials
+s = poly(0, 's');
+p = [s, s*(s+1)^2, 2*s^2+s^3];
+[pgcd, u] = gcd(p);
+assert_checkequal(p*u, [0 0 s]);
+// Complex polynomials should yield an error
+s = poly(%i, 's');
+p = [s, s*(s+1)^2,2*s^2+s^3];
+refMsg = msprintf(_("%s: Wrong type for argument #%d: Real Polynomial expected.\n"), "gcd", 1);
+assert_checkerror("[pgcd, u] = gcd(p);", refMsg);
+
+// Normal behavior, with integers
+V = int32([2^2*3^5, 2^3*3^2, 2^2*3^4*5]);
+[thegcd, U] = gcd(V);
+assert_checkequal(V*U, int32([0 0 36]));
+assert_checkequal(gcd(uint8([15 20])), uint8(5));
+assert_checkequal(gcd([iconvert(15, 4) iconvert(20, 4)]), int32(5));
+assert_checkequal(gcd(iconvert([15 20], 4)), int32(5));
+// Trying to use doubles should yield an error
+refMsg2 = msprintf(_("%s: Wrong type for argument #%d: Integer array or Polynomial expected.\n"), "gcd", 1);
+assert_checkerror("gcd([15 20]);", refMsg2);
+
+
+////////////////// lcm
+// Normal behavior, with polynomials
+s = poly(0, 's');
+p = [s, s*(s+1)^2, s^2*(s+2)];
+[pp, fact] = lcm(p);
+assert_checkequal(pp, [2*s^2 + 5*s^3 + 4*s^4 + s^5]);
+// Complex polynomials should yield an error
+s = poly(%i, 's');
+p = [s, s*(s+1)^2, s^2*(s+2)];
+refMsg3 = msprintf(_("%s: Wrong type for argument #%d: Real Polynomial expected.\n"), "lcm", 1);
+assert_checkerror("[pp, fact] = lcm(p);", refMsg3);
+
+// Normal behavior, with integers
+V = int32([2^2*3^5, 2^3*3^2, 2^2*3^4*5]);
+assert_checkequal(lcm(V), int32(9720));
+// Trying to use doubles should yield an error
+refMsg4 = msprintf(_("%s: Wrong type for argument #%d: Integer array or Polynomial expected.\n"), "lcm", 1);
+assert_checkerror("lcm([15 20]);", refMsg4);