Elementary_functions: members() improved 82/12282/8
Paul BIGNIER [Wed, 14 Aug 2013 09:56:06 +0000 (11:56 +0200)]
Added row-wise, column-wise and shuffle search and modified the optional arguments.

Displayed head comments for zero input arguments call to members() and updated doc & SEP.

Added a warning for "shuffle" option outside of "row" or "column" modes.

Typo fix in SEP #102.

Change-Id: Ie7eec14c3003ad4b3b92eea2533bbe5b961da790

SEP/SEP_102_members.odt
scilab/modules/elementary_functions/help/en_US/setoperations/members.xml
scilab/modules/elementary_functions/help/fr_FR/setoperations/members.xml
scilab/modules/elementary_functions/macros/members.sci
scilab/modules/elementary_functions/tests/unit_tests/members.dia.ref
scilab/modules/elementary_functions/tests/unit_tests/members.tst
scilab/modules/m2sci/help/en_US/m2sci_equivalents/i/ismember.xml

index c4db1fb..6bc0df3 100644 (file)
Binary files a/SEP/SEP_102_members.odt and b/SEP/SEP_102_members.odt differ
index de18b6e..88d741d 100644 (file)
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2009 - Université du Maine - Samuel Gougeon
+ * Copyright (C) 2013 - Samuel GOUGEON
+ * Copyright (C) 2009 - Université du Maine - Samuel GOUGEON
  *
  * 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
  *
  -->
-<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="members" xml:lang="fr">
+<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="members" xml:lang="en">
     <refnamediv>
         <refname>members</refname>
-        <refpurpose>returns vectors of indexes corresponding to the common values of two matrices
+        <refpurpose>count (and locate) in an array each element or row or column of another array
         </refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Calling Sequence</title>
-        <synopsis>[nb [,loc]] = members(A, S [,last])</synopsis>
+        <synopsis>
+            [nb [,loc]] = members(N, H)
+            [nb [,loc]] = members(N, H, "last")
+            [nb [,loc]] = members(N, H, "rows"|"cols")
+            [nb [,loc]] = members(N, H, "rows"|"cols", "last")
+            [nb [,loc]] = members(N, H, "rows"|"cols", "shuffle")
+            [nb [,loc]] = members(N, H, "rows"|"cols", "shuffle", "last")
+        </synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Arguments</title>
         <variablelist>
             <varlistentry>
-                <term>A</term>
+                <term>N</term>
                 <listitem>
-                    <para>matrix or hypermatrix of booleans, integers, reals, complexes, polynomials or strings</para>
+                    <para>
+                        Needles: matrix or hypermatrix of booleans, integer-encoded numbers, real or complex decimal numbers, polynomials or texts. In "rows" or "cols" mode, no hypermatrix is accepted. A given value (or row or column) may appear several times in <literal>N</literal>.
+                    </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>S</term>
+                <term>H</term>
                 <listitem>
                     <para>
-                        matrix or hypermatrix of same datatype as <literal>A</literal>
+                        Haystack: matrix or hypermatrix of same data type as <literal>N</literal>. In "rows" or "cols" mode, no hypermatrix is accepted, and <literal>N</literal> and <literal>H</literal> must have respectively the same number of columns or rows.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>last</term>
+                <term>Options:</term>
                 <listitem>
-                    <para>scalar boolean</para>
+                    <para>From one to three options may be specified in any order:
+                        <variablelist>
+                            <varlistentry>
+                                <term>"last"</term>
+                                <listitem>
+                                    <para>
+                                        when the location in <literal>H</literal> of needles from <literal>N</literal> is querried through <literal>loc</literal>, by default the position of the first respective occurrences in <literal>H</literal> are returned. If <literal>"last"</literal> is specified, the position of the last occurrences in <literal>H</literal> are returned instead.
+                                    </para>
+                                </listitem>
+                            </varlistentry>
+                            <varlistentry>
+                                <term>"rows", "cols"</term>
+                                <listitem>
+                                    <para>
+                                        By default, each element <literal>N(i, j, ...)</literal> of <literal>N</literal> is considered as a needle to search in <literal>H</literal>. If <literal>"rows"</literal> is specified, each row of <literal>N</literal> is considered as a needle -- as a whole --, and is searched among rows of <literal>H</literal>. The same applies between columns of <literal>N</literal> and <literal>H</literal> if <literal>"cols"</literal> is used.
+                                    </para>
+                                </listitem>
+                            </varlistentry>
+                            <varlistentry>
+                                <term>"shuffle"</term>
+                                <listitem>
+                                    <para>
+                                        In <literal>"rows"</literal> or <literal>"cols"</literal> mode, by default the order of components of a row/column is considered: for instance, <literal>[ 7 3 5 ]</literal> in <literal>N</literal> does not match <literal>[3 5 7]</literal> in <literal>H</literal>. When <literal>"shuffle"</literal> is specified, any permutation of --say--<literal>[3 5 7]</literal> will be considered as matching a <literal>[3 5 7]</literal> row of <literal>N</literal>. This option is ignored for polynomials.
+                                    </para>
+                                </listitem>
+                            </varlistentry>
+                        </variablelist>
+                    </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>nb</term>
                 <listitem>
                     <para>
-                        matrix of reals, same size as <literal>A</literal>
+                        In normal mode: <literal>nb(i, j, ...)</literal> returns (as reals) the number of occurrences in <literal>H</literal> of <literal>N(i, j, ...)</literal>. <literal>nb</literal> and <literal>N</literal> have the same format. If <literal>H</literal> is empty, a matrix of zeros is returned. If <literal>N</literal> is empty, the empty matrix <literal>[]</literal> is returned.
+                    </para>
+                    <para>
+                        In <literal>"rows"</literal> or <literal>"cols"</literal> mode: <literal>nb</literal> is a row of reals with as many components as <literal>N</literal> has rows/columns. <literal>nb(i)</literal> returns the number of occurrences in <literal>H(., :)</literal> of <literal>N(i, :)</literal> (or of <literal>N(:, i)</literal> in <literal>H(:, .)</literal> ).
                     </para>
                 </listitem>
             </varlistentry>
                 <term>loc</term>
                 <listitem>
                     <para>
-                        matrix of reals, same size as <literal>A</literal>
+                        In normal mode: <literal>loc</literal> and <literal>N</literal> have the same format. <literal>loc(i, j, ...)</literal> returns the smallest linearized index in <literal>H</literal> where <literal>N(i, j, ...)</literal> occurs. If the <literal>"last"</literal> flag is used, the greatest linearized index is returned instead. If <literal>N(i, j, ...)</literal> in not found in <literal>H</literal>, <literal>loc(i, j, ...)</literal> is set to <literal>0</literal>.
+                    </para>
+                    <para>
+                        In <literal>"rows"</literal> or <literal>"cols"</literal> mode: <literal>loc</literal> is a row of reals with as many components as <literal>N</literal> has respectively rows or columns. <literal>loc(i)</literal> returns the index of the first line <literal>H(loc(i), :)</literal> matching <literal>N(i, :)</literal> (or the index of the first column <literal>H(:, loc(i))</literal> matching <literal>N(:, i)</literal>). If the <literal>"shuffle"</literal> flag is additionnaly specified, the order of components along the rows/columns is not considered.
                     </para>
                 </listitem>
             </varlistentry>
     <refsection>
         <title>Description</title>
         <para>
-            <literal>nb = members(A, S)</literal> returns the number of occurrences of <literal>A</literal> in <literal>S</literal>.
-            After <literal>[nb, loc] = members(A, S, last)</literal>,
-            <literal>loc(i, j)</literal>contains the linear index in <literal>S</literal> of the first occurrence of <literal>A(i, j)</literal>.
-            If <literal>last==%t</literal>, the index of the last occurrence is returned instead.
-            <literal>loc(i, j)</literal> returns zero if <literal>A(i, j)</literal> is not found.
-            <literal>%inf</literal> and <literal>-%inf</literal> values are supported either in <literal>A</literal> as well as in <literal>S</literal>.
-            <literal>%nan</literal> are only supported in <literal>A</literal>.
+            <literal>nb = members(N, H [,"rows"|"cols"])</literal> returns the number of occurrences of each component or row or column of <literal>N</literal> found in <literal>H</literal>. If no match is found for an element, 0 is returned for it.
+            The index in <literal>H</literal> of the first (default) or <literal>"last"</literal> occurrence of <literal>N(i,j,...)</literal> can be querried through a second optional output <literal>loc</literal>.
+            If matching <literal>"rows"</literal> or <literal>"cols"</literal> are searched for, matches can ignore the order of their elements, by using the option <literal>"shuffle"</literal>.
         </para>
         <para>
-            When <literal>A</literal> is a vector of doubles or integers and <literal>S</literal> is a vector of doubles or integers in strictly increasing order,
-            <literal>dsearch(A, S, "d")</literal> is preferred over <literal>members(A, S)</literal>.
+            <literal>%inf</literal> and <literal>-%inf</literal> values are supported in <literal>N</literal> as well as in <literal>H</literal>.
+            In normal mode, <literal>%nan</literal> are supported in <literal>N</literal> but not in <literal>H</literal>. In <literal>"rows"</literal> or <literal>"cols"</literal> modes, <literal>%nan</literal> are supported everywhere.
+        </para>
+        <para>
+            In normal element-wise mode, members(..) uses <link type="scilab" linkend="dsearch">dsearch(..)</link> to fastly proceed with booleans, integer-encoded numbers (any length 8-16-32 bits signed or not), and real numbers. For complex numbers, texts, and polynomials, a slower and more memory-consuming algorithm is used. For better performances with these types of data, for big <literal>N</literal> or/and <literal>H</literal>, the user may priorly increase the <link type="scilab" linkend="scilab.help/stacksize">stacksize(..)</link>. For long calculations, a progression bar is displayed.
         </para>
     </refsection>
     <refsection>
         <title>Examples</title>
         <programlisting role="example"><![CDATA[
-A = [1 8 4 5 2 1];
-S = [9 7 4 2 1 4];
+N = [1 8 4 5 2 1];
+H = [9 7 4 2 1 4];
 
-[nb, loc] = members(A, S, %t)
-// Returns nb  = [1 0 2 0 1 1] because, for instance, the third element of A (which is 4) appears twice in S.
-// And     loc = [5 0 6 0 4 5] because the last occurrence in S of the third element of A (which is 4) is in sixth position
+[nb, loc] = members(N, H, "last")
+// Returns nb  = [1 0 2 0 1 1]: for instance, 4 appears twice in H.
+// And     loc = [5 0 6 0 4 5]: the last occurrence of 4 is in sixth position in H
 
-[nb, loc] = members(A, S, %f)
-// Returns loc = [5 0 3 0 4 5] because the first occurrence in S of the third element of A (which is 4) is in third position
+[nb, loc] = members(N, H)
+// Returns loc = [5 0 3 0 4 5]: the 1st occurrence of 4 is in third position in H
 
-// With hypermatrices. From previous A and S:
-A = matrix(A, [3 1 2]);
-S = matrix(S, [3 1 2]);
-[nb, loc] = members(A, S, %T)
+// With hypermatrices. From previous N and H:
+N = matrix(N, [3 1 2]);
+H = matrix(H, [3 1 2]);
+[nb, loc] = members(N, H, "last")
 
 // With integers:
-A = int8(grand(3, 2, "uin", -5, 5));
-S = int8(grand(4, 4, "uin", -5, 5));
-[nb, loc] = members(A, S)
+N = int8(grand(3, 2, "uin", -5, 5));
+H = int8(grand(4, 4, "uin", -5, 5));
+[nb, loc] = members(N, H)
 
 // With polynomials (complex coefficients are accepted):
 z = %z;
-A = [z (1-z)^2 ; -4 %i*z ];
-S = [2  %i*z -z  3-z  z  z^3 z];
-[nb, loc] = members(A, S)
+N = [z (1-z)^2 ; -4 %i*z ];
+H = [2  %i*z -z  3-z  z  z^3 z];
+[nb, loc] = members(N, H)
 
 // With text:
-A = [ "Hi" "Hu" "Allo"];
-S = [ "Hello" "Bonjour" "Allo"
+N = [ "Hi" "Hu" "Allo"];
+H = [ "Hello" "Bonjour" "Allo"
       "Holà"  "Allo"  "Hallo"
       "Hi"    "Hé"    "Salud" ];
-[nb, loc] = members(A, S, %t)
+[nb, loc] = members(N, H, "last")
+
+// By rows:
+ H = [
+  3  3  0
+  4  1  0
+  2  0  3
+  0  1  4
+  3  4  3
+  0  4  1
+  3  1  0
+  ];
+ N = [
+  1  2  3
+  0  1  4
+  3  0  3
+  4  1  0
+  2  0  2
+  ];
+ N, H
+ [nb, loc] = members(N, H, "rows")
+ [nb, loc] = members(N, H, "rows","last")
+ [nb, loc] = members(N, H, "rows","shuffle") // [4 1 0], [0 1 4] and [0 4 1] are considered the same
+
+// By columns: From N and H defined above:
+ N = N.', H = H.'
+ [nb, loc] = members(N, H, "cols", "shuffle")
+
 ]]></programlisting>
     </refsection>
     <refsection role="see also">
         <title>See Also</title>
         <simplelist type="inline">
             <member>
-                <link linkend="dsearch">dsearch</link>
-            </member>
-            <member>
-                <link linkend="intersect">intersect</link>
+                <link type="scilab" linkend="scilab.help/dsearch">dsearch</link>
             </member>
             <member>
-                <link linkend="unique">unique</link>
+                <link type="scilab" linkend="scilab.help/intersect">intersect</link>
             </member>
             <member>
-                <link linkend="gsort">gsort</link>
+                <link type="scilab" linkend="scilab.help/find">find</link>
             </member>
             <member>
-                <link linkend="union">union</link>
+                <link type="scilab" linkend="scilab.help/vectorfind">vectorfind</link>
             </member>
         </simplelist>
     </refsection>
@@ -139,7 +205,7 @@ S = [ "Hello" "Bonjour" "Allo"
         <revhistory>
             <revision>
                 <revnumber>5.5.0</revnumber>
-                <revremark>Function members introduced.</revremark>
+                <revremark>members() function introduced.</revremark>
             </revision>
         </revhistory>
     </refsection>
index 494b1ba..500dbb9 100644 (file)
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2009 - Université du Maine - Samuel Gougeon
+ * Copyright (C) 2013 - Samuel GOUGEON
+ * Copyright (C) 2009 - Université du Maine - Samuel GOUGEON
  *
  * 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
  *
  -->
-<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="members" xml:lang="en">
+<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="members" xml:lang="fr">
     <refnamediv>
         <refname>members</refname>
-        <refpurpose>retourne des vecteurs d'indices correspondants aux valeurs communes entre deux matrices
+        <refpurpose>dénombre (et localise) dans un tableau chaque élément ou ligne ou colonne d'un autre tableau
         </refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Séquence d'appel</title>
-        <synopsis>[nb [,loc]] = members(A, S [,last])</synopsis>
+        <synopsis>
+            [nb [,loc]] = members(N, H)
+            [nb [,loc]] = members(N, H, "last")
+            [nb [,loc]] = members(N, H, "rows"|"cols")
+            [nb [,loc]] = members(N, H, "rows"|"cols", "last")
+            [nb [,loc]] = members(N, H, "rows"|"cols", "shuffle")
+            [nb [,loc]] = members(N, H, "rows"|"cols", "shuffle", "last")
+        </synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Paramètres</title>
         <variablelist>
             <varlistentry>
-                <term>A</term>
+                <term>N</term>
                 <listitem>
-                    <para>matrice ou hypermatrice de booléens, entiers, réels, complexes, polynômes ou chaînes de caractères</para>
+                    <para>
+                        Matrice ou hypermatrice dont les éléments, rangées ou colonnes doivent être recherchés. Il peut s'agir de booléens, d'entiers encodés, de nombres décimaux réels ou complexes, de polynômes ou de textes. En mode "rows" ou "cols", l'hypermatrice n'est pas acceptée. Un élément donné (ou une rangée ou colonne) peut apparaitre plusieurs fois dans <literal>N</literal>.
+                    </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>S</term>
+                <term>H</term>
                 <listitem>
                     <para>
-                        matrice ou hypermatrice du même type que <literal>A</literal>
+                        Matrice ou hypermatrice scrutée, de même type que <literal>N</literal>. En mode "rows" / "cols", l'hypermatrice n'est pas acceptée, et <literal>N</literal> et <literal>H</literal> doivent avoir le même nombre de colonnes / lignes.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>last</term>
+                <term>Options :</term>
                 <listitem>
-                    <para>booléen</para>
+                    <para>Une à 3 options peuvent être indiquées après H, sans ordre particulier :
+                        <variablelist>
+                            <varlistentry>
+                                <term>"last"</term>
+                                <listitem>
+                                    <para>
+                                        Lorsque la localisation dans <literal>H</literal> des éléments de <literal>N</literal> est retournée via le paramètre de sortie <literal>loc</literal>, par défaut les positions des 1ères occurences dans <literal>H</literal> sont retournées, élément par élément de N. Si <literal>"last"</literal> est indiqué, les positions retournées sont celles des dernières occurences dans <literal>H</literal>.
+                                    </para>
+                                </listitem>
+                            </varlistentry>
+                            <varlistentry>
+                                <term>"rows", "cols"</term>
+                                <listitem>
+                                    <para>
+                                        Par défaut, chaque élément individuel <literal>N(i, j, ..)</literal> de <literal>N</literal> est recherché dans <literal>H</literal>. Si <literal>"rows"</literal> est indiquée, chaque rangée de <literal>N</literal> est recherchée parmi les rangées de <literal>H</literal>. De même, si <literal>"cols"</literal> est indiquée, chaque colonne de <literal>N</literal> est recherchée parmi les colonnes de <literal>H.</literal>.
+                                    </para>
+                                </listitem>
+                            </varlistentry>
+                            <varlistentry>
+                                <term>"shuffle"</term>
+                                <listitem>
+                                    <para>
+                                        En mode <literal>"rows"</literal> ou <literal>"cols"</literal>, par défaut l'ordre des éléments d'une rangée ou d'une colonne est pris en compte : par exemple, <literal>[ 7 3 5 ]</literal> dans <literal>N</literal> et <literal>[ 3 5 7]</literal> dans <literal>H</literal> ne correspondront pas. Lorsque l'option <literal>"shuffle"</literal> est utilisée, toute permutation de --disons--<literal>[3 5 7]</literal> sera reconnue dans H comme correspondant à la rangée <literal>[3 5 7]</literal> dans <literal>N</literal>. Cette option est ignorée pour les polynômes.
+                                    </para>
+                                </listitem>
+                            </varlistentry>
+                        </variablelist>
+                    </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>nb</term>
                 <listitem>
                     <para>
-                        matrice de réels de même taille que <literal>A</literal>
+                        En mode normal : <literal>nb(i, j, ..)</literal> (décimaux) retourne le nombre d'occurences dans <literal>H</literal> de <literal>N(i, j, ..)</literal>. <literal>nb</literal> et <literal>N</literal> ont le même format. Si <literal>H</literal> est vide [], une matrice de zéros est retournée. Si <literal>N</literal> est vide, la matrice vide <literal>[]</literal> est retournée.
+                    </para>
+                    <para>
+                        En mode <literal>"rows"</literal> ou <literal>"cols"</literal> : <literal>nb</literal> est un vecteur ligne de décimaux avec autant d'élements que <literal>N</literal> a de rangées ou colonnes. <literal>nb(i)</literal> retourne le nombre d'occurences dans <literal>H(1:$, :)</literal> de <literal>N(i, :)</literal> (ou de <literal>N(:, i)</literal> dans <literal>H(:, 1:$)</literal> ).
                     </para>
                 </listitem>
             </varlistentry>
                 <term>loc</term>
                 <listitem>
                     <para>
-                        matrice de réels de même taille que <literal>A</literal>
+                        En mode normal : <literal>loc</literal> et <literal>N</literal> ont le même format. <literal>loc(i, j, ..)</literal> retourne le n°(linéarisé) dans <literal>H</literal> le plus petit auquel <literal>N(i, j, ..)</literal> advient : <literal>H(loc(i, j, ..))==N(i, j, ..)</literal>. Si l'option <literal>"last"</literal> est utilisée, le n° le plus grand vérifiant la même condition est retourné à la place. Si <literal>N(i, j, ..)</literal> n'est pas présent dans <literal>H</literal>, <literal>loc(i, j, ..)</literal> est mis à <literal>0</literal>.
+                    </para>
+                    <para>
+                        En mode <literal>"rows"</literal> ou <literal>"cols"</literal> : <literal>loc</literal> est un vecteur ligne de décimaux, avec autant d'éléments que <literal>N</literal> a respectivement de rangées ou de colonnes. <literal>loc(i)</literal> retourne le n° de la 1ère ligne <literal>H(loc(i), :)</literal> identifiable à <literal>N(i, :)</literal> (ou le n° de la 1ère colonne <literal>H(:, loc(i))</literal> identifiable à <literal>N(:, i)</literal>). Si l'option <literal>"shuffle"</literal> est en outre utilisée, l'ordre des éléments de <literal>N(i, :)</literal> est ignoré et toutes les permutations de <literal>N(i, :)</literal> identifiables en rangées de <literal>H</literal> sont considérées.
                     </para>
                 </listitem>
             </varlistentry>
     <refsection>
         <title>Description</title>
         <para>
-            <literal>nb = members(A, S)</literal> retourne le nombre d'occurrences de <literal>A</literal> dans <literal>S</literal>.
-            Après <literal>[nb, loc] = members(A, S, last)</literal>,
-            <literal>loc(i, j)</literal> contient l'indice linéraire dans <literal>S</literal> de la première occurrence de <literal>A(i, j)</literal>.
-            Si <literal>last==%t</literal>, l'index de la dernière occurrence est retourné.
-            <literal>loc(i, j)</literal> retourne zéro si <literal>A(i, j)</literal> n'est pas trouvé.
-            <literal>%inf</literal> et <literal>-%inf</literal> sont supportés dans <literal>A</literal> et <literal>S</literal>.
-            <literal>%nan</literal> ne sont supportés que dans <literal>A</literal>.
+            <literal>nb = members(N, H [,"rows"|"cols"])</literal> retourne le nombre d'occurences de chaque élément ou rangée ou colonne de <literal>N</literal> identifiables dans <literal>H</literal>. Si aucune correspondance n'est trouvée, 0 est retourné pour le composant considéré.
+            La position dans <literal>H</literal> de la 1ère (par défaut) ou de la dernière (avec <literal>"last"</literal>) occurence des <literal>N(i, j, ...)</literal> peut être obtenue via la seconde variable de sortie <literal>loc</literal>.
+            Si des rangées ou colonnes correspondantes sont recherchées, l'ordre de leurs éléments peut être ignoré en utilisant l'option <literal>"shuffle"</literal>.
         </para>
         <para>
-            Quand <literal>A</literal> est un vecteur de réels ou entiers et <literal>S</literal> est un vecteur de réels ou entiers strictement croissant,
-            <literal>dsearch(A, S, "d")</literal> est préféré à <literal>members(A, S)</literal>.
+            Les valeurs spéciales <literal>%inf</literal> et <literal>-%inf</literal> sont admises dans <literal>N</literal> comme dans <literal>H</literal>.
+            <literal>%nan</literal> est toujours admis dans <literal>N</literal>, mais pas dans <literal>H</literal> en mode normal.
+        </para>
+        <para>
+            En mode normal (élément par élément), members(..) utilise la fonction <link type="scilab" linkend="scilab.help/dsearch">dsearch(..)</link> afin de traiter efficacement les tableaux de booléens, d'entiers encodés (de tous formats : 8-16-32 bits signés ou non), ou de nombres réels. Le traitement des tableaux de nombres complexes, de polynômes ou de textes est réalisé par un algorithme plus lent et gourmand en mémoire vive. Pour de meilleures performances avec ces types de données, en particulier si <literal>N</literal> ou/et <literal>H</literal> sont de grandes tailles, l'utilisateur peut préalablement augmenter la taille de la pile dévolue aux variables en utilisant <link type="scilab" linkend="scilab.help/stacksize">stacksize(..)</link>. Lorsque le traitement est long, une jauge de progression est affichée.
         </para>
     </refsection>
     <refsection>
         <title>Exemples</title>
         <programlisting role="example"><![CDATA[
-A = [1 8 4 5 2 1];
-S = [9 7 4 2 1 4];
-
-[nb, loc] = members(A, S, %t)
-// Retourne loc = [5 0 6 0 4 5] parce-que la dernière occurrence dans S du troisième élément de A (qui est 4) est en sixième position
+N = [1 8 4 5 2 1];
+H = [9 7 4 2 1 4];
 
-[nb, loc] = members(A, S, %f)
-// Retourne loc = [5 0 3 0 4 5] parce-que la première occurrence dans S du troisième élément de A (qui est 4) est en troisième position
+[nb, loc] = members(N, H, "last")
+// Retourne nb  = [1 0 2 0 1 1] : par exemple, 4 apparait 2 fois dans H.
+// Et       loc = [5 0 6 0 4 5] : la dernière occurence de 4 figure en 6ème position dans H
 
-// Dans les deux cas, nb = [1 0 2 0 1 1] parce-que, par exemple, le nombre d'occurrences du troisième élément de A dans S est 2.
+[nb, loc] = members(N, H)
+// Retourne loc = [5 0 3 0 4 5] : la 1ère occurence de 4 figure en 3ème position dans H
 
-// Avec des hypermatrices. En réutilisant A et S :
-A = matrix(A, [3 1 2]);
-S = matrix(S, [3 1 2]);
-[nb, loc] = members(A, S, %T)
+// avec des hypermatrices. Avec N et H déclarées ci-dessus :
+N = matrix(N, [3 1 2]);
+H = matrix(H, [3 1 2]);
+[nb, loc] = members(N, H, "last")
 
-// Avec des entiers :
-A = int8(grand(3, 2, "uin", -5, 5));
-S = int8(grand(4, 4, "uin", -5, 5));
-[nb, loc] = members(A, S)
+// Avec des entiers encodés :
+N = int8(grand(3, 2, "uin", -5, 5));
+H = int8(grand(4, 4, "uin", -5, 5));
+[nb, loc] = members(N, H)
 
-// Avec des polynômes (les coefficients complexes sont acceptés) :
+// Avec des polynômes (à coefficients éventuellement complexes) :
 z = %z;
-A = [z (1-z)^2 ; -4 %i*z ];
-S = [2  %i*z -z  3-z  z  z^3 z];
-[nb, loc] = members(A, S)
+N = [z (1-z)^2 ; -4 %i*z ];
+H = [2  %i*z -z  3-z  z  z^3 z];
+[nb, loc] = members(N, H)
 
-// Avec du texte :
-A = [ "Hi" "Hu" "Allo"];
-S = [ "Hello" "Bonjour" "Allo"
+// Avec des matrices de textes :
+N = [ "Hi" "Hu" "Allo"];
+H = [ "Hello" "Bonjour" "Allo"
       "Holà"  "Allo"  "Hallo"
       "Hi"    "Hé"    "Salud" ];
-[nb, loc] = members(A, S, %t)
+[nb, loc] = members(N, H, "last")
+
+// Recherche de rangées :
+ H = [
+  3  3  0
+  4  1  0
+  2  0  3
+  0  1  4
+  3  4  3
+  0  4  1
+  3  1  0
+  ];
+ N = [
+  1  2  3
+  0  1  4
+  3  0  3
+  4  1  0
+  2  0  2
+  ];
+ N, H
+ [nb, loc] = members(N, H, "rows")
+ [nb, loc] = members(N, H, "rows","last")
+ [nb, loc] = members(N, H, "rows","shuffle") // [4 1 0], [0 1 4] et [0 4 1] sont associées
+
+// Recherche de colonnes, en utilisant N et H définies ci-dessus :
+ N = N.', H = H.'
+ [nb, loc] = members(N, H, "cols", "shuffle")
+
 ]]></programlisting>
     </refsection>
     <refsection role="see also">
         <title>Voir aussi</title>
         <simplelist type="inline">
             <member>
-                <link linkend="dsearch">dsearch</link>
-            </member>
-            <member>
-                <link linkend="intersect">intersect</link>
+                <link type="scilab" linkend="scilab.help/dsearch">dsearch</link>
             </member>
             <member>
-                <link linkend="unique">unique</link>
+                <link type="scilab" linkend="scilab.help/intersect">intersect</link>
             </member>
             <member>
-                <link linkend="gsort">gsort</link>
+                <link type="scilab" linkend="scilab.help/find">find</link>
             </member>
             <member>
-                <link linkend="union">union</link>
+                <link type="scilab" linkend="scilab.help/vectorfind">vectorfind</link>
             </member>
         </simplelist>
     </refsection>
@@ -140,7 +205,7 @@ S = [ "Hello" "Bonjour" "Allo"
         <revhistory>
             <revision>
                 <revnumber>5.5.0</revnumber>
-                <revremark>Fonction members introduite.</revremark>
+                <revremark>Introduction de la fonction members()</revremark>
             </revision>
         </revhistory>
     </refsection>
index 177c795..b691b49 100644 (file)
@@ -1,5 +1,6 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2009,2013 - Université du Maine - Samuel Gougeon
+// Copyright (C) 2013 - Samuel GOUGEON
+// Copyright (C) 2009 - Université du Maine - Samuel GOUGEON
 //
 // This file must be used under the terms of the CeCILL.
 // This source file is licensed as described in the file COPYING, which
 // are also available at
 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
 
-function [nb, loc] = members(A, S, last)
+function [nb, loc] = members(A, S, varargin)
+    //
+    // Looks for how many times in S each element of A occurs
+    // Looks for how many rows of S match each row of A
+    // Can return the position in S of each respective first or last match.
+    //
+    // Calling sequence:
+    // -------------------------
+    // [nb [,loc]] = members(A, S)
+    // [nb [,loc]] = members(A, S, "last")
+    // [nb [,loc]] = members(A, S, "rows"|"cols")
+    // [nb [,loc]] = members(A, S, "rows"|"cols", "last")
+    // [nb [,loc]] = members(A, S, "rows"|"cols", "shuffle")
+    // [nb [,loc]] = members(A, S, "rows"|"cols", "shuffle", "last")
     //
     // Input / Output arguments:
     // -------------------------
     // A   : Matrix or hypermatrix of booleans, integers, reals, complexes, polynomials or strings:
     //       entities (needles) to search in S (haystack).
     // S   : Matrix or hypermatrix of same datatype as A
-    // last: Scalar boolean
+    // "last": litteral keyword (optional): if it is provided, indices of last
+    //       occurrences are returned instead of for the first ones.
+    // "rows": litteral keyword (optional). if it is provided, each row of A
+    //       is searched as a whole, among rows of S.
+    // "cols": litteral keyword (optional). if it is provided, each column of A
+    //       is searched as a whole, among columns of S.
+    //       "rows" and "cols" options are exclusive. If both are specified,
+    //       only the last specified one is considered.
+    // "shuffle": litteral keyword (optional), modifying the "rows" or "cols"
+    //       option. If it is provided, detection of -- say -- A rows in S is
+    //       performed without respect of the order of elements in each row.
+    //       This option is ignored when processing polynomials.
+    //
+    // NORMAL mode: neither "rows" nor "cols" is set. Then,
     // nb  : Matrix of reals: same sizes as A
     //       nb(i, j, ...): number of occurrences of A(i, j, ...) in S.
     // loc : Matrix of reals: same sizes as A
     //       loc(i, j, ...): linear index in S of the first occurrence of A(i, j, ...).
-    //       If last==%t, the index of the last occurrence is returned instead.
+    //       If "last" is set, the index of the last occurrence is returned instead.
     //       loc(i, j, ...) returns zero if A(i, j, ...) is not found.
+    // ROW-WISE mode:
+    // nb  : Row of reals with size(A, 1) elements
+    //       nb(i): number of occurrences of A(i, :) found as rows of S
+    // loc : Row of reals with size(A, 1) elements
+    //       loc(i): index of the first row in S which matches A(i, :).
+    //       If "last" is set, the index of the last occurrence is returned instead.
+    //       loc(i, j, ...) returns zero if A(i, :) is not found.
+    // COLUMN-WISE mode:
+    //  same as above. nb and loc are row vectors with size(A, 2) elements.
     //
-    // %inf, -%inf values are supported in A as well as in S.
-    // %nan are supported only in A.
+    // REMARK: %inf, -%inf values are supported in A as well as in S.
+    //
+    // LIMITATION: in normal element-wise mode, %nan are supported only in A.
     //
     // Examples:
     // ---------
     // a) with reals:
-    // N = [ 7  3
-    //     %inf 0
-    //     %nan 1 ];
-    // H = [ 5   8    0   4
-    //       3   4    7   7
-    //       3 %inf %inf  2
-    //       7   5    5   8 ];
-    // [nb, loc] = members(N, H)
-    // [nb, loc] = members(N, H, %T)
+    //   N = [ 7  3
+    //       %inf 0
+    //       %nan 1 ];
+    //   H = [ 5   8    0   4
+    //         3   4    7   7
+    //         3 %inf %inf  2
+    //         7   5    5   8 ];
+    //   [nb, loc] = members(N, H)
+    //   [nb, loc] = members(N, H, "last")
     //
     // b) with hypermatrices, from previous N and H:
-    // N = matrix(N, [3 1 2]);
-    // H = matrix(H, [4 2 2]);
-    // [nb, loc] = members(N, H, %T)
+    //   N = matrix(N, [3 1 2]);
+    //   H = matrix(H, [4 2 2]);
+    //   [nb, loc] = members(N, H, "last")
     //
     // c) with integers:
-    // N = int8(grand(3, 2, "uin", -5, 5));
-    // H = int8(grand(4, 4, "uin", -5, 5));
-    // [nb, loc] = members(N, H)
+    //   N = int8(grand(3, 2, "uin", -5, 5));
+    //   H = int8(grand(4, 4, "uin", -5, 5));
+    //   [nb, loc] = members(N, H)
     //
     // d) with polynomials (complex coefficients are accepted):
-    // z = %z;
-    // N = [z (1-z)^2 ; -4 %i*z ];
-    // H = [2  %i*z -z  3-z  z  z^3 z];
-    // [nb, loc] = members(N, H)
+    //   z = %z;
+    //   N = [z (1-z)^2 ; -4 %i*z ];
+    //   H = [2  %i*z -z  3-z  z  z^3 z];
+    //   [nb, loc] = members(N, H)
     //
     // e) with text:
-    // N = [ "Hi" "Hu" "Allo"];
-    // H = [ "Hello" "Bonjour" "Allo"
-    //       "Holà"  "Allo"  "Hallo"
-    //       "Hi"    "Hé"    "Salud" ];
-    // [nb, loc] = members(N, H, %t)
+    //   N = [ "Hi" "Hu" "Allo"];
+    //   H = [ "Hello" "Bonjour" "Allo"
+    //         "Holà"  "Allo"  "Hallo"
+    //         "Hi"    "Hé"    "Salud" ];
+    //   [nb, loc] = members(N, H, "last")
+    //
+    // f) by rows:
+    //   H = [
+    //    3  3  0
+    //    4  1  0
+    //    2  0  3
+    //    0  1  4
+    //    3  4  3
+    //    0  1  4
+    //    3  1  0 ];
+    //   N = [
+    //    1 2 3
+    //    0 1 4
+    //    3 0 3
+    //    4 1 0
+    //    2 0 2 ];
+    //   N, H
+    //   [nb, loc] = members(N, H, "rows")
+    //   [nb, loc] = members(N, H, "rows", "last")
+    //   [nb, loc] = members(N, H, "rows", "shuffle")
+    //
+    // g) by columns, from previous N and H:
+    //   N = N.', H = H.'
+    //   [nb, loc] = members(N, H, "cols", "shuffle")
 
     [lhs, rhs] = argn();
+    nb = [];
+    if rhs == 0 then
+        head_comments("members");
+        return
+    end
     if rhs < 2 then
         error(msprintf(gettext("%s: Wrong number of input argument(s): at least %d expected.\n"), "members", 2));
     end
-    if rhs == 2 then
-        last = %f;
-    end
     if A == [] then
-        nb = [];
         if lhs > 1 then
             loc = [];
         end
@@ -83,168 +145,273 @@ function [nb, loc] = members(A, S, last)
         return
     end
 
+    sA = size(A);
     type_A = type(A(:));
     type_S = type(S(:));
-    if type_A <> type_S then
+    if type_A ~= type_S then
         error(msprintf(gettext("%s: Wrong type for input argument #%d: expected same type as first argument.\n"), "members", 2));
     end
-    if and(type_A <> [1 2 4 8 10]) then
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: Matrix of Integers, Reals, Complexes, Booleans, Polynomials or Strings expected.\n"), "members", 1));
+    if and(type_A ~= [1 2 4 8 10]) then
+        error(msprintf(gettext("%s: Wrong type for input argument #%d: Matrix of encoded-Integers, Reals, Complexes, Booleans, Polynomials or Strings expected.\n"), "members", 1));
     end
-    if and(type_S <> [1 2 4 8 10]) then
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: Matrix of Integers, Reals, Complexes, Booleans, Polynomials or Strings expected.\n"), "members", 2));
+    if and(type_S ~= [1 2 4 8 10]) then
+        error(msprintf(gettext("%s: Wrong type for input argument #%d: Matrix of encoded-Integers, Reals, Complexes, Booleans, Polynomials or Strings expected.\n"), "members", 2));
     end
     if or(isnan(S)) then
         error(msprintf(gettext("%s: Wrong value for argument #%d: Must not contain NaN.\n"), "members", 2));
     end
-    if type(last) <> 4 then
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: Boolean matrix expected.\n"), "members", 3));
-    end
-    if ~isscalar(last) then
-        error(msprintf(gettext("%s: Wrong size for input argument #%d: Scalar expected.\n"), "members", 3));
+
+    // Checking optional flags (if any):
+    last = %f;
+    direction = "";
+    shuffle = %f;
+    shuffle_temp = %f;
+    if  rhs > 2 then
+        i = 2;
+        for option=varargin
+            i = i + 1;
+            if typeof(option) ~= "string" | ~isscalar(option) then
+                msg = _("%s: Wrong type for argument #%d: Scalar string expected => option ignored.\n");
+                warning(msprintf(msg, "members", i))
+                continue
+            end
+            o = convstr(option, "l");
+            if o == "last" then
+                last = %t;
+            elseif o == "rows"
+                direction = "rows";
+            elseif o == "cols"
+                direction = "cols";
+            elseif o == "shuffle"
+                shuffle_temp = %t;
+            else
+                msg = _("%s: Unknown option ""%s"" => ignored.\n");
+                warning(msprintf(msg, "members", o))
+            end
+        end
+        if shuffle_temp == %t then
+            if direction == "" then
+                msg = _("%s: Option ""%s"" only relevant for ""%s"" and ""%s"" modes => ignored.\n");
+                warning(msprintf(msg, "members", "shuffle", "rows", "cols"))
+            else
+                shuffle = %t;
+            end
+        end
     end
 
     // ------------------------------------------------------------------------
 
-    // Reals: special faster processing with dsearch().
-    //  %inf, -%inf are supported in A and S. %nan are only supported in A.
-    //  Processing integers and strings requires bugs 6305 & 12778 to be fixed.
+    // Usual processing: searching for matching individual components
+    // --------------------------------------------------------------
+    if direction == "" then
+        // Reals: special faster processing with dsearch().
+        //  %inf, -%inf are supported in A and S. %nan are only supported in A.
+        //  Processing integers and strings requires bugs 6305 & 12778 to be fixed.
 
-    if type_A == 8 then   // Convert integers into reals in order to use dsearch
-        A = double(A);
-        S = double(S);
-    end
-    if type_A == 1 & isreal(A) & isreal(S) then
-        S = S(:);
-        if last then
-            S = S($:-1:1);
+        if type_A == 8 then   // Convert integers into reals in order to use dsearch
+            A = double(A);
+            S = double(S);
+        elseif type_A == 4 then   // Convert booleans into reals
+            A = bool2s(A);
+            S = bool2s(S);
         end
-        [Su, kS] = unique(S);
-        [i, nbS] = dsearch(S, Su, "d");
-
-        I = dsearch(A(:), Su, "d");
-        k = find(I~=0);
-        nb = I;
-        nb(k) = nbS(I(k));
-        nb = matrix(nb, size(A));
-        if lhs > 1 then
-            loc = I;
-            loc(k) = kS(I(k));
+        if type_A == 1 & isreal(A) & isreal(S) then
+            S = S(:);
             if last then
-                loc(k) = length(S)-loc(k)+1;
+                S = S($:-1:1);
             end
-            loc = matrix(loc, size(A));
-        end
-        // ------------------------------------------------------------------------
-    else
-        // Other cases : polynomials, text, complexes
-        // ==========================================
-        sA = size(A);
-        LA = size(A, "*");
-        LS = size(S, "*");
-        A = A(:);
-        if ~last then
-            S = S($:-1:1);
-        end
+            [Su, kS] = unique(S);
+            [i, nbS] = dsearch(S, Su, "d");
 
-        // Slices may be needed in case of memory overflow
-        //
-        // Function returning the memory space in [bytes] occupied by each
-        //  querried variable. If a variable exists in several contexts,
-        //  only the last created one is considered
-        function varargout = varspace(varargin)
-            [Ln, Ls] = who("local");
-            vs = list();
-            for vn = varargin
-                i = find(Ln==vn);
-                if i ~= [] then
-                    vs($+1) = Ls(i(1))*8;
-                else
-                    vs($+1) = 0;
+            I = dsearch(A(:), Su, "d");
+            k = find(I~=0);
+            nb = I;
+            nb(k) = nbS(I(k));
+            nb = matrix(nb, size(A));
+            if lhs > 1 then
+                loc = I;
+                loc(k) = kS(I(k));
+                if last then
+                    loc(k) = length(S)-loc(k)+1;
                 end
+                loc = matrix(loc, size(A));
             end
-            varargout = vs;
-        endfunction
-        // -----------------------------------
-        // Memory space needed to process a i:j slice of A:
-        // nb  : j doubles (occupied at the end)
-        // loc : j doubles (occupied at the end)
-        // tmp : LS * (j-i+1) doubles needed
-        // A2  : LS * mem(A(i:j)) needed
-        // S2  : mem(S)*(j-i+1) needed
-
-        // Function setting the thickness of the slice, according to the
-        //    available and needed memory
-        function j = set_j(i, LS, memS, rA)
-            // rA : remaining unprocessed part of A
-            [memA2, memS2, memtmp] = varspace("A2", "S2", "tmp");
-            // Available memory [bytes]:
-            m = stacksize();
-            avail = (m(1)-m(2))*8 + memA2 + memS2 + memtmp -16*(i-1); // [bytes]
-            avail = 0.15*avail;  // A lot of memory is used as Intermediate memory
-            // Diadic loop on e = j-i+1 (slice's thickness):
-            // Init
-            e = size(rA, "*");
-            Vtest = rA(1:e);
-            memrA = varspace("Vtest");   // [bytes]
-            // Loop fitting the slice's thickness e for the available memory
-            while (e*(memS+8*LS+16)+LS*memrA > avail & e > 1)
-                e = ceil(e/2);   // Remaining thickness => divided by 2
+            // ------------------------------------------------------------------------
+        else
+            // Other cases : polynomials, text, complexes
+            // ==========================================
+            LA = size(A, "*");
+            LS = size(S, "*");
+            A = A(:);
+            if ~last then
+                S = S($:-1:1);
+            end
+
+            // Slices may be needed in case of memory overflow
+            //
+            // Function returning the memory space in [bytes] occupied by each
+            //  querried variable. If a variable exists in several contexts,
+            //  only the last created one is considered
+            function varargout = varspace(varargin)
+                [Ln, Ls] = who("local");
+                vs = list();
+                for vn = varargin
+                    i = find(Ln==vn);
+                    if i ~= [] then
+                        vs($+1) = Ls(i(1))*8;
+                    else
+                        vs($+1) = 0;
+                    end
+                end
+                varargout = vs;
+            endfunction
+            // -----------------------------------
+            // Memory space needed to process a i:j slice of A:
+            //   nb  : j doubles (occupied at the end)
+            //   loc : j doubles (occupied at the end)
+            //   tmp : LS * (j-i+1) doubles needed
+            //   A2  : LS * mem(A(i:j)) needed
+            //   S2  : mem(S)*(j-i+1) needed
+
+            // Function setting the thickness of the slice, according to the
+            //    available and needed memory
+            function j = set_j(i, LS, memS, rA)
+                // rA : remaining unprocessed part of A
+                [memA2, memS2, memtmp] = varspace("A2", "S2", "tmp");
+                // Available memory [bytes]:
+                m = stacksize();
+                avail = (m(1) - m(2))*8 + memA2 + memS2 + memtmp - 16*(i-1); // [bytes]
+                avail = 0.15*avail;  // A lot of memory is used as Intermediate memory
+                // Diadic loop on e = j-i+1 (slice's thickness):
+                // Init
+                e = size(rA, "*");
                 Vtest = rA(1:e);
-                memrA = varspace("Vtest");
+                memrA = varspace("Vtest");   // [bytes]
+                // Loop fitting the slice's thickness e for the available memory
+                while e*(memS+8*LS+16)+LS*memrA > avail & e > 1
+                    e = ceil(e/2);   // Remaining thickness => divided by 2
+                    Vtest = rA(1:e);
+                    memrA = varspace("Vtest");
+                end
+                if (e*(memS+8*LS+16)+LS*memrA > avail) then
+                    msg = _("%s: not enough memory to proceed\n");
+                    error(sprintf(msg, "members"));
+                end
+                j = i+e-1;
+            endfunction
+
+            memS = varspace("S");  // [bytes]
+
+            // Starting and ending indices in A for the current slice
+            i = 1;   // Starting index: initialization
+            j = 0;   // Ending index: initialization
+            while j<LA      // Slicing loop
+                // Setting next j (=> thickness of the slice = j-i+1)
+                j = set_j(i, LS, memS, A(i:$))
+
+                // Progression bar
+                if j < LA then
+                    if isdef("waitH") then
+                        waitbar(j/LA, waitH);
+                    elseif j/LA < 0.4   // Else: too few steps => not worthwhile
+                        waitH = waitbar(j/LA);
+                    end
+                end
+
+                A2 = repmat(A(i:j), 1, LS);
+                S2 = repmat(S(:).', j-i+1, 1);
+
+                tmp = bool2s(A2==S2);
+                nb(i:j) = sum(tmp, "c");
+                if lhs > 1 then
+                    tmp = tmp.* ( (1:LS) .*. ones(j-i+1, 1) );
+                    loc(i:j) = max(tmp, "c");
+                end
+                i = j+1;
+                // End of slice processing
             end
-            if (e*(memS+8*LS+16)+LS*memrA > avail) then
-                msg = _("%s: not enough memory to proceed");
-                error(sprintf(msg, "members"));
+            // Deleting the waitbar (if any) and clearing transient variables
+            clear A2 S2 tmp
+            if isdef("waitH") then
+                delete(waitH);
             end
-            j = i+e-1;
-        endfunction
-
-        memS = varspace("S");  // [bytes]
-
-        // Starting and ending indices in A for the current slice
-        i = 1;   // Starting index: initialization
-        j = 0;   // Ending index: initialization
-        while j < LA      // Slicing loop
-            // Setting next j (=> thickness of the slice = j-i+1)
-            j = set_j(i, LS, memS, A(i:$));
-
-            // Progression bar
-            if j < LA then
-                if isdef("waitH") then
-                    waitbar(j/LA, waitH);
-                elseif j/LA < 0.4   // Else: too few steps => not worthwhile
-                    waitH = waitbar(j/LA);
+
+            // Final operations on the overall result(s)
+            nb = matrix(nb, sA);
+            if lhs > 1
+                if ~last
+                    k = loc~=0;
+                    loc(k) = LS - loc(k) + 1;
                 end
+                loc = matrix(loc, sA);
             end
+        end
+        // ========================================================================
+
+    else
+        // Row-wise processing: searching for matching rows
+        // ------------------------------------------------
 
-            A2 = repmat(A(i:j), 1, LS);
-            S2 = repmat(S(:).', j-i+1, 1);
+        // Additionnal input checking:
+        A = squeeze(A);
+        if ~ismatrix(A) then
+            msg = _("%s: Wrong type for argument #%d: Matrix expected.\n"); // error #209
+            error(msprintf(msg, "members", 1))
+        end
 
-            tmp = bool2s(A2==S2);
-            nb(i:j) = sum(tmp, "c");
-            if lhs > 1 then
-                tmp = tmp.* ( (1:LS) .*. ones(j-i+1, 1) );
-                loc(i:j) = max(tmp, "c");
-            end
-            i = j+1;
-            // End of slice processing
+        S = squeeze(S);
+        if ~ismatrix(S) then
+            msg = _("%s: Wrong type for argument #%d: Matrix expected.\n"); // error #209
+            error(msprintf(msg, "members", 2))
         end
-        // Deleting the waitbar (if any) and clearing transient variables
-        clear A2 S2 tmp
-        if isdef("waitH") then
-            delete(waitH);
+
+        if direction == "rows" & size(A, 2) ~= size(S, 2) then
+            msg = _("%s: Incompatible input arguments #%d and #%d: Same number of columns expected.\n");
+            error(msprintf(msg, "members", 1, 2))
+        elseif direction == "cols" & size(A, 1) ~= size(S, 1) then
+            msg = _("%s: Incompatible input arguments #%d and #%d: Same number of rows expected.\n");
+            error(msprintf(msg, "members", 1, 2))
+        end
+
+        // Column-wise = Row-wise after transposition
+        if direction == "cols" then
+            A = A.';
+            S = S.';
         end
 
-        // Final operations on the overall result(s)
-        nb = matrix(nb, sA);
-        if lhs > 1
-            if ~last
-                k = loc~=0;
-                loc(k) = LS - loc(k) + 1;
+        // If "shuffle" is set, we first sort elements along each row of A and S
+        if  type_A ~= 2 & shuffle then    // Polynomials are not sortable
+            A = gsort(A, "c", "i");
+            S = gsort(S, "c", "i");
+        end
+
+        // Pre-Processing: Preparing initial chart of double indices
+        nLA = size(A, 1);  // Number of rows of A
+        nLS = size(S, 1);  // Number of rows of S
+        I1 = (1:nLA)' .*. ones(nLS, 1); // indices of A rows, grouped by S rows
+        I2 = ones(nLA, 1) .*. (1:nLS)';  // set of S rows indices, replicated by the number of A rows
+        IND = [I1 I2];   // Column #1 gives index in A. column #2 gives index in S
+
+        // Processing: loop over columns
+        for k = 1:size(S, 2)
+            cA = A(IND(:, 1), k);
+            cS = S(IND(:, 2), k);
+            IND = IND(find(cA==cS), :);
+            if IND == [] then
+                break
             end
-            loc = matrix(loc, sA);
         end
+
+        // Post-processing
+        if last then
+            [nb, loc] = members((1:nLA)', IND(:, 1), "last");
+        else
+            [nb, loc] = members((1:nLA)', IND(:, 1));
+        end
+        k = find(loc~=0);
+        loc(k) = IND(loc(k), 2);
+        nb = nb';
+        loc = loc';
     end
 
 endfunction
index bf92370..54e2a18 100644 (file)
@@ -4,90 +4,93 @@
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
+//
 // <-- CLI SHELL MODE -->
+//
 // <-- ENGLISH IMPOSED -->
+//
 // Vectors
-[nb, loc] = members([], [], %t);
+[nb, loc] = members([], [], "last");
 assert_checkequal(nb , []);
 assert_checkequal(loc, []);
-[nb, loc] = members([], [], %f);
+[nb, loc] = members([], []);
 assert_checkequal(nb , []);
 assert_checkequal(loc, []);
-[nb, loc] = members([1 2], [3 4], %t);
+[nb, loc] = members([1 2], [3 4], "last");
 assert_checkequal(nb , [0 0]);
 assert_checkequal(loc, [0 0]);
-[nb, loc] = members([1 2], [3 4], %f);
+[nb, loc] = members([1 2], [3 4]);
 assert_checkequal(nb , [0 0]);
 assert_checkequal(loc, [0 0]);
-[nb, loc] = members([1 2; 3 4], [5 6; 7 8], %t);
+[nb, loc] = members([1 2; 3 4], [5 6; 7 8], "last");
 assert_checkequal(nb , [0 0; 0 0]);
 assert_checkequal(loc, [0 0; 0 0]);
-[nb, loc] = members([1 2; 3 4], [5 6; 7 8], %f);
+[nb, loc] = members([1 2; 3 4], [5 6; 7 8]);
 assert_checkequal(nb , [0 0; 0 0]);
 assert_checkequal(loc, [0 0; 0 0]);
-[nb, loc] = members(string([1 2; 3 4]), string([5 6; 7 8]), %t);
+[nb, loc] = members(string([1 2; 3 4]), string([5 6; 7 8]), "last");
 assert_checkequal(nb , [0 0; 0 0]);
 assert_checkequal(loc, [0 0; 0 0]);
-[nb, loc] = members(string([1 2; 3 4]), string([5 6; 7 8]), %f);
+[nb, loc] = members(string([1 2; 3 4]), string([5 6; 7 8]));
 assert_checkequal(nb , [0 0; 0 0]);
 assert_checkequal(loc, [0 0; 0 0]);
 A = [1 8 4 5 2 1];
 S = [9 7 4 2 1 4];
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 6 0 4 5]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 3 0 4 5]);
 // Strings
 A = 'a'+string(A);
 S = 's'+string(S);
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [0 0 0 0 0 0]);
 assert_checkequal(loc, [0 0 0 0 0 0]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [0 0 0 0 0 0]);
 assert_checkequal(loc, [0 0 0 0 0 0]);
 A = ["elt1" "elt3" "elt4"];
 S = ["elt5" "elt1" "elt3"];
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 1 0]);
 assert_checkequal(loc, [2 3 0]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 1 0]);
 assert_checkequal(loc, [2 3 0]);
 A = ["elt1" "elt3" "elt4"];
 S = ["elt5" "elt6" "elt2" "elt1" "elt3"];
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 1 0]);
 assert_checkequal(loc, [4 5 0]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 1 0]);
 assert_checkequal(loc, [4 5 0]);
 // Integers
 A = int16([1 8 4 5 2 1]);
 S = int16([9 7 4 2 1 4]);
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 6 0 4 5]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 3 0 4 5]);
 A = uint8([1 8 4 5 2 1]);
 S = uint8([9 7 4 2 1 4]);
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 6 0 4 5]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 3 0 4 5]);
 // Complexes
 A = [1 8 4 5 2 1]*%i;
 S = [9 7 4 2 1 4]*%i;
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 6 0 4 5]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 3 0 4 5]);
 // Matrices
@@ -121,10 +124,10 @@ nb_ref   = [ 1 2 3 2 3 ;
              2 4 4 4 4 ;
              4 2 1 3 0 ;
              2 0 3 1 2 ];
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
@@ -150,20 +153,20 @@ nb_ref   = [1 2 4 2 4 2 ;
             3 2 3 4 1 3 ;
             2 3 2 4 3 1 ;
             3 1 3 4 0 2 ];
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
 // Matrices of Integers
 A = uint32(A);
 S = uint32(S);
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
@@ -173,20 +176,20 @@ S = string(S_for_later);
 loc_ref  = loc_ref_for_later;
 loc2_ref = loc2_ref_for_later;
 nb_ref   = nb_ref_for_later;
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
 // Matrices of Complexes
 A = A_for_later*%i;
 S = S_for_later*%i;
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
@@ -197,10 +200,10 @@ S = S_for_later;
 loc_ref(:, :, 2)  = loc_ref;
 loc2_ref(:, :, 2) = loc2_ref;
 nb_ref(:, :, 2)   = nb_ref;
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc(:, :, 1) >= loc2(:, :, 1));
@@ -208,10 +211,10 @@ assert_checktrue(loc(:, :, 2) >= loc2(:, :, 2));
 // Hypermatrices of Integers
 A_int = uint32(A);
 S_int = uint32(S);
-[nb, loc] = members(A_int, S_int, %t);
+[nb, loc] = members(A_int, S_int, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A_int, S_int, %f);
+[nb, loc2] = members(A_int, S_int);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc(:, :, 1) >= loc2(:, :, 1));
@@ -219,10 +222,10 @@ assert_checktrue(loc(:, :, 2) >= loc2(:, :, 2));
 // Hypermatrices of Strings
 A_str = string(A);
 S_str = string(S);
-[nb, loc] = members(A_str, S_str, %t);
+[nb, loc] = members(A_str, S_str, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A_str, S_str, %f);
+[nb, loc2] = members(A_str, S_str);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc(:, :, 1) >= loc2(:, :, 1));
@@ -230,29 +233,125 @@ assert_checktrue(loc(:, :, 2) >= loc2(:, :, 2));
 // Hypermatrices of Complexes
 A_img = A.*%i;
 S_img = S*%i;
-[nb, loc] = members(A_img, S_img, %t);
+[nb, loc] = members(A_img, S_img, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A_img, S_img, %f);
+[nb, loc2] = members(A_img, S_img);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc(:, :, 1) >= loc2(:, :, 1));
 assert_checktrue(loc(:, :, 2) >= loc2(:, :, 2));
 // Polynomials
 z = %z;
-A = [z (1-z)^2 ; -4 %i*z ];
-S = [2  %i*z -z  3-z  z  z^3 z];
+A_pol = [z (1-z)^2 ; -4 %i*z ];
+S_pol = [2  %i*z -z  3-z  z  z^3 z];
 loc_ref  = [7 0 ; 0 2];
 loc2_ref = [5 0 ; 0 2];
 nb_ref   = [2 0 ; 0 1];
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A_pol, S_pol, "last");
 assert_checkequal(nb, nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A_pol, S_pol);
 assert_checkequal(nb, nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
+// Row-wise and column-wise search
+// With reals
+A_cols = A_for_later;
+S_cols = S_for_later;
+S_cols(:, 2) = A_for_later(:, 2);
+loc_ref = [0 2 0 0 0];
+nb_ref  = [0 1 0 0 0];
+[nb, loc] = members(A_cols, S_cols, "cols");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+// With integers
+A_cols = int16(A_cols);
+S_cols = int16(S_cols);
+[nb, loc] = members(A_cols, S_cols, "cols");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+// With strings
+A_cols = string(A_cols);
+S_cols = string(S_cols);
+[nb, loc] = members(A_cols, S_cols, "cols");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+// Shuffle option
+// With reals
+A_cols = A_for_later;
+S_cols = S_for_later;
+S_cols(:, 2) = A_for_later(:, 2);
+temp = S_cols(1, 2); S_cols(1, 2) = S_cols(6, 2); S_cols(6, 2) = temp; // Switching two elements of S
+S_cols = [S_cols S_cols(:, 2)]; // To get two column occurrences of A in S, for "later" to be relevant
+loc_ref  = [0 2 0 0 0];
+loc2_ref = [0 4 0 0 0];
+nb_ref   = [0 2 0 0 0];
+[nb, loc] = members(A_cols, S_cols, "cols", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_cols, S_cols, "cols", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_rows, S_rows, "rows", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+// With integers
+A_cols = int16(A_cols);
+S_cols = int16(S_cols);
+[nb, loc] = members(A_cols, S_cols, "cols", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_cols, S_cols, "cols", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_rows, S_rows, "rows", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+// With strings
+A_cols = string(A_cols);
+S_cols = string(S_cols);
+[nb, loc] = members(A_cols, S_cols, "cols", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_cols, S_cols, "cols", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_rows, S_rows, "rows", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
 // IEEE
+// Normal mode
 A = [ 0 0 1 1 1 ;
       0 2 2 2 %nan ;
       2 0 1 1 1 ;
@@ -261,25 +360,48 @@ S = [1 0 1 ;
      2 0 4 ;
      1 2 5 ;
   %inf -%inf 6];
-loc_ref  = [6 6 9 9 9 ;
-            6 7 7 7 0 ;
-            7 6 9 9 9 ;
-            6 6 9 4 8 ];
-loc2_ref = [5 5 1 1 1 ;
-            5 2 2 2 0 ;
-            2 5 1 1 1 ;
-            5 5 1 4 8 ];
-nb_ref   = [2 2 3 3 3 ;
-            2 2 2 2 0 ;
-            2 2 3 3 3 ;
-            2 2 3 1 1 ];
-[nb, loc] = members(A, S, %t);
+loc_ieee_ref  = [6 6 9 9 9 ;
+                 6 7 7 7 0 ;
+                 7 6 9 9 9 ;
+                 6 6 9 4 8 ];
+loc2_ieee_ref = [5 5 1 1 1 ;
+                 5 2 2 2 0 ;
+                 2 5 1 1 1 ;
+                 5 5 1 4 8 ];
+nb_ieee_ref   = [2 2 3 3 3 ;
+                 2 2 2 2 0 ;
+                 2 2 3 3 3 ;
+                 2 2 3 1 1 ];
+[nb, loc] = members(A, S, "last");
+assert_checkequal(nb , nb_ieee_ref);
+assert_checkequal(loc, loc_ieee_ref);
+[nb, loc2] = members(A, S);
+assert_checkequal(nb  , nb_ieee_ref);
+assert_checkequal(loc2, loc2_ieee_ref);
+assert_checktrue(loc >= loc2);
+// Row-wise and column-wise modes
+A_cols(:, 1) = "%nan";      // Introducing a %nan column
+A_cols(1, 2) = "%inf";      // Adding some %inf elements
+A_cols(2, 2) = "-%inf";
+S_cols(:, 1) = "%nan";      // Introducing a %nan column
+S_cols(1, [2 4]) = "%inf";  // Adding the same %inf elements to S
+S_cols(2, [2 4]) = "-%inf";
+S_cols(3, [2 4]) = "7";     // Adjusting, for shuffle option
+A_rows(1, :) = "%nan";      // Same operations, by rows
+A_rows(2, 1) = "%inf";
+A_rows(2, 2) = "-%inf";
+S_rows(1, :) = "%nan";
+S_rows([2 4], 1) = "%inf";
+S_rows([2 4], 2) = "-%inf";
+S_rows([2 4], 3) = "7";
+loc_ref(1) = 1; // %nan columns are common to A and S, in first position
+nb_ref(1)  = 1;
+[nb, loc] = members(A_cols, S_cols, "cols", "shuffle");
+assert_checkequal(nb , nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc] = members(A_rows, S_rows, "rows", "shuffle");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
-assert_checkequal(nb  , nb_ref);
-assert_checkequal(loc2, loc2_ref);
-assert_checktrue(loc >= loc2);
 // =============================================================================
 // Error checks
 A = [1 2 3; 4 5 6];
@@ -287,21 +409,24 @@ refMsg = msprintf(_("%s: Wrong number of input argument(s): at least %d expected
 assert_checkerror("[nb, loc] = members(A);", refMsg);
 S = string(A);
 refMsg = msprintf(_("%s: Wrong type for input argument #%d: expected same type as first argument.\n"), "members", 2);
-assert_checkerror("[nb, loc] = members(A, S, %t);", refMsg);
+assert_checkerror("[nb, loc] = members(A, S, ""last"");", refMsg);
 S = int16(A);
-assert_checkerror("[nb, loc] = members(A, S, %t);", refMsg);
+assert_checkerror("[nb, loc] = members(A, S, ""last"");", refMsg);
 S = uint8(A);
-assert_checkerror("[nb, loc] = members(A, S, %f);", refMsg);
+assert_checkerror("[nb, loc] = members(A, S);", refMsg);
 S = [7 8 9; 10 %nan 12];
 refMsg = msprintf(_("%s: Wrong value for argument #%d: Must not contain NaN.\n"), "members", 2);
 assert_checkerror("[nb, loc] = members(A, S);", refMsg);
-S = [7 8 9; 10 11 12];
-last = 1;
-refMsg = msprintf(_("%s: Wrong type for input argument #%d: Boolean matrix expected.\n"), "members", 3);
-assert_checkerror("[nb, loc] = members(A, S, last);", refMsg);
-last = "yes";
-refMsg = msprintf(_("%s: Wrong type for input argument #%d: Boolean matrix expected.\n"), "members", 3);
-assert_checkerror("[nb, loc] = members(A, S, last);", refMsg);
-last = [%t %f];
-refMsg = msprintf(_("%s: Wrong size for input argument #%d: Scalar expected.\n"), "members", 3);
-assert_checkerror("[nb, loc] = members(A, S, last);", refMsg);
+A = rand(2, 3, 2);
+S = [7 8; 10 11];
+refMsg = msprintf(_("%s: Wrong type for argument #%d: Matrix expected.\n"), "members", 1);
+assert_checkerror("[nb, loc] = members(A, S, ""rows"");", refMsg);
+A = [1 2 3; 4 5 6; 7 8 9];
+S = rand(2, 3, 2);
+refMsg = msprintf(_("%s: Wrong type for argument #%d: Matrix expected.\n"), "members", 2);
+assert_checkerror("[nb, loc] = members(A, S, ""rows"");", refMsg);
+S = [7 8; 10 11];
+refMsg = msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of columns expected.\n"), "members", 1, 2);
+assert_checkerror("[nb, loc] = members(A, S, ""rows"");", refMsg);
+refMsg = msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of rows expected.\n"), "members", 1, 2);
+assert_checkerror("[nb, loc] = members(A, S, ""cols"");", refMsg);
index f36d4e1..d3f6814 100644 (file)
@@ -4,47 +4,48 @@
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
-
+//
 // <-- CLI SHELL MODE -->
+//
 // <-- ENGLISH IMPOSED -->
-
+//
 
 // Vectors
-[nb, loc] = members([], [], %t);
+[nb, loc] = members([], [], "last");
 assert_checkequal(nb , []);
 assert_checkequal(loc, []);
-[nb, loc] = members([], [], %f);
+[nb, loc] = members([], []);
 assert_checkequal(nb , []);
 assert_checkequal(loc, []);
 
-[nb, loc] = members([1 2], [3 4], %t);
+[nb, loc] = members([1 2], [3 4], "last");
 assert_checkequal(nb , [0 0]);
 assert_checkequal(loc, [0 0]);
-[nb, loc] = members([1 2], [3 4], %f);
+[nb, loc] = members([1 2], [3 4]);
 assert_checkequal(nb , [0 0]);
 assert_checkequal(loc, [0 0]);
 
-[nb, loc] = members([1 2; 3 4], [5 6; 7 8], %t);
+[nb, loc] = members([1 2; 3 4], [5 6; 7 8], "last");
 assert_checkequal(nb , [0 0; 0 0]);
 assert_checkequal(loc, [0 0; 0 0]);
-[nb, loc] = members([1 2; 3 4], [5 6; 7 8], %f);
+[nb, loc] = members([1 2; 3 4], [5 6; 7 8]);
 assert_checkequal(nb , [0 0; 0 0]);
 assert_checkequal(loc, [0 0; 0 0]);
 
-[nb, loc] = members(string([1 2; 3 4]), string([5 6; 7 8]), %t);
+[nb, loc] = members(string([1 2; 3 4]), string([5 6; 7 8]), "last");
 assert_checkequal(nb , [0 0; 0 0]);
 assert_checkequal(loc, [0 0; 0 0]);
-[nb, loc] = members(string([1 2; 3 4]), string([5 6; 7 8]), %f);
+[nb, loc] = members(string([1 2; 3 4]), string([5 6; 7 8]));
 assert_checkequal(nb , [0 0; 0 0]);
 assert_checkequal(loc, [0 0; 0 0]);
 
 A = [1 8 4 5 2 1];
 S = [9 7 4 2 1 4];
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 6 0 4 5]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 3 0 4 5]);
 
@@ -53,30 +54,30 @@ assert_checkequal(loc, [5 0 3 0 4 5]);
 A = 'a'+string(A);
 S = 's'+string(S);
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [0 0 0 0 0 0]);
 assert_checkequal(loc, [0 0 0 0 0 0]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [0 0 0 0 0 0]);
 assert_checkequal(loc, [0 0 0 0 0 0]);
 
 A = ["elt1" "elt3" "elt4"];
 S = ["elt5" "elt1" "elt3"];
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 1 0]);
 assert_checkequal(loc, [2 3 0]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 1 0]);
 assert_checkequal(loc, [2 3 0]);
 
 A = ["elt1" "elt3" "elt4"];
 S = ["elt5" "elt6" "elt2" "elt1" "elt3"];
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 1 0]);
 assert_checkequal(loc, [4 5 0]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 1 0]);
 assert_checkequal(loc, [4 5 0]);
 
@@ -85,20 +86,20 @@ assert_checkequal(loc, [4 5 0]);
 A = int16([1 8 4 5 2 1]);
 S = int16([9 7 4 2 1 4]);
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 6 0 4 5]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 3 0 4 5]);
 
 A = uint8([1 8 4 5 2 1]);
 S = uint8([9 7 4 2 1 4]);
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 6 0 4 5]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 3 0 4 5]);
 
@@ -107,10 +108,10 @@ assert_checkequal(loc, [5 0 3 0 4 5]);
 A = [1 8 4 5 2 1]*%i;
 S = [9 7 4 2 1 4]*%i;
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 6 0 4 5]);
-[nb, loc] = members(A, S, %f);
+[nb, loc] = members(A, S);
 assert_checkequal(nb , [1 0 2 0 1 1]);
 assert_checkequal(loc, [5 0 3 0 4 5]);
 
@@ -147,10 +148,10 @@ nb_ref   = [ 1 2 3 2 3 ;
              4 2 1 3 0 ;
              2 0 3 1 2 ];
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
@@ -178,10 +179,10 @@ nb_ref   = [1 2 4 2 4 2 ;
             2 3 2 4 3 1 ;
             3 1 3 4 0 2 ];
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
@@ -191,10 +192,10 @@ assert_checktrue(loc >= loc2);
 A = uint32(A);
 S = uint32(S);
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
@@ -207,10 +208,10 @@ loc_ref  = loc_ref_for_later;
 loc2_ref = loc2_ref_for_later;
 nb_ref   = nb_ref_for_later;
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
@@ -220,10 +221,10 @@ assert_checktrue(loc >= loc2);
 A = A_for_later*%i;
 S = S_for_later*%i;
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
@@ -237,10 +238,10 @@ loc_ref(:, :, 2)  = loc_ref;
 loc2_ref(:, :, 2) = loc2_ref;
 nb_ref(:, :, 2)   = nb_ref;
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A, S, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A, S);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc(:, :, 1) >= loc2(:, :, 1));
@@ -251,10 +252,10 @@ assert_checktrue(loc(:, :, 2) >= loc2(:, :, 2));
 A_int = uint32(A);
 S_int = uint32(S);
 
-[nb, loc] = members(A_int, S_int, %t);
+[nb, loc] = members(A_int, S_int, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A_int, S_int, %f);
+[nb, loc2] = members(A_int, S_int);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc(:, :, 1) >= loc2(:, :, 1));
@@ -265,10 +266,10 @@ assert_checktrue(loc(:, :, 2) >= loc2(:, :, 2));
 A_str = string(A);
 S_str = string(S);
 
-[nb, loc] = members(A_str, S_str, %t);
+[nb, loc] = members(A_str, S_str, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A_str, S_str, %f);
+[nb, loc2] = members(A_str, S_str);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc(:, :, 1) >= loc2(:, :, 1));
@@ -279,10 +280,10 @@ assert_checktrue(loc(:, :, 2) >= loc2(:, :, 2));
 A_img = A.*%i;
 S_img = S*%i;
 
-[nb, loc] = members(A_img, S_img, %t);
+[nb, loc] = members(A_img, S_img, "last");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A_img, S_img, %f);
+[nb, loc2] = members(A_img, S_img);
 assert_checkequal(nb  , nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc(:, :, 1) >= loc2(:, :, 1));
@@ -291,22 +292,123 @@ assert_checktrue(loc(:, :, 2) >= loc2(:, :, 2));
 
 // Polynomials
 z = %z;
-A = [z (1-z)^2 ; -4 %i*z ];
-S = [2  %i*z -z  3-z  z  z^3 z];
+A_pol = [z (1-z)^2 ; -4 %i*z ];
+S_pol = [2  %i*z -z  3-z  z  z^3 z];
 loc_ref  = [7 0 ; 0 2];
 loc2_ref = [5 0 ; 0 2];
 nb_ref   = [2 0 ; 0 1];
 
-[nb, loc] = members(A, S, %t);
+[nb, loc] = members(A_pol, S_pol, "last");
 assert_checkequal(nb, nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
+[nb, loc2] = members(A_pol, S_pol);
 assert_checkequal(nb, nb_ref);
 assert_checkequal(loc2, loc2_ref);
 assert_checktrue(loc >= loc2);
 
 
+// Row-wise and column-wise search
+// With reals
+A_cols = A_for_later;
+S_cols = S_for_later;
+S_cols(:, 2) = A_for_later(:, 2);
+loc_ref = [0 2 0 0 0];
+nb_ref  = [0 1 0 0 0];
+[nb, loc] = members(A_cols, S_cols, "cols");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+// With integers
+A_cols = int16(A_cols);
+S_cols = int16(S_cols);
+[nb, loc] = members(A_cols, S_cols, "cols");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+// With strings
+A_cols = string(A_cols);
+S_cols = string(S_cols);
+[nb, loc] = members(A_cols, S_cols, "cols");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+
+
+// Shuffle option
+// With reals
+A_cols = A_for_later;
+S_cols = S_for_later;
+S_cols(:, 2) = A_for_later(:, 2);
+temp = S_cols(1, 2); S_cols(1, 2) = S_cols(6, 2); S_cols(6, 2) = temp; // Switching two elements of S
+S_cols = [S_cols S_cols(:, 2)]; // To get two column occurrences of A in S, for "later" to be relevant
+loc_ref  = [0 2 0 0 0];
+loc2_ref = [0 4 0 0 0];
+nb_ref   = [0 2 0 0 0];
+[nb, loc] = members(A_cols, S_cols, "cols", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_cols, S_cols, "cols", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_rows, S_rows, "rows", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+// With integers
+A_cols = int16(A_cols);
+S_cols = int16(S_cols);
+[nb, loc] = members(A_cols, S_cols, "cols", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_cols, S_cols, "cols", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_rows, S_rows, "rows", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+// With strings
+A_cols = string(A_cols);
+S_cols = string(S_cols);
+[nb, loc] = members(A_cols, S_cols, "cols", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_cols, S_cols, "cols", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+A_rows = A_cols';
+S_rows = S_cols';
+[nb, loc] = members(A_rows, S_rows, "rows", "shuffle");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc2] = members(A_rows, S_rows, "rows", "shuffle", "last");
+assert_checkequal(nb, nb_ref);
+assert_checkequal(loc2, loc2_ref);
+
+
+
 // IEEE
+// Normal mode
 A = [ 0 0 1 1 1 ;
       0 2 2 2 %nan ;
       2 0 1 1 1 ;
@@ -315,52 +417,83 @@ S = [1 0 1 ;
      2 0 4 ;
      1 2 5 ;
   %inf -%inf 6];
-loc_ref  = [6 6 9 9 9 ;
-            6 7 7 7 0 ;
-            7 6 9 9 9 ;
-            6 6 9 4 8 ];
-loc2_ref = [5 5 1 1 1 ;
-            5 2 2 2 0 ;
-            2 5 1 1 1 ;
-            5 5 1 4 8 ];
-nb_ref   = [2 2 3 3 3 ;
-            2 2 2 2 0 ;
-            2 2 3 3 3 ;
-            2 2 3 1 1 ];
-
-[nb, loc] = members(A, S, %t);
+loc_ieee_ref  = [6 6 9 9 9 ;
+                 6 7 7 7 0 ;
+                 7 6 9 9 9 ;
+                 6 6 9 4 8 ];
+loc2_ieee_ref = [5 5 1 1 1 ;
+                 5 2 2 2 0 ;
+                 2 5 1 1 1 ;
+                 5 5 1 4 8 ];
+nb_ieee_ref   = [2 2 3 3 3 ;
+                 2 2 2 2 0 ;
+                 2 2 3 3 3 ;
+                 2 2 3 1 1 ];
+
+[nb, loc] = members(A, S, "last");
+assert_checkequal(nb , nb_ieee_ref);
+assert_checkequal(loc, loc_ieee_ref);
+[nb, loc2] = members(A, S);
+assert_checkequal(nb  , nb_ieee_ref);
+assert_checkequal(loc2, loc2_ieee_ref);
+assert_checktrue(loc >= loc2);
+
+
+// Row-wise and column-wise modes
+A_cols(:, 1) = "%nan";      // Introducing a %nan column
+A_cols(1, 2) = "%inf";      // Adding some %inf elements
+A_cols(2, 2) = "-%inf";
+S_cols(:, 1) = "%nan";      // Introducing a %nan column
+S_cols(1, [2 4]) = "%inf";  // Adding the same %inf elements to S
+S_cols(2, [2 4]) = "-%inf";
+S_cols(3, [2 4]) = "7";     // Adjusting, for shuffle option
+A_rows(1, :) = "%nan";      // Same operations, by rows
+A_rows(2, 1) = "%inf";
+A_rows(2, 2) = "-%inf";
+S_rows(1, :) = "%nan";
+S_rows([2 4], 1) = "%inf";
+S_rows([2 4], 2) = "-%inf";
+S_rows([2 4], 3) = "7";
+loc_ref(1) = 1; // %nan columns are common to A and S, in first position
+nb_ref(1)  = 1;
+
+[nb, loc] = members(A_cols, S_cols, "cols", "shuffle");
+assert_checkequal(nb , nb_ref);
+assert_checkequal(loc, loc_ref);
+[nb, loc] = members(A_rows, S_rows, "rows", "shuffle");
 assert_checkequal(nb , nb_ref);
 assert_checkequal(loc, loc_ref);
-[nb, loc2] = members(A, S, %f);
-assert_checkequal(nb  , nb_ref);
-assert_checkequal(loc2, loc2_ref);
-assert_checktrue(loc >= loc2);
+
 
 
 // =============================================================================
 
 
+
 // Error checks
 A = [1 2 3; 4 5 6];
 refMsg = msprintf(_("%s: Wrong number of input argument(s): at least %d expected.\n"), "members", 2);
 assert_checkerror("[nb, loc] = members(A);", refMsg);
 S = string(A);
 refMsg = msprintf(_("%s: Wrong type for input argument #%d: expected same type as first argument.\n"), "members", 2);
-assert_checkerror("[nb, loc] = members(A, S, %t);", refMsg);
+assert_checkerror("[nb, loc] = members(A, S, ""last"");", refMsg);
 S = int16(A);
-assert_checkerror("[nb, loc] = members(A, S, %t);", refMsg);
+assert_checkerror("[nb, loc] = members(A, S, ""last"");", refMsg);
 S = uint8(A);
-assert_checkerror("[nb, loc] = members(A, S, %f);", refMsg);
+assert_checkerror("[nb, loc] = members(A, S);", refMsg);
 S = [7 8 9; 10 %nan 12];
 refMsg = msprintf(_("%s: Wrong value for argument #%d: Must not contain NaN.\n"), "members", 2);
 assert_checkerror("[nb, loc] = members(A, S);", refMsg);
-S = [7 8 9; 10 11 12];
-last = 1;
-refMsg = msprintf(_("%s: Wrong type for input argument #%d: Boolean matrix expected.\n"), "members", 3);
-assert_checkerror("[nb, loc] = members(A, S, last);", refMsg);
-last = "yes";
-refMsg = msprintf(_("%s: Wrong type for input argument #%d: Boolean matrix expected.\n"), "members", 3);
-assert_checkerror("[nb, loc] = members(A, S, last);", refMsg);
-last = [%t %f];
-refMsg = msprintf(_("%s: Wrong size for input argument #%d: Scalar expected.\n"), "members", 3);
-assert_checkerror("[nb, loc] = members(A, S, last);", refMsg);
+A = rand(2, 3, 2);
+S = [7 8; 10 11];
+refMsg = msprintf(_("%s: Wrong type for argument #%d: Matrix expected.\n"), "members", 1);
+assert_checkerror("[nb, loc] = members(A, S, ""rows"");", refMsg);
+A = [1 2 3; 4 5 6; 7 8 9];
+S = rand(2, 3, 2);
+refMsg = msprintf(_("%s: Wrong type for argument #%d: Matrix expected.\n"), "members", 2);
+assert_checkerror("[nb, loc] = members(A, S, ""rows"");", refMsg);
+S = [7 8; 10 11];
+refMsg = msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of columns expected.\n"), "members", 1, 2);
+assert_checkerror("[nb, loc] = members(A, S, ""rows"");", refMsg);
+refMsg = msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of rows expected.\n"), "members", 1, 2);
+assert_checkerror("[nb, loc] = members(A, S, ""cols"");", refMsg);
index 9467415..b60e403 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2009 - Université du Maine - Samuel Gougeon
+ * Copyright (C) 2013 - Samuel GOUGEON
  *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
@@ -10,7 +10,7 @@
  * 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:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="m2sci_ismember">
+<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:id="m2sci_ismember" xml:lang="en">
     <refnamediv>
         <refname>ismember (Matlab function)</refname>
         <refpurpose>Data sets membership comparison</refpurpose>
             <tr>
                 <td>
                     <programlisting role="example"><![CDATA[
-[., loc] = ismember(A, B)
+// a)
+AinB = ismember(A, B)
+
+// b)
+[AinB, loc] = ismember(A, B)
+// c)
+[rAinB, loc] = ismember(A, B, 'rows')
 ]]></programlisting>
                 </td>
                 <td>
                     <programlisting role="example"><![CDATA[
-[., loc] = members(A, B, %f)
+// a)
+mA = members(A, B);
+AinB = bool2s(mA~=0)
+// b)
+[mA, loc] = members(A, B)
+// c)
+[rmA, loc] = members(A, B, "rows");
+rAinB = bool2s(rmA~=0)
 ]]></programlisting>
                 </td>
             </tr>
@@ -43,7 +56,7 @@
     <refsection>
         <title>Description</title>
         <para>
-            The second output argument returned by <emphasis role="bold">members(A, B, %f)</emphasis> in Scilab is equivalent to the second output argument of <emphasis role="bold">ismember(A, B)</emphasis> in Matlab.
+            In addition, Scilab provides the number of occurrences, can provide the locations of last occurrences instead of the first ones, can process A and B column-wise, and can ignore the order of elements in each row/column to be detected (detection of permutations).
         </para>
     </refsection>
 </refentry>