* bug 15017.a: gcd() always returned a int32. + support int64 & uint64 80/19180/4
Samuel GOUGEON [Sun, 12 Mar 2017 23:18:26 +0000 (00:18 +0100)]
  * http://bugzilla.scilab.org/15017
  * The type of output GCD is now the type of input.
  * The input can now be an array instead of a row (was not checked)
  * Support to int64 and uint64 added
  * Code improved & simplified:
     - # of input arguments was not checked.
     - %i_gcd() included and removed (used nowhere else)
  * Help page updated and improved.
    Existing translations: too many changes => not worth keeping them
  * There were no unit tests: added

  The bug 15058 http://bugzilla.scilab.org/15058 will be fixed in master
  after merging this commit and merging 6.0 => master

Change-Id: I54d731a7a061d7f60cbfda8aa8f8279b39eb924a

scilab/CHANGES.md
scilab/modules/elementary_functions/help/en_US/discrete/gcd.xml
scilab/modules/elementary_functions/help/fr_FR/discrete/gcd.xml [deleted file]
scilab/modules/elementary_functions/help/ja_JP/discrete/gcd.xml [deleted file]
scilab/modules/elementary_functions/help/pt_BR/discrete/gcd.xml [deleted file]
scilab/modules/elementary_functions/help/ru_RU/discrete/gcd.xml [deleted file]
scilab/modules/overloading/macros/%i_gcd.sci [deleted file]
scilab/modules/polynomials/macros/gcd.sci
scilab/modules/polynomials/tests/unit_tests/gcd.tst [new file with mode: 0644]

index 998fdc8..b505367 100644 (file)
@@ -211,6 +211,7 @@ bounds selected out of the axes areas is now restored, after the Scilab 5.4 regr
 * A new console `File => Go to Favorite directory` menu allows to go to a favorite directory selected
   in a dynamical list set from Scinotes favorite and most recent directories.
 * `size` can now be overloadable for tlist lists, as it already could for mlist lists.
+* `gcd` now accepts `int64` and `uint64` integers. The input can now be any array instead of a row.
 
 
 Help pages:
@@ -221,7 +222,7 @@ Help pages:
   `scilab|scilex`, `flipdim`, `Matplot_properties`, `meshgrid`, `ismatrix`, `xget`, `xset`, `ieee`
 * rewritten: `consolebox`, `double`, `isoview`, `pixel_drawing_mode`, `householder`, `or`, `|,||`,
 `and`, `&,&&`, `format`, `typeof`, `brackets`, `setlanguage`, `sleep`, `isinf`,
-`bitor`, `bitxor`, `bitand`, `macr2tree`, `geomean`, `clf`, `getPreferencesValue`
+`bitor`, `bitxor`, `bitand`, `macr2tree`, `geomean`, `clf`, `getPreferencesValue`, `gcd`
 * reorganized:
   - `else`, `elseif`, `end`, `try`, `sciargs`, `global`, `halt`, `empty`, `power`, `numderivative`
   - `pixel_drawing_mode`, `show_window`, `twinkle`, `uigetcolor`, `winsid`, `xdel`, `xgrid`, `xname`, `xnumb`
@@ -370,6 +371,7 @@ the [development mailing list](dev@lists.scilab.org) for a particular toolbox.
 * [#15008](http://bugzilla.scilab.org/show_bug.cgi?id=15008): scilab crash in using operator AND (&, &&) or OR (| ||) with a string.
 * [#15010](http://bugzilla.scilab.org/show_bug.cgi?id=15010): Coselica did not simulate on Scilab 6.
 * [#15015](http://bugzilla.scilab.org/show_bug.cgi?id=15015): Xcos blocks using the `ascii` didn't work
+* [#15017](http://bugzilla.scilab.org/show_bug.cgi?id=15017): On numbers, `gcd` result was always of `int32` type instead of matching the input type.
 * [#15019](http://bugzilla.scilab.org/show_bug.cgi?id=15019): Add 'csci6' in the calling of ilib_build in 'Getting started with API_Scilab' help page.
 * [#15023](http://bugzilla.scilab.org/show_bug.cgi?id=15023): `clf()` wrongly reset `figure_id`.
 * [#15024](http://bugzilla.scilab.org/show_bug.cgi?id=15024): Xcos labels were not preserved at diagram compilation.
@@ -741,3 +743,4 @@ the [development mailing list](dev@lists.scilab.org) for a particular toolbox.
 * [#14685](http://bugzilla.scilab.org/show_bug.cgi?id=14685): datavec produced an invalid index error.
 * [#14980] (http://bugzilla.scilab.org/show_bug.cgi?id=14980): The datatip display of the root locus arcs is broken.
 * [#14992] (http://bugzilla.scilab.org/show_bug.cgi?id=14992): `readgateway` has been removed, use `whereis` instead.
+
index b6f9fce..613bec3 100644 (file)
@@ -2,8 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2006-2008 - INRIA
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2017 - Samuel GOUGEON
  *
  * 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.
  * along with this program.
  *
  -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="gcd">
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML"
+        xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org"
+        xml:lang="en" xml:id="gcd">
     <refnamediv>
         <refname>gcd</refname>
         <refpurpose>Greatest Common Divisor</refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Syntax</title>
-        <synopsis>[pgcd, U] = gcd(p)</synopsis>
+        <synopsis>
+            gpcd = gcd(P)
+            [gpcd, U] = gcd(P)
+        </synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Arguments</title>
         <variablelist>
             <varlistentry>
-                <term>p</term>
+                <term>P</term>
                 <listitem>
                     <para>
-                        a polynomial row vector <literal>p = [p1, ..., pn]</literal> (type equal to 2) or
-                        an integer row vector (type equal to 1 or 8).
+                        array of decimal integers, encoded integers, or of polynomials.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>pgcd</term>
+                <term>gpcd</term>
                 <listitem>
                     <para>
-                        vector of the same type as <literal>p</literal>
+                        single element of <literal>P</literal> type: the greatest
+                        common divisor of all <literal>P</literal> components.
                     </para>
                 </listitem>
             </varlistentry>
                 <term>U</term>
                 <listitem>
                     <para>
-                        matrix of the same type as <literal>p</literal>
+                        Square matrix of the <literal>P</literal> type, with integer components or
+                        of minimal degrees. Its last column <literal>B = U(:,$)</literal> holds
+                        Bezout coefficients, such that
+                        <literal>B(1)*P(1) + B(2)*P(2) + .... + B($)*P($) == gpcd</literal>.
                     </para>
                 </listitem>
             </varlistentry>
     <refsection>
         <title>Description</title>
         <para>
-            <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
+            <code>[gpcd, U] = gcd(P)</code> computes the greatest common divisor
+            <varname>gpcd</varname> of components of <varname>P</varname>, and an unimodular matrix
+            <varname>U</varname>.
         </para>
         <para>
-            <literal>p*U = [0 ... 0 pgcd]</literal>.
+            If <literal>P</literal> components are decimal or encoded integers, they are priorly
+            converted into <literal>int64</literal> signed integers.
         </para>
         <para>
-            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>.
+            If <varname>P</varname> has an unsigned inttype <literal>uint8</literal>,
+            <literal>uint16</literal>, <literal>uint32</literal> or <literal>uint64</literal>,
+            <varname>U</varname> gets the corresponding signed inttype.
         </para>
         <para>
-            The greatest common divisor of an array <literal>p</literal> of real numbersof real numbers can be obtained by
-            converting it to a polynomial before calling <literal>gcd</literal>, through <code>p = inv_coeff(p, 0)</code>.
+            When a second output is expected, an unimodular matrix <literal>U</literal> of the
+            <literal>P</literal> type is returned, such that
+            <itemizedlist>
+                <listitem>
+                    <literal>size(U) == [length(P) length(P)]</literal>
+                </listitem>
+                <listitem>
+                    <literal>matrix(P,1,-1)*U = [0...0 gpcd]</literal> with
+                    <literal>length(P)-1</literal> leading zeros
+                </listitem>
+                <listitem>
+                    <literal>det(U)</literal> is <literal>1</literal> or
+                    <literal>-1</literal>.
+                </listitem>
+            </itemizedlist>
         </para>
         <para>
-            If <literal>p</literal> is given as an integer double (type 1), then it is treated as an <literal>int32</literal>.
+            Its last column provides Bezout coefficients.
         </para>
+        <note>
+            <literal>gcd([0 0])</literal> returns <literal>0</literal>.
+        </note>
+        <warning>
+            For big <varname>P</varname> values (smaller but of the order of 2^63, depending also
+            on the number of input values), results may be corrupted by integer overflow and
+            wrapping (int8(127)+1 == -128).
+        </warning>
     </refsection>
     <refsection>
         <title>Examples</title>
         <programlisting role="example"><![CDATA[
-// Polynomial case
+// With polynomials
 s = %s;
-p = [s  s*(s+1)^2 2*s^2+s^3];
-[pgcd,u] = gcd(p);
+p = [s  s*(s+1)^2  2*s^2+s^3];
+[GCD, U] = gcd(p)
 p*u
 
-// Integer case
-V = int32([2^2*3^5 2^3*3^2 2^2*3^4*5]);
-[thegcd,U] = gcd(V)
+// With encoded integers
+V = uint16([2^2*3^5 2^3*3^2 2^2*3^4*5])
+[GCD, U] = gcd(V)
+typeof(GCD)
+typeof(U)
 V*U
 
-// Double case
+// With decimal integers
 V = [2^2*3^5 2^3*3^2 2^2*3^4*5];
-[thegcd,U] = gcd(V)
+[GCD, U] = gcd(V)
+type(GCD)
+type(U)
 V*U
 
-gcd(uint8([15 20]))
-
-gcd([iconvert(15, 4) iconvert(20, 4)])
-
-gcd(iconvert([15 20], 4))
+gcd([0 60])
+gcd([0 0])
  ]]></programlisting>
     </refsection>
     <refsection role="see also">
@@ -110,8 +143,32 @@ gcd(iconvert([15 20], 4))
                 <link linkend="lcm">lcm</link>
             </member>
             <member>
+                <link linkend="factor">factor</link>
+            </member>
+            <member>
+                <link linkend="prod">prod</link>
+            </member>
+            <member>
                 <link linkend="hermit">hermit</link>
             </member>
         </simplelist>
     </refsection>
-</refentry>
+    <refsection role="history">
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>6.0.1</revnumber>
+                <revdescription>
+                    <itemizedlist>
+                        <listitem>
+                            <literal>int64</literal> and <literal>uint64</literal> input integers
+                            are now supported.
+                        </listitem>
+                        <listitem>
+                            The input <literal>P</literal> may be any array instead of a row vector.
+                        </listitem>
+                    </itemizedlist>
+                </revdescription>
+            </revision>
+        </revhistory>
+    </refsection></refentry>
diff --git a/scilab/modules/elementary_functions/help/fr_FR/discrete/gcd.xml b/scilab/modules/elementary_functions/help/fr_FR/discrete/gcd.xml
deleted file mode 100644 (file)
index 16d5123..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="fr" xml:id="gcd">
-    <refnamediv>
-        <refname>gcd</refname>
-        <refpurpose>calcul de PGCD  </refpurpose>
-    </refnamediv>
-    <refsynopsisdiv>
-        <title>Séquence d'appel</title>
-        <synopsis>[pgcd, U] = gcd(p)</synopsis>
-    </refsynopsisdiv>
-    <refsection>
-        <title>Paramètres</title>
-        <variablelist>
-            <varlistentry>
-                <term>p</term>
-                <listitem>
-                    <para>
-                        vecteur ligne de polynômes <literal>p = [p1,..,pn] (type égal à 2) ou d'entiers (type égal à 1 ou 8)</literal>
-                    </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>pgcd</term>
-                <listitem>
-                    <para>
-                        vecteur de même type que <literal>p</literal>
-                    </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>u</term>
-                <listitem>
-                    <para>
-                        matrice de même type que <literal>p</literal>
-                    </para>
-                </listitem>
-            </varlistentry>
-        </variablelist>
-    </refsection>
-    <refsection>
-        <title>Description</title>
-        <para>
-            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>
-        </para>
-        <para>
-            Le PGCD d'une matrice <literal>p</literal> de réels peut s'obtenir en la convertissant en polynôme
-            avant d'appeler <literal>gcd</literal>, grâce à la commande <literal>p = inv_coeff(p, 0)</literal>.
-        </para>
-        <para>
-            Si <literal>p</literal> est donné comme un flottant entier (type 1), alors il est traité comme un <literal>int32</literal>.
-        </para>
-    </refsection>
-    <refsection>
-        <title>Exemples</title>
-        <programlisting role="example"><![CDATA[
-// Cas des polynômes
-s = %s;
-p = [s  s*(s+1)^2 2*s^2+s^3];
-[pgcd,u] = gcd(p);
-p*u
-
-// Cas des entiers
-V = int32([2^2*3^5 2^3*3^2 2^2*3^4*5]);
-[thegcd,U] = gcd(V)
-V*U
-
-// Cas des doubles
-V = [2^2*3^5 2^3*3^2 2^2*3^4*5];
-[thegcd,U] = gcd(V)
-V*U
-
-gcd(uint8([15 20]))
-
-gcd([iconvert(15, 4) iconvert(20, 4)])
-
-gcd(iconvert([15 20], 4))
- ]]></programlisting>
-    </refsection>
-    <refsection role="see also">
-        <title>Voir aussi</title>
-        <simplelist type="inline">
-            <member>
-                <link linkend="bezout">bezout</link>
-            </member>
-            <member>
-                <link linkend="lcm">lcm</link>
-            </member>
-            <member>
-                <link linkend="hermit">hermit</link>
-            </member>
-        </simplelist>
-    </refsection>
-</refentry>
diff --git a/scilab/modules/elementary_functions/help/ja_JP/discrete/gcd.xml b/scilab/modules/elementary_functions/help/ja_JP/discrete/gcd.xml
deleted file mode 100644 (file)
index cf268af..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2006-2008 - INRIA
- *
- * 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.
- *
- -->
-
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="ja" xml:id="gcd">
-
-    <refnamediv>
-
-        <refname>gcd</refname>
-
-        <refpurpose>最大公約数を計算</refpurpose>
-
-    </refnamediv>
-
-    <refsynopsisdiv>
-
-        <title>呼び出し手順</title>
-
-        <synopsis>[pgcd,U]=gcd(p)</synopsis>
-
-    </refsynopsisdiv>
-
-    <refsection>
-
-        <title>引数</title>
-
-        <variablelist>
-
-            <varlistentry>
-
-                <term>p</term>
-
-                <listitem>
-
-                    <para>
-
-                        多項式行ベクトル <literal>p=[p1,..,pn]</literal> または整数行ベクトル
-
-                        (8型)
-
-                    </para>
-
-                </listitem>
-
-            </varlistentry>
-
-        </variablelist>
-
-    </refsection>
-
-    <refsection>
-
-        <title>説明</title>
-
-        <para>
-
-            <code>[pgcd, U] = gcd(p)</code>は,
-
-            <literal>p</literal>の要素の最大公約数(<varname>pgcd</varname>)
-
-            および以下のような最小次数の
-
-            (多項式の逆を有する)ユニモジュラ行列 <varname>U</varname>
-
-            を計算します.
-
-        </para>
-
-        <para>
-
-            <literal>p*U=[0 ... 0 pgcd]</literal>
-
-        </para>
-
-        <para>
-
-            数学的には,<emphasis role='italic'>ユニモジュラ</emphasis> 行列
-
-            <literal>U</literal> は,
-
-            行列式 <literal>+1</literal> or <literal>-1</literal>を有する
-
-            正方整数行列です.
-
-        </para>
-
-        <para>
-
-            実数配列<literal>p</literal>の最大公約数は,
-
-            <literal>gcd</literal>をコールする前に, <code>p = inv_coeff(p, 0)</code>により
-
-            多項式に変換することにより得られます.
-
-        </para>
-
-    </refsection>
-
-    <refsection>
-
-        <title>例</title>
-
-        <programlisting role="example"><![CDATA[
-//多項式の場合
-s=poly(0,'s');
-p=[s,s*(s+1)^2,2*s^2+s^3];
-[pgcd,u]=gcd(p);
-p*u
-//整数の場合
-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)])
-gcd(iconvert([15 20],4))
-
- ]]></programlisting>
-
-    </refsection>
-
-    <refsection role="see also">
-
-        <title>参照</title>
-
-        <simplelist type="inline">
-
-            <member>
-
-                <link linkend="bezout">bezout</link>
-
-            </member>
-
-            <member>
-
-                <link linkend="lcm">lcm</link>
-
-            </member>
-
-            <member>
-
-                <link linkend="hermit">hermit</link>
-
-            </member>
-
-        </simplelist>
-
-    </refsection>
-
-</refentry>
-
diff --git a/scilab/modules/elementary_functions/help/pt_BR/discrete/gcd.xml b/scilab/modules/elementary_functions/help/pt_BR/discrete/gcd.xml
deleted file mode 100644 (file)
index 79fc70d..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2006-2008 - INRIA
- *
- * 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.
- *
- -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns5="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="gcd" xml:lang="pt">
-    <refnamediv>
-        <refname>gcd</refname>
-        <refpurpose>cálculo de máximo divisor comum</refpurpose>
-    </refnamediv>
-    <refsynopsisdiv>
-        <title> Seqüência de Chamamento </title>
-        <synopsis>[pgcd,U]=gcd(p)</synopsis>
-    </refsynopsisdiv>
-    <refsection>
-        <title>Parâmetros</title>
-        <variablelist>
-            <varlistentry>
-                <term>p</term>
-                <listitem>
-                    <para>
-                        vetor linha de polinômios <literal>p=[p1,..,pn]</literal> ou
-                        vetor linha de inteiros (tipo igual a 8)
-                    </para>
-                </listitem>
-            </varlistentry>
-        </variablelist>
-    </refsection>
-    <refsection>
-        <title>Descrição</title>
-        <para>
-            Computa o MDC dos componentes de <literal>p</literal> e uma matriz
-            unimodular (inversa de polinômios) <literal>U</literal>, com grau mínimo
-            tais que
-        </para>
-        <para>
-            <literal>p*U=[0 ... 0 pgcd]</literal>
-        </para>
-    </refsection>
-    <refsection>
-        <title>Exemplos</title>
-        <programlisting role="example"><![CDATA[
-//caso polinomial
-s=poly(0,'s');
-p=[s,s*(s+1)^2,2*s^2+s^3];
-[pgcd,u]=gcd(p);
-p*u
-
-//caso inteiro
-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)])
-
-gcd(iconvert([15 20],4))
- ]]></programlisting>
-    </refsection>
-    <refsection>
-        <title> Ver Também </title>
-        <simplelist type="inline">
-            <member>
-                <link linkend="bezout">bezout</link>
-            </member>
-            <member>
-                <link linkend="lcm">lcm</link>
-            </member>
-            <member>
-                <link linkend="hermit">hermit</link>
-            </member>
-        </simplelist>
-    </refsection>
-</refentry>
diff --git a/scilab/modules/elementary_functions/help/ru_RU/discrete/gcd.xml b/scilab/modules/elementary_functions/help/ru_RU/discrete/gcd.xml
deleted file mode 100644 (file)
index 5ced884..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2006-2008 - INRIA
- *
- * 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.
- *
- -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="ru" xml:id="gcd">
-    <refnamediv>
-        <refname>gcd</refname>
-        <refpurpose>наибольший общий делитель (НОД)</refpurpose>
-    </refnamediv>
-    <refsynopsisdiv>
-        <title>Синтаксис</title>
-        <synopsis>[pgcd, U]=gcd(p)</synopsis>
-    </refsynopsisdiv>
-    <refsection>
-        <title>Аргументы</title>
-        <variablelist>
-            <varlistentry>
-                <term>p</term>
-                <listitem>
-                    <para>
-                        вектор-строка полиномиальных значений <literal>p=[p1, ..., pn]</literal>
-                        либо вектор-строка целочисленных значений (тип 8).
-                    </para>
-                </listitem>
-            </varlistentry>
-        </variablelist>
-    </refsection>
-    <refsection>
-        <title>Описание</title>
-        <para>
-            <code>[pgcd, U]=gcd(p)</code> вычисляет наибольший общий делитель элементов <varname>p</varname>
-            (<varname>pgcd</varname>) и унимодулярной матрицы (с полиномиальной инверсией) <varname>U</varname>, с минимальной степенью такая, что
-        </para>
-        <para>
-            <literal>p*U=[0 ... 0 pgcd]</literal>.
-        </para>
-        <para>
-            В математике <emphasis role='italic'>унимодулярная</emphasis> матрица
-            <literal>U</literal> - это квадратная с целочисленными элементами,
-            определитель которой равен <literal>+1</literal> или <literal>-1</literal>.
-        </para>
-    </refsection>
-    <refsection>
-        <title>Примеры</title>
-        <programlisting role="example"><![CDATA[
-//случай полиномов
-s=poly(0,'s');
-p=[s,s*(s+1)^2,2*s^2+s^3];
-[pgcd,u]=gcd(p);
-p*u
-//случай целых чисел
-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)])
-
-gcd(iconvert([15 20],4))
- ]]></programlisting>
-    </refsection>
-    <refsection role="see also">
-        <title>Смотрите также</title>
-        <simplelist type="inline">
-            <member>
-                <link linkend="bezout">bezout</link>
-            </member>
-            <member>
-                <link linkend="lcm">lcm</link>
-            </member>
-            <member>
-                <link linkend="hermit">hermit</link>
-            </member>
-        </simplelist>
-    </refsection>
-</refentry>
diff --git a/scilab/modules/overloading/macros/%i_gcd.sci b/scilab/modules/overloading/macros/%i_gcd.sci
deleted file mode 100644 (file)
index 43abcc4..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) INRIA
-//
-// 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.
-
-function [x,uu]=%i_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]
-    //!
-
-    [lhs,rhs]=argn(0)
-    [m,n]=size(p);it=inttype(p)
-    mn=m*n
-    p=matrix(p,1,mn)
-    x=p(1);
-    uu=iconvert(1,it)
-    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]);
-        end
-    end,
-    if lhs==1 then return,end
-    for l=mn:-1:2
-        pivot=uu(l,l-1);
-        for k=l:mn
-            q=uu(l,k)/pivot
-            r=uu(l,k)-q*pivot
-            if q<>iconvert(0,it) then
-                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 4f1f06e..cc3d63d 100644 (file)
@@ -1,7 +1,7 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) ????-2008 - INRIA
-//
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2017 - Samuel GOUGEON : http://bugzilla.scilab.org/15017
 //
 // 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.
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-
 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)<>1 & type(p)<>2 & type(p)<>8 then
-        error(msprintf(_("%s: Wrong type for argument #%d: Integer array or Polynomial expected.\n"), "gcd", 1));
+    [lhs,rhs] = argn(0)
+    if rhs~=1
+        msg = _("%s: Wrong number of input arguments: %d expected.\n")
+        error(msprintf(msg, "gcd", 1));
+    end
+    if ~or(type(p)==[1 2 8])
+        msg = _("%s: Wrong type for argument #%d: Decimal or encoded integers or Polynomial expected.\n")
+        error(msprintf(msg, "gcd", 1));
     end
 
-    if type(p)==1 then
-        if floor(p)<>p then
-            error(msprintf(_("%s: Wrong type for argument #%d: Integer array or Polynomial expected.\n"), "gcd", 1));
-        else
-            p = iconvert(p,4);
+    if  type(p)~=2
+        intype = inttype(p)
+        if type(p)==1
+            if floor(p)<>p
+                msg = _("%s: Wrong values for argument #%d: Integer values expected.\n")
+                error(msprintf(msg, "gcd", 1));
+            else
+                p = iconvert(p,8);  // calculations may need/lead to negative terms (argout#2)
+            end
         end
     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
-    end
 
-    [m, n] = size(p)
-    mn = m*n
-    p = matrix(p, 1, mn)
+    mn = size(p,"*")
+    p = matrix(p, 1, -1)
     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 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;
+    end
+
+    if lhs>1
+        if type(p)==2
+            // Polynomials case
+            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;
+                    end
+                end
+            end
+        else
+            // Integers
+            iz = iconvert(0,intype)
+            for l = mn:-1:2
+                pivot = uu(l, l-1);
+                for k=l:mn
+                    q = uu(l,k)/pivot
+                    r = uu(l,k)-q*pivot
+                    if q <> iz then
+                        uu(1:l-1,k)=uu(1:l-1,k)-q*uu(1:l-1,l-1)
+                        uu(l,k)=r;
+                    end
+                end
             end
         end
     end
+    if type(p)==8
+        x  = iconvert(x, intype)
+        uu = iconvert(uu, modulo(intype,10))    // may have negative terms
+    end
 
 endfunction
diff --git a/scilab/modules/polynomials/tests/unit_tests/gcd.tst b/scilab/modules/polynomials/tests/unit_tests/gcd.tst
new file mode 100644 (file)
index 0000000..7668ba0
--- /dev/null
@@ -0,0 +1,84 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2017 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// unit tests for gcd()
+// ====================
+
+// Checking arguments
+// ------------------
+[g, f] = gcd([]);
+assert_checkequal(g, []);
+assert_checkequal(f, 1);
+d = 9*49*13*23*29*37*47;    // 6.650D+09   2^63 ~ 9.223D+18
+v = [d*2*25*31  d*29*37  d*31];
+[g, f] = gcd(v);
+assert_checkequal(size(g), [1 1]);
+assert_checkequal(size(f), [3 3]);
+
+// Checking errors
+// ---------------
+assert_checkfalse(execstr("gcd()", "errcatch")==0);
+assert_checkfalse(execstr("gcd(%z,%s)", "errcatch")==0);
+assert_checkfalse(execstr("[a,b,c]=gcd(v)", "errcatch")==0);
+assert_checkfalse(execstr("gcd(sparse([25 21 110]))", "errcatch")==0);
+assert_checkfalse(execstr("gcd([25 21 110]+0.1)", "errcatch")==0);
+
+// Checking results
+// ================
+// With encoded integers
+// ---------------------
+//--> pr = primes(50)
+// pr  =
+//   2.  3.  5.  7.  11.  13.  17.  19.  23.  29.  31.  37.  41.  43.  47.
+// int8
+Gcd = 10;     // 2^7 = 128
+v = [10*3 ; 10*11];
+// int16
+d =  3*7*13;  // 273.  2^15 = 32768
+Gcd = [Gcd  d];
+v = [v  [d*3*17 ; d*5*23]];
+// int32
+d =  3*7*13*29*37;  // 292929.  2^31 ~ 2.147D+09
+Gcd = [Gcd  d];
+v = [v  [d*2*19*27 ; d*5*11*23]];
+// int64
+d = 9*49*13*23*29*37*47;  // 6.650D+09   2^63 ~ 9.223D+18
+Gcd = [Gcd  d];
+v = [v  [d*2*25*31 ; d*7*29]];  // 1.031D+13 ; 1.350D+12
+for j = 1:length(Gcd)
+    for i = [0 10]
+        ty = 2^(j-1)+i;  // inttype: [1 11 2 12 4 14 8 18]
+        [g, m] = gcd(iconvert(v(:,j), ty));
+        assert_checkequal(inttype(g), ty);
+        assert_checkequal(g, iconvert(Gcd(j), ty));
+        assert_checkequal(inttype(m), modulo(ty,10));
+        if ty~=18
+            assert_checkequal(v(:,j)'*m, iconvert([0 Gcd(j)],inttype(m)));
+            // Otherwise there are expected round-off errors
+        end
+    end
+end
+
+// With decimal integers
+// ---------------------
+// Decimals  2^31 ~ 2.147D+09 < X < 2^52 ~ 4.504D+15
+v = [d*2*25*31 ; d*29*37];  //    1.031D+13 ; 7.135D+12
+[g, f] = gcd(v);
+assert_checkequal(g, d);
+assert_checkequal(v'*f, [0 g]);
+
+// With polynomials
+// ----------------
+d = (1-%z)*(2+%z)*(5*%z -4);
+v = d*[%z (%z+1)];
+[g, f] = gcd(v);
+assert_checkequal(type(g), 2);
+assert_checktrue(clean(g+d/5)==0);
+assert_checkequal(clean(f - [-5-5*%z, 0.2 ; 5*%z, -0.2]),zeros(2,2)*%z);