* modulo() and pmodulo() support integers & hypermatrices 61/13061/5
Samuel Gougeon [Fri, 1 Nov 2013 02:05:07 +0000 (03:05 +0100)]
Change-Id: I056f796d23f04d36253fbace3c2b6fcbad756b8f

scilab/CHANGES_5.5.X
scilab/modules/elementary_functions/help/en_US/modulo.xml
scilab/modules/elementary_functions/help/fr_FR/modulo.xml
scilab/modules/elementary_functions/macros/modulo.sci
scilab/modules/elementary_functions/macros/pmodulo.sci

index a1c28ef..d234b41 100644 (file)
@@ -10,6 +10,8 @@ New Features
 * New functions introduced:
  - jcreatejar - Creates a Java archive (JAR) from a set of files / directories
 
+* modulo() and pmodulo() now support integers & hypermatrices (See bug #13002).
+
 
 Scilab Bug Fixes
 ================
@@ -129,6 +131,8 @@ Scilab Bug Fixes
 
 * Bug #13000 fixed - []./int8(3) and on int8(3)./[] led to an endless recursive.
 
+* Bug #13002 fixed - modulo() and pmodulo() did not support integers & hypermatrices.
+
 * Bug #13003 fixed - String to enum converter added to Java external objects.
 
 * Bug #13004 fixed - Debug infos were printed on an error with eoj.
index fb3050f..48d49f0 100644 (file)
@@ -7,18 +7,18 @@
  * 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
  *
  -->
 <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="modulo" xml:lang="en">
     <refnamediv>
         <refname>modulo</refname>
-        <refpurpose>symmetric arithmetic remainder modulo m</refpurpose>
+        <refpurpose>remainder modulo m with the left operand sign</refpurpose>
     </refnamediv>
     <refnamediv xml:id="pmodulo">
         <refname>pmodulo</refname>
-        <refpurpose>positive arithmetic remainder modulo m</refpurpose>
+        <refpurpose>positive euclidian remainder modulo m</refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Calling Sequence</title>
         <title>Arguments</title>
         <variablelist>
             <varlistentry>
-                <term>n</term>
+                <term>m, n</term>
                 <listitem>
-                    <para>real or polynomial vector or matrix </para>
+                    <para>Scalar, vector, matrix or hypermatrix of encoded integers, reals or polynomials (Hypermatrix is not supported for polynomials). 
+                        <varname>m</varname> and <varname>n</varname> must have the same type. If they are of integer type, they may be of distinct 
+                        encoding length (for instance int8 and int16). If none of them is scalar, they must have the same sizes.
+                    </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>m</term>
+                <term>i</term>
                 <listitem>
-                    <para>real or polynomial vector or matrix </para>
+                    <para>
+                        Scalar, vector, matrix or hypermatrix of same type (and inttype) as <varname>n</varname>.
+                        <varname>i</varname> takes the sizes of the bigger <varname>m</varname> or<varname>n</varname>.
+                    </para>
                 </listitem>
             </varlistentry>
         </variablelist>
     <refsection>
         <title>Description</title>
         <para>
-            <function>modulo</function> computes <code>i = n (modulo
-                m)
-            </code>
-            i.e. remainder of <varname>n</varname> divided by
-            <varname>m</varname>.
+            <function>modulo</function> computes <code>i = n (modulo m)</code>
+            i.e. remainder of <varname>n</varname> divided by <varname>m</varname>.
         </para>
         <para>
             <code>i = n - m .* int (n ./ m)</code>. Here the answer may be negative
             if <varname>n</varname> or <varname>m</varname> are negative.
         </para>
         <para>
-            <function>pmodulo</function> computes <code>i = n - |m| .* floor (n
-                ./ |m|)
-            </code>
-            , the answer is positive or zero.
-        </para>
-        <para>
-            <code>modulo(x,0)</code> returns an error message: "Division by zero...". With ieee(2), <code>modulo(x,0)</code> returns <constant>%nan</constant>.
-        </para>
-        <para>
-            <code>pmodulo(x,0)</code> returns an error message: "Division by zero...". With ieee(2), <code>pmodulo(x,0)</code> returns <constant>%nan</constant>.
-        </para>
-    </refsection>
-    <refsection>
-        <title>Remark</title>
-        <para><note>
-                If m and n are vector or matrix type, m and n must have the same dimensions.
-            </note>
+            <function>pmodulo</function> computes <code>i = n - |m| .* floor (n ./ |m|)</code>,
+            the answer is positive or zero.
         </para>
+        <warning>
+            If <varname>m</varname> contains at least one 0 value, <code>modulo(x,m)</code> and <code>pmodulo(x,m)</code> will perform a division by zero. If <varname>m</varname> is of real type, this exception will be processed according to the <literal>ieee()</literal> mode. For encoded integers, it will always yield an error.
+        </warning>
     </refsection>
     <refsection>
         <title>Examples</title>
@@ -88,6 +79,51 @@ modulo(10, -4)
 pmodulo(-3, 9)
 pmodulo(10, -6)
 pmodulo(-10, -6)
+
+// Encoded integers
+modulo( int8(-13), int16(-7))
+pmodulo(int8(-13), int16(-7))
+modulo( int8(-13), int16([-7 5]))
+pmodulo(int8(-13), int16([-7 5]))
+modulo( int8([-13 8]), int16(-7))
+pmodulo(int8([-13 8]), int16(-7))
+modulo( int8([-13 8]), int16([-7 5]))
+pmodulo(int8([-13 8]), int16([-7 5]))
+
+// Hypermatrices
+m = grand(2,2,2,"uin",-100,100)
+n = grand(2,2,2,"uin",-10 ,10);
+n(n==0) = 1
+modulo(m, 5)
+pmodulo(m,5)
+modulo(51, n)
+pmodulo(51,n)
+modulo(m, n)
+pmodulo(m,n)
+
+// Polynomials
+modulo( %z^2+1, %z)
+pmodulo(%z^2+1, %z)
+
+
  ]]></programlisting>
     </refsection>
+    <refsection role= "see also">
+        <title>See also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="ieee">ieee</link>
+            </member>
+        </simplelist>
+    </refsection>
+    <refsection>
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>5.5.0</revnumber>
+                <revremark>Extension to encoded integers and to hypermatrices of encoded integers or reals.</revremark>
+            </revision>
+        </revhistory>
+    </refsection>
+    
 </refentry>
index 488bc53..fd25312 100644 (file)
@@ -7,18 +7,18 @@
  * 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
  *
  -->
 <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="modulo" xml:lang="fr">
     <refnamediv>
         <refname>modulo</refname>
-        <refpurpose>reste arithmétique symétrique modulo m</refpurpose>
+        <refpurpose>reste symétrique modulo m ayant le signe du dividande</refpurpose>
     </refnamediv>
     <refnamediv xml:id="pmodulo">
         <refname>pmodulo</refname>
-        <refpurpose>reste arithmétique positif modulo m</refpurpose>
+        <refpurpose>reste modulo m euclidien positif</refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Séquence d'appel</title>
         <title>Paramètres</title>
         <variablelist>
             <varlistentry>
-                <term>n</term>
+                <term>m, n</term>
                 <listitem>
-                    <para>vecteur ou matrice de rééls ou de polynômes</para>
+                    <para>Scalaire, vecteur, matrice ou hypermatrice d'entiers encodés, de décimaux réels ou de polynômes (les hypermatrices de polynômes ne sont pas admises). 
+                        <varname>m</varname> et <varname>n</varname> doivent être de même type. S'ils sont de types entiers, il peuvent être d'encodages distincts (par exemple int8 et int16) Si aucune des deux n'est scalaire, elles doivent avoir les mêmes dimensions.
+                    </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>m</term>
+                <term>i</term>
                 <listitem>
-                    <para>vecteur ou matrice de rééls ou de polynômes</para>
+                    <para>
+                        Scalaire, vecteur, matrice ou hypermatrice du type de <varname>n</varname> (voire de même inttype).
+                        <varname>i</varname> a les dimensions de la plus large de <varname>m</varname> ou<varname>n</varname>.
+                    </para>
                 </listitem>
             </varlistentry>
         </variablelist>
             <literal>n</literal> et/ou <literal>m</literal> sont négatifs.
         </para>
         <para>
-            <literal>pmodulo</literal> calcule <literal>i = n - |m| .* floor (n ./
-                |m|)
-            </literal>
-            ,la réponse est positive ou nulle.
-        </para>
-    </refsection>
-    <refsection>
-        <title>Remarque</title>
-        <para>
-            <note>
-                Si m et n sont des vecteurs ou des matrices, ils doivent être de même taille.
-            </note>
+            <literal>pmodulo</literal> calcule <literal>i = n - |m| .* floor (n ./|m|)</literal>,la réponse est positive ou nulle.
         </para>
+        <warning>
+            Si <literal>m</literal> contient au moins une valeur nulle, <code>modulo(x,m)</code> et <code>pmodulo(x,m)</code> effectueront une division par zéro. Si <varname>m</varname> est de type réel, l'exception sera traitée selon le mode <literal>ieee()</literal> actif. Si <literal>m</literal> est de type entier, une erreur sera toujours émise.
+        </warning>
     </refsection>
     <refsection>
         <title>Exemples</title>
@@ -80,6 +77,49 @@ modulo(10, -4)
 pmodulo(-3, 9)
 pmodulo(10, -6)
 pmodulo(-10, -6)
+
+// Entiers encodés
+modulo( int8(-13), int16(-7))
+pmodulo(int8(-13), int16(-7))
+modulo( int8(-13), int16([-7 5]))
+pmodulo(int8(-13), int16([-7 5]))
+modulo( int8([-13 8]), int16(-7))
+pmodulo(int8([-13 8]), int16(-7))
+modulo( int8([-13 8]), int16([-7 5]))
+pmodulo(int8([-13 8]), int16([-7 5]))
+
+// Hypermatrices
+m = grand(2,2,2,"uin",-100,100)
+n = grand(2,2,2,"uin",-10 ,10);
+n(n==0) = 1
+modulo(m, 5)
+pmodulo(m,5)
+modulo(51, n)
+pmodulo(51,n)
+modulo(m, n)
+pmodulo(m,n)
+
+// Polynômes
+modulo( %z^2+1, %z)
+pmodulo(%z^2+1, %z)
+
  ]]></programlisting>
     </refsection>
+    <refsection role= "see also">
+        <title>Voir aussi</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="ieee">ieee</link>
+            </member>
+        </simplelist>
+    </refsection>
+    <refsection>
+        <title>Historique</title>
+        <revhistory>
+            <revision>
+                <revnumber>5.5.0</revnumber>
+                <revremark>Extension aux entiers encodés et aux hypermatrices d'entiers ou de réels.</revremark>
+            </revision>
+        </revhistory>
+    </refsection>
 </refentry>
index 63d6056..1058ec6 100644 (file)
@@ -2,6 +2,7 @@
 // Copyright (C) INRIA
 // Copyright (C) DIGITEO - 2011 - Allan CORNET
 // Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
+// Copyright (C) 2013 - Samuel GOUGEON : Bug 13002 : extension to hypermatrices & integers
 //
 // This file must be used under the terms of the CeCILL.
 // This source file is licensed as described in the file COPYING, which
 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
 
 function i = modulo(n, m)
-    //i=modulo(n,m) returns  n modulo m.
 
     [lhs, rhs] = argn(0);
     if rhs <> 2 then
-        error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"),"modulo", 2));
+        msg = _("%s: Wrong number of input argument(s): %d expected.\n")
+        error(msprintf(msg, "modulo", 2))
     end
 
-    if and(typeof(n) <> ["constant", "polynomial"]) | ~isreal(n) then
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: A real expected.\n"), "modulo", 1));
+    mt = type(m($))
+    nt = type(n($))
+    // -----------------------  Checking arguments --------------------------
+
+    if or(type(n)==[15 16]) | and(nt <> [1 2 8]) | (nt==1 & ~isreal(n))
+        msg = _("%s: Wrong type for input argument #%d: Reals, encoded integers or polynomials expected.\n")
+        error(msprintf(msg, "modulo", 1))
+    end
+
+    if or(type(m)==[15 16]) |  and(mt <> [1 2 8]) | (mt==1 & ~isreal(m))
+        msg = _("%s: Wrong type for input argument #%d: Reals, encoded integers or polynomials expected.\n")
+        error(msprintf(msg, "modulo", 2))
     end
 
-    if typeof(m) <> "constant" & typeof(m) <> "polynomial" | ~isreal(m) then
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: A real expected.\n"), "modulo", 2));
+    if (nt==8 | mt==8)  & nt~=mt
+        msg = _("%s: Incompatible input arguments #%d and #%d: Same types expected.\n")
+        error(msprintf(msg, "modulo", 1, 2))
     end
 
-    if typeof(m) =="constant" & typeof(n) =="constant" then
-        if size(n,"*")==1 then
-            i = zeros(m);
-            k = find(m==0);
-            i(k) = n - int(n ./ m(k)) .* m(k);
-            k = find(m~=0);
-            i(k) = n-int(n./m(k)).*m(k);
-        elseif size(m,"*")==1 then
-            i = zeros(n);
-            if m == 0 then
-                i = n - int(n ./ m) .* m;
-            else
-                i = n-int(n./m).*m;
-            end
+    // --------------------------  Processing ----------------------------
+
+    if or(mt==[1 8]) & mt==nt then
+        ms = size(m)
+        ns = size(n)
+        m = m(:)
+        n = n(:)
+        if length(n)>1 & length(m)>1 & or(ns <> ms) then
+            msg = _("%s: Wrong size for input arguments: Same size expected.\n")
+            error(msprintf(msg, "modulo"))
+        end
+        i = n - int(n ./ m) .* m
+        i = iconvert(i, inttype(n))
+        if length(m)>1 then
+            s = ms
         else
-            if or(size(n) <> size(m)) then
-                error(msprintf(gettext("%s: Wrong size for input arguments: Same size expected.\n"),"modulo"));
-            end
-            i = zeros(n);
-            k = find(m==0);
-            i(k) = n(k) - int(n(k) ./ m(k)) .* m(k);
-            k = find(m~=0);
-            i(k) = n(k) - int(n(k)./m(k)).*m(k);
+            s = ns
         end
+        i = matrix(i, s)
     else
-        [i,q]=pdiv(n,m);
+        [i,q] = pdiv(n, m)
     end
-endfunction
-
-
-
-
-
 
+endfunction
index 5e59f88..6164a87 100644 (file)
@@ -2,7 +2,7 @@
 // Copyright (C) INRIA
 // Copyright (C) DIGITEO - 2011 - Allan CORNET
 // Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
-// Copyright (C) 2013 - Samuel GOUGEON
+// Copyright (C) 2013 - Samuel GOUGEON :  : bugs 12373 & 13002
 //
 // This file must be used under the terms of the CeCILL.
 // This source file is licensed as described in the file COPYING, which
@@ -16,39 +16,55 @@ function i = pmodulo(n, m)
 
     [lhs, rhs] = argn(0);
     if rhs <> 2 then
-        error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "pmodulo", 2));
+        msg = _("%s: Wrong number of input argument(s): %d expected.\n")
+        error(msprintf(msg, "pmodulo", 2))
     end
 
-    if ~isreal(n) then
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: A real expected.\n"), "pmodulo", 1));
+    mt = type(m($))
+    nt = type(n($))
+
+    // -----------------------  Checking arguments --------------------------
+
+    if or(type(n)==[15 16]) | and(nt <> [1 2 8]) | (nt==1 & ~isreal(n)) then
+        msg = _("%s: Wrong type for input argument #%d: Reals, encoded integers or polynomials expected.\n")
+        error(msprintf(msg, "pmodulo", 1))
     end
 
-    if ~isreal(m) then
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: A real expected.\n"), "pmodulo", 2));
+    if or(type(m)==[15 16]) | and(mt <> [1 2 8]) | (mt==1 & ~isreal(m)) then
+        msg = _("%s: Wrong type for input argument #%d: Reals, encoded integers or polynomials expected.\n")
+        error(msprintf(msg, "pmodulo", 2))
     end
 
-    m = abs(m)  // else returns i<0 for m<0 : http://bugzilla.scilab.org/12373
-    if size(n,"*") == 1 then
-        i = zeros(m);
-        k = find(m == 0)
-        i(k) = n - floor(n ./ m(k)) .* m(k);
-        k = find(m~=0);
-        i(k) = n-floor(n./m(k)).*m(k);
-    elseif size(m,"*") == 1 then
-        i = zeros(n);
-        if m == 0 then
-            i = n - floor(n ./ m) .* m;
-        else
-            i = n-floor(n./m).*m;
-        end
+    if (nt==8 | mt==8)  & nt~=mt
+        msg = _("%s: Incompatible input arguments: Same types expected.\n")
+        error(msprintf(msg, "pmodulo"))
+    end
+
+    // --------------------------  Processing ----------------------------
+
+    if  nt==2 then
+        [i,q] = pdiv(n, m)
     else
-        if or(size(n)<>size(m)) then
-            error(msprintf(gettext("%s: Wrong size for input arguments: Same size expected.\n"),"pmodulo"));
+        ms = size(m)
+        ns = size(n)
+        m = m(:)
+        n = n(:)
+        m = abs(m)  // else returns i<0 for m<0 : http://bugzilla.scilab.org/12373
+        if length(n)>1 & length(m)>1 & or(ns<>ms) then
+            msg = _("%s: Wrong size for input arguments: Same size expected.\n")
+            error(msprintf(msg, "pmodulo"))
+        end
+        i = n - floor(n ./ m) .* m
+        k = find(i<0)           // this may occur for encoded integers
+        if length(m)>1 then
+            i(k) = i(k) + m(k)
+            i = iconvert(i, inttype(n))
+            i = matrix(i, ms)
+        else
+            i(k) = i(k) + m
+            i = iconvert(i, inttype(n))
+            i = matrix(i, ns)
         end
-        i = zeros(n);
-        k = find(m==0);
-        i(k) = n(k) - floor(n(k) ./ m(k)) .* m(k);
-        k = find(m~=0);
-        i(k) = n(k)-floor(n(k)./m(k)).*m(k);
     end
+
 endfunction