* Bugs 15866 & 15867 fixed: setdiff() + 'r'|'c' & integers 07/20607/4
Samuel GOUGEON [Sun, 4 Nov 2018 13:35:18 +0000 (14:35 +0100)]
  http://bugzilla.scilab.org/15866
  http://bugzilla.scilab.org/15867

  Page overhauled (PDF): http://bugzilla.scilab.org/attachment.cgi?id=4839
  Too many changes to update non-en_US versions.
  It might be preferable to wait for fixing the additional setdiff bugs
     http://bugzilla.scilab.org/15737 (complex numbers) and
     http://bugzilla.scilab.org/15868 (sparse)
  in some additional commits before retranslating the new up-to-date
  setdiff page.

Change-Id: Ia72e6a634ba7dda2c8bec9e8248310d16b20201b

scilab/CHANGES.md
scilab/modules/elementary_functions/help/en_US/setoperations/setdiff.xml
scilab/modules/elementary_functions/help/ja_JP/setoperations/setdiff.xml [deleted file]
scilab/modules/elementary_functions/help/pt_BR/setoperations/setdiff.xml [deleted file]
scilab/modules/elementary_functions/help/ru_RU/setoperations/setdiff.xml
scilab/modules/elementary_functions/macros/setdiff.sci
scilab/modules/elementary_functions/tests/unit_tests/setdiff.dia.ref [deleted file]
scilab/modules/elementary_functions/tests/unit_tests/setdiff.tst

index d641d93..7447851 100644 (file)
@@ -676,6 +676,8 @@ Known issues
 * [#15858](http://bugzilla.scilab.org/show_bug.cgi?id=15858): `size(cblock,'r'|'c'|'*'|1|2)` did not take the option into account. `size()` of an empty cblock table yielded an error.
 * [#15859](http://bugzilla.scilab.org/show_bug.cgi?id=15859): `isempty` could not be overloaded for custom mlist or tlist typeof.
 * [#15860](http://bugzilla.scilab.org/show_bug.cgi?id=15860): Horizontal concatenations with cblock tables had troubles.
+* [#15866](http://bugzilla.scilab.org/show_bug.cgi?id=15866): Unlike all other set functions, `setdiff` did not accept any "r" or "c" option.
+* [#15867](http://bugzilla.scilab.org/show_bug.cgi?id=15867): For input encoded integers, `setdiff` returned selected elements in decreasing order.
 * [#15878](http://bugzilla.scilab.org/show_bug.cgi?id=15878): `sgrid` and `evans` were broken.
 * [#15880](http://bugzilla.scilab.org/show_bug.cgi?id=15880): `sgrid` needed some improvements: Labeling was sometimes ambiguous ; large circles were not labeled ; data_bounds did not always take the input wn into account ; named and #RRGGBB colors specifications could not be used. `evans` needed some improvements: the block of legends hid data ; asymptotes were too visible.
 * [#15886](http://bugzilla.scilab.org/show_bug.cgi?id=15886): Display of polynomials was broken.
index 26e2ce5..5ec08ec 100644 (file)
@@ -2,8 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2008 - INRIA
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2018 - Samuel GOUGEON
  *
  * This file is hereby licensed under the terms of the GNU GPL v2.0,
  * pursuant to article 5.3.4 of the CeCILL v.2.1.
  * along with this program.
  *
  -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns: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="setdiff" 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="setdiff" xml:lang="en">
     <refnamediv>
         <refname>setdiff</refname>
-        <refpurpose>returns components of a vector which do not belong to another
-            one
+        <refpurpose>
+            returns elements or rows or columns of an array that do not belong to another one
         </refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Syntax</title>
-        <synopsis>v=setdiff(a,b)
-            [v,ka]=setdiff(a,b)
+        <synopsis>
+            v = setdiff(a, b)
+            v = setdiff(a, b, orien)
+            [v, ka] = setdiff(..)
         </synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Arguments</title>
         <variablelist>
             <varlistentry>
-                <term>a</term>
+                <term>a, b</term>
                 <listitem>
-                    <para>vector of real numbers or strings</para>
+                    <para>
+                        vectors, matrices or hypermatrices of real numbers or encoded integers or
+                        strings. Both must have the same data types (and integer types).
+                    </para>
+                    <para>
+                        If the option <literal>orien="r"</literal> is used, <literal>a</literal>
+                        and <literal>b</literal> must have the same number of columns.
+                        If the <literal>orien="c"</literal> is used, they must have the same
+                        number of rows.
+                    </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>b</term>
+                <term>orien</term>
                 <listitem>
-                    <para>vector of real numbers or strings</para>
+                    oriented processing:
+                    <itemizedlist>
+                        <listitem>
+                            <literal>"r"</literal>: rows of
+                            <literal>a</literal> are searched among <literal>b</literal> ones.
+                        </listitem>
+                        <listitem>
+                            <literal>"c"</literal>: columns of
+                            <literal>a</literal> are searched among <literal>b</literal> ones.
+                        </listitem>
+                        <listitem>
+                            no orien: elements of <literal>a</literal> are searched among
+                            <literal>b</literal> ones.
+                        </listitem>
+                    </itemizedlist>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>v</term>
                 <listitem>
-                    <para>vector of real numbers or strings with same orientation than
-                        <literal>a</literal>
-                    </para>
+                    <itemizedlist>
+                        <listitem>
+                            sorted vector of <literal>a</literal>'s components that are not in
+                            <literal>b</literal>.
+                        </listitem>
+                        <listitem>
+                            <literal>orien="r"</literal>: matrix of rows of <literal>a</literal>
+                            that are not in <literal>b</literal>, sorted in lexicographic order.
+                        </listitem>
+                        <listitem>
+                            <literal>orien="c"</literal>: matrix of columns of <literal>a</literal>
+                            that are not in <literal>b</literal>, sorted in lexicographic order.
+                        </listitem>
+                    </itemizedlist>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>ka</term>
                 <listitem>
-                    <para>row vector of integers, ka(i) is the location of v(i) in
-                        a
+                    <para>
+                        vector of linear indices of selected  <literal>a</literal>'s components,
+                        rows, or columns, such that
+                        <itemizedlist>
+                            <listitem>
+                                <literal>v = a(ka)</literal>, or
+                            </listitem>
+                            <listitem>
+                                <literal>v = a(ka,:)</literal> (<literal>orien="r"</literal>), or
+                            </listitem>
+                            <listitem>
+                                <literal>v = a(:,ka)</literal> (<literal>orien="c"</literal>)
+                            </listitem>
+                        </itemizedlist>
                     </para>
                 </listitem>
             </varlistentry>
     <refsection>
         <title>Description</title>
         <para>
-            <literal>setdiff(a,b)</literal> returns a sorted vector which
-            retains the <literal>a</literal> entries which are not in
-            <literal>b</literal>
+            <literal>setdiff(a, b,..)</literal> computes and returns the elements or rows or columns
+            of <literal>a</literal> that are NOT in <literal>b</literal>.
+        </para>
+        <para>
+            All duplicates (elements or rows or columns) are removed from <literal>a</literal> and
+            from <literal>b</literal> before processing.
         </para>
         <para>
-            <literal>[v,ka]=setdiff(a,b)</literal> returns a sorted vector which
-            retains the <literal>a</literal> entries which are not in
-            <literal>b</literal> and the location of these entries in a.
+            If <literal>a</literal> is an hypermatrix and the <literal>"r"</literal> option is used,
+            <literal>a</literal> is replaced with the matrix of all its rows over all its higher
+            dimensions, before processing.
+            Same thing if <literal>b</literal> is an hypermatrix.
+            If the <literal>"c"</literal> option is used, <literal>a</literal> or/and
+            <literal>"b"</literal> are replaced with the respective matrices of all their columns.
+        </para>
+        <para>
+            The format of results is presented in the following table, according to the shape of
+            <literal>a</literal> and the <literal>orien</literal> option. In all cases, if all
+            entities of <literal>a</literal> are in <literal>b</literal>,
+            <literal>[]</literal> is returned for <literal>v</literal> as for <literal>ka</literal>:
+            <table>
+                <tr>
+                    <th align="right">orien →</th>
+                    <td colspan="2" align="center"><emphasis role="bold">none</emphasis></td>
+                    <td colspan="2" align="center"><emphasis role="bold">"r"</emphasis></td>
+                    <td colspan="2" align="center"><emphasis role="bold">"c"</emphasis></td>
+                </tr>
+                <tr>
+                    <th>a ↓</th><th>v</th><th>ka</th><th>v</th><th>ka</th><th>v</th><th>ka</th>
+                </tr>
+                <tr>
+                    <td align="right"><emphasis role="bold">row</emphasis></td>
+                    <td>row</td><td>row</td>
+                    <td>row</td><td>scal</td>
+                    <td>row</td><td>row</td>
+                </tr>
+                <tr>
+                    <td align="right"><emphasis role="bold">column</emphasis></td>
+                    <td>col</td><td>col</td>
+                    <td>col</td><td>col</td>
+                    <td>col</td><td>scal</td>
+                </tr>
+                <tr>
+                    <td align="right"><emphasis role="bold">matrix</emphasis></td>
+                    <td>col</td><td>col</td>
+                    <td>mat</td><td>col</td>
+                    <td>mat</td><td>row</td>
+                </tr>
+                <tr>
+                    <td align="right"><emphasis role="bold">hypermatrix</emphasis></td>
+                    <td>col</td><td>col</td>
+                    <td>mat</td><td>col</td>
+                    <td>mat</td><td>row</td>
+                </tr>
+                <tr align="center">
+                    <td align="right"><emphasis role="bold">scalar</emphasis></td>
+                    <td>scal</td><td>scal</td>
+                    <td>scal</td><td>scal</td>
+                    <td>scal</td><td>scal</td>
+                </tr>
+            </table>
+        </para>
+        <para>
+            <literal>v</literal> and <literal>ka</literal> become empty <literal>[]</literal>
+            if <literal>a</literal> is empty (whatever is <literal>b</literal>), or if all
+            <literal>a</literal> elements are in <literal>b</literal>.
         </para>
     </refsection>
     <refsection>
         <title>Examples</title>
+        <para>
+            <emphasis role="bold">Example #1:</emphasis>
+        </para>
         <programlisting role="example"><![CDATA[
-a = [223;111;2;4;2;2];
-b = [2;3;21;223;123;22];
-setdiff(a,b)
-[v,k]=setdiff(string(a),string(b))
+a = grand(1, 10,"uin", 0, 9)
+b = grand(2, 4, "uin", 0, 9)
+[d, k] = setdiff(a, b);
+d, k
  ]]></programlisting>
+    <screen><![CDATA[
+--> a = grand(1, 10,"uin", 0, 9)
+ a  =
+   2.   2.   4.   5.   4.   1.   9.   5.   8.   3.
+
+--> b = grand(2, 4, "uin", 0, 9)
+ b  =
+   5.   0.   9.   9.
+   5.   6.   0.   4.
+
+--> [d, k] = setdiff(a, b);
+--> d, k
+ d  =
+   1.   2.   3.   8.
+
+ k  =
+   6.   1.   10.   9.
+ ]]></screen>
+        <para>
+            <emphasis role="bold">Example #2: column-wise processing</emphasis>
+        </para>
+        <programlisting role="example"><![CDATA[
+a = grand(2, 7,"uin", 0, 3)
+b = grand(2, 10, "uin", 0, 3)
+[d, k] = setdiff(a, b, "c");
+d, k
+ ]]></programlisting>
+    <screen><![CDATA[
+--> a = grand(2, 7,"uin", 0, 3)
+ a  =
+   0.   1.   0.   2.   3.   0.   2.
+   2.   2.   2.   1.   0.   1.   2.
+
+--> b = grand(2, 10, "uin", 0, 3)
+ b  =
+   1.   1.   3.   1.   1.   1.   3.   0.   2.   0.
+   3.   3.   2.   2.   0.   0.   1.   0.   1.   0.
+
+--> [d, k] = setdiff(a, b, "c");
+--> d, k
+ d  =
+   0.   0.   2.   3.
+   1.   2.   2.   0.
+
+ k  =
+   6.   1.   7.   5.
+ ]]></screen>
+        <para>
+            <emphasis role="bold">Example #3: with some text</emphasis>
+        </para>
+        <programlisting role="example"><![CDATA[
+v1 = tokens("ab  ca  ba  bb  ca  cb  ba  aa  cc  bc  ac  aa")'
+v2 = tokens("cc  ac  ca  bb  ac  bc  ab")'
+[r, k] = setdiff(v1, v2);
+r, k
+]]></programlisting>
+    <screen><![CDATA[
+--> v1 = tokens("ab  ca  ba  bb  ca  cb  ba  aa  cc  bc  ac  aa")'
+ v1  =
+!ab  ca  ac  bb  ca  cb  ba  aa  cc  bc  ac  aa  !
+
+--> v2 = tokens("cc  ac  ca  bb  ac  bc  ab")'
+ v2  =
+!cc  ac  ca  bb  ac  bc  ab  !
+
+--> [r, k] = setdiff(v1, v2);
+--> r, k
+ r  =
+!aa  ba  cb  !
+
+ k  =
+   8.   3.   6.
+]]></screen>
     </refsection>
     <refsection role="see also">
         <title>See also</title>
@@ -88,11 +273,31 @@ setdiff(a,b)
                 <link linkend="unique">unique</link>
             </member>
             <member>
-                <link linkend="gsort">gsort</link>
+                <link linkend="union">union</link>
             </member>
             <member>
-                <link linkend="union">union</link>
+                <link linkend="members">members</link>
+            </member>
+            <member>
+                <link linkend="vertorfind">vectorfind</link>
             </member>
         </simplelist>
     </refsection>
-</refentry>
+    <refsection role="history">
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>&lt; 5.0</revnumber>
+                <revdescription>
+                    Function introduced.
+                </revdescription>
+            </revision>
+            <revision>
+                <revnumber>6.0.2</revnumber>
+                <revdescription>
+                    Option "r" | "c" added, including for hypermatrices.
+                </revdescription>
+            </revision>
+        </revhistory>
+    </refsection>
+</refentry>
\ No newline at end of file
diff --git a/scilab/modules/elementary_functions/help/ja_JP/setoperations/setdiff.xml b/scilab/modules/elementary_functions/help/ja_JP/setoperations/setdiff.xml
deleted file mode 100644 (file)
index 647948f..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2008 - INRIA
- *
- * Copyright (C) 2012 - 2016 - Scilab Enterprises
- *
- * This file is hereby licensed under the terms of the GNU GPL v2.0,
- * pursuant to article 5.3.4 of the CeCILL v.2.1.
- * This file was originally licensed under the terms of the CeCILL v2.1,
- * and continues to be available under such terms.
- * For more information, see the COPYING file which you should have received
- * along with this program.
- *
- -->
-
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns5="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="setdiff" xml:lang="ja">
-
-    <refnamediv>
-
-        <refname>setdiff</refname>
-
-        <refpurpose>ベクトルの要素のうちで別のベクトルに
-
-            属していない要素を返す
-        </refpurpose>
-
-    </refnamediv>
-
-    <refsynopsisdiv>
-
-        <title>呼び出し手順</title>
-
-        <synopsis>v=setdiff(a,b)
-
-            [v,ka]=setdiff(a,b)
-
-        </synopsis>
-
-    </refsynopsisdiv>
-
-    <refsection>
-
-        <title>引数</title>
-
-        <variablelist>
-
-            <varlistentry>
-
-                <term>a</term>
-
-                <listitem>
-
-                    <para>実数または文字列のベクトル</para>
-
-                </listitem>
-
-            </varlistentry>
-
-            <varlistentry>
-
-                <term>b</term>
-
-                <listitem>
-
-                    <para>実数または文字列のベクトル</para>
-
-                </listitem>
-
-            </varlistentry>
-
-            <varlistentry>
-
-                <term>v</term>
-
-                <listitem>
-
-                    <para>
-
-                        <literal>a</literal>と同じ方向の実数または文字列のベクトル
-
-                    </para>
-
-                </listitem>
-
-            </varlistentry>
-
-            <varlistentry>
-
-                <term>ka</term>
-
-                <listitem>
-
-                    <para>整数の行ベクトルで, ka(i) は a における v(i) の位置</para>
-
-                </listitem>
-
-            </varlistentry>
-
-        </variablelist>
-
-    </refsection>
-
-    <refsection>
-
-        <title>説明</title>
-
-        <para>
-
-            <literal>setdiff(a,b)</literal> は,
-
-            <literal>b</literal>の中に存在しない
-
-            <literal>a</literal>のエントリからなる
-
-            ソート済みのベクトルを返します.
-
-        </para>
-
-        <para>
-
-            <literal>[v,ka]=setdiff(a,b)</literal> は,
-
-            <literal>b</literal>の中に存在しない
-
-            <literal>a</literal>のエントリからなる
-
-            ソート済みのベクトルとこれらのエントリの a の中での位置を返します.
-
-        </para>
-
-    </refsection>
-
-    <refsection>
-
-        <title>例</title>
-
-        <programlisting role="example"><![CDATA[
-a = [223;111;2;4;2;2];
-b = [2;3;21;223;123;22];
-setdiff(a,b)
-[v,k]=setdiff(string(a),string(b))
- ]]></programlisting>
-
-    </refsection>
-
-    <refsection role="see also">
-
-        <title>参照</title>
-
-        <simplelist type="inline">
-
-            <member>
-
-                <link linkend="unique">unique</link>
-
-            </member>
-
-            <member>
-
-                <link linkend="gsort">gsort</link>
-
-            </member>
-
-            <member>
-
-                <link linkend="union">union</link>
-
-            </member>
-
-        </simplelist>
-
-    </refsection>
-
-</refentry>
-
diff --git a/scilab/modules/elementary_functions/help/pt_BR/setoperations/setdiff.xml b/scilab/modules/elementary_functions/help/pt_BR/setoperations/setdiff.xml
deleted file mode 100644 (file)
index bc6fbc0..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2008 - INRIA
- *
- * Copyright (C) 2012 - 2016 - Scilab Enterprises
- *
- * This file is hereby licensed under the terms of the GNU GPL v2.0,
- * pursuant to article 5.3.4 of the CeCILL v.2.1.
- * This file was originally licensed under the terms of the CeCILL v2.1,
- * and continues to be available under such terms.
- * For more information, see the COPYING file which you should have received
- * along with this program.
- *
- -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns5="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="setdiff" xml:lang="pt">
-    <refnamediv>
-        <refname>setdiff</refname>
-        <refpurpose>retorna componentes de um vetor que não pertecem a outro
-            vetor
-        </refpurpose>
-    </refnamediv>
-    <refsynopsisdiv>
-        <title>Seqüência de Chamamento</title>
-        <synopsis>v=setdiff(a,b)
-            [v,ka]=setdiff(a,b)
-        </synopsis>
-    </refsynopsisdiv>
-    <refsection>
-        <title>Parâmetros</title>
-        <variablelist>
-            <varlistentry>
-                <term>a</term>
-                <listitem>
-                    <para>vetor de números reais ou strings </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>b</term>
-                <listitem>
-                    <para>vetor de números reais ou strings </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>v</term>
-                <listitem>
-                    <para>vetor de números reais ou strings com a mesma orientação de
-                        <literal>a</literal>
-                    </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>ka</term>
-                <listitem>
-                    <para>vetor linha de inteiros, ka(i) é a localização de v(i) em
-                        a
-                    </para>
-                </listitem>
-            </varlistentry>
-        </variablelist>
-    </refsection>
-    <refsection>
-        <title>Descrição</title>
-        <para>
-            <literal>setdiff(a,b)</literal> retorna um vetor ordenado que retém
-            as entradas de <literal>a</literal> que não estão em
-            <literal>b</literal>
-        </para>
-        <para>
-            <literal>[v,ka]=setdiff(a,b)</literal> retorna um vetor ordenado que
-            retém as entradas de <literal>a</literal> que não estão em
-            <literal>b</literal> e a localização destas entradas em a.
-        </para>
-    </refsection>
-    <refsection>
-        <title>Exemplos </title>
-        <programlisting role="example"><![CDATA[
-a = [223;111;2;4;2;2];
-b = [2;3;21;223;123;22];
-setdiff(a,b)
-[v,k]=setdiff(string(a),string(b))
- ]]></programlisting>
-    </refsection>
-    <refsection role="see also">
-        <title>Ver Também</title>
-        <simplelist type="inline">
-            <member>
-                <link linkend="unique">unique</link>
-            </member>
-            <member>
-                <link linkend="gsort">gsort</link>
-            </member>
-            <member>
-                <link linkend="union">union</link>
-            </member>
-        </simplelist>
-    </refsection>
-</refentry>
index 2ecb4b3..5adf70a 100644 (file)
@@ -2,8 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2008 - INRIA
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2018 - Samuel GOUGEON
  *
  * This file is hereby licensed under the terms of the GNU GPL v2.0,
  * pursuant to article 5.3.4 of the CeCILL v.2.1.
  * along with this program.
  *
  -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns: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="setdiff" xml:lang="ru">
+<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="setdiff" xml:lang="ru">
     <refnamediv>
         <refname>setdiff</refname>
-        <refpurpose>возвращает элементы вектора, которые не принадлежат другому вектору</refpurpose>
+        <refpurpose>
+            возвращает элементы или строк или столбцов массива, которые не принадлежат другому массиву
+        </refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Синтаксис</title>
-        <synopsis>v=setdiff(a,b)
-            [v,ka]=setdiff(a,b)
+        <synopsis>
+            v = setdiff(a, b)
+            v = setdiff(a, b, orien)
+            [v, ka] = setdiff(..)
         </synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Аргументы</title>
         <variablelist>
             <varlistentry>
-                <term>a</term>
+                <term>a, b</term>
                 <listitem>
-                    <para>вектор вещественных чисел или строк</para>
+                    <para>
+                        векторы, матрицы или гиперматрицы вещественных чисел или кодированных 
+                        целых чисел или строк. Оба должны иметь одинаковые типы данных (или типы 
+                        целых чисел).
+                    </para>
+                    <para>
+                        Если используется опция <literal>orien="r"</literal>, то 
+                        <literal>a</literal> и <literal>b</literal> должны иметь одинаковое 
+                        количество столбцов. Если используется <literal>orien="c"</literal>, то 
+                        они должны иметь одинаковое количество строк.
+                    </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>b</term>
+                <term>orien</term>
                 <listitem>
-                    <para>вектор вещественных чисел или строк</para>
+                    направленная обработка:
+                    <itemizedlist>
+                        <listitem>
+                            <literal>"r"</literal>: строки из <literal>a</literal> ищутся среди строк в <literal>b</literal>.
+                        </listitem>
+                        <listitem>
+                            <literal>"c"</literal>: столбцы из <literal>a</literal> ищутся среди
+                            столбцов в <literal>b</literal>.
+                        </listitem>
+                        <listitem>
+                            <varname>orien</varname> не указано: элементы из <literal>a</literal> 
+                            ищутся среди элементов <literal>b</literal>.
+                        </listitem>
+                    </itemizedlist>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>v</term>
                 <listitem>
-                    <para>
-                        вектор вещественных чисел или строк с той же ориентацией, что и у                 <literal>a</literal>
-                    </para>
+                    <itemizedlist>
+                        <listitem>
+                            сортированный вектор из компонентов <literal>a</literal>, которые 
+                            отсутствуют в <literal>b</literal>.
+                        </listitem>
+                        <listitem>
+                            <literal>orien="r"</literal>: матрица строк из <literal>a</literal>,
+                            которые отсутствуют в <literal>b</literal>, отсортированный в 
+                            лексикографическом порядке.
+                        </listitem>
+                        <listitem>
+                            <literal>orien="c"</literal>: матрица столбцов из 
+                            <literal>a</literal>, которые отсутствуют в <literal>b</literal>, 
+                            отсортированный в лексикографическом порядке.
+                        </listitem>
+                    </itemizedlist>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>ka</term>
                 <listitem>
                     <para>
-                        вектор-строка целых чисел, <literal>ka(i)</literal> - положение
-                        <literal>v(i)</literal> в <literal>a</literal>
+                        вектор линейный индексов выбранных элементов, строк, столбцов из 
+                        <literal>a</literal> таких, что
+                        <itemizedlist>
+                            <listitem>
+                                <literal>v = a(ka)</literal> либо
+                            </listitem>
+                            <listitem>
+                                <literal>v = a(ka,:)</literal> (<literal>orien="r"</literal>) либо
+                            </listitem>
+                            <listitem>
+                                <literal>v = a(:,ka)</literal> (<literal>orien="c"</literal>)
+                            </listitem>
+                        </itemizedlist>
                     </para>
                 </listitem>
             </varlistentry>
     <refsection>
         <title>Описание</title>
         <para>
-            <literal>setdiff(a,b)</literal> возвращает отсортированный вектор, который содержит
-            элементы <literal>a</literal>, которые отсутствуют в <literal>b</literal>.
+            <literal>setdiff(a, b,..)</literal> вычисляет и возвращает элементы либо строк либо 
+            столбцов из <literal>a</literal> которые ОТСУТСТВУЮТ в <literal>b</literal>.
         </para>
         <para>
-            <literal>[v,ka]=setdiff(a,b)</literal> возвращает отсортированный вектор, который
-            содержит элементы <literal>a</literal>, отсутствующие в <literal>b</literal> и
-            положение этих элементов в <literal>a</literal>.
+            Все дупликаты (элементы или строк или столбцов) удаляются из <literal>a</literal> и
+            из <literal>b</literal> перед обработкой.
+        </para>
+        <para>
+            Если <literal>a</literal> - гиперматрица и используется опция <literal>"r"</literal>, 
+            то перед обработкой <literal>a</literal> заменяется матрицей, состоящией из строк по 
+            всем своим более высоким размерностям. То же самое и в случае, если 
+            <literal>b</literal> является гиперматрицей. Если исползуется опция 
+            <literal>"c"</literal>, то <literal>a</literal> или/и <literal>"b"</literal> 
+            заменяются соответствующими матрицами, состоящими из всех своих столбцов.
+        </para>
+        <para>
+            Формат результатов представлен в следующей таблице, в соответствии с формой
+            <literal>a</literal> и опцией <literal>orien</literal>. Во всех случаях, если все элементы <literal>a</literal> находятся в <literal>b</literal>, возвращается
+            <literal>[]</literal> для <literal>v</literal> как для <literal>ka</literal>:
+            <table>
+                <tr>
+                    <th align="right">orien →</th>
+                    <td colspan="2" align="center"><emphasis role="bold">отсутствует</emphasis></td>
+                    <td colspan="2" align="center"><emphasis role="bold">"r"</emphasis></td>
+                    <td colspan="2" align="center"><emphasis role="bold">"c"</emphasis></td>
+                </tr>
+                <tr>
+                    <th>a ↓</th><th>v</th><th>ka</th><th>v</th><th>ka</th><th>v</th><th>ka</th>
+                </tr>
+                <tr>
+                    <td align="right"><emphasis role="bold">строка</emphasis></td>
+                    <td>cтр</td><td>cтр</td>
+                    <td>cтр</td><td>скал</td>
+                    <td>cтр</td><td>cтр</td>
+                </tr>
+                <tr>
+                    <td align="right"><emphasis role="bold">столбец</emphasis></td>
+                    <td>cтлб</td><td>cтлб</td>
+                    <td>cтлб</td><td>cтлб</td>
+                    <td>cтлб</td><td>скал</td>
+                </tr>
+                <tr>
+                    <td align="right"><emphasis role="bold">матрица</emphasis></td>
+                    <td>cтлб</td><td>cтлб</td>
+                    <td>матр</td><td>cтлб</td>
+                    <td>матр</td><td>cтр</td>
+                </tr>
+                <tr>
+                    <td align="right"><emphasis role="bold">гиперматрица</emphasis></td>
+                    <td>cтлб</td><td>cтлб</td>
+                    <td>матр</td><td>cтлб</td>
+                    <td>матр</td><td>cтр</td>
+                </tr>
+                <tr align="center">
+                    <td align="right"><emphasis role="bold">скаляр</emphasis></td>
+                    <td>скал</td><td>скал</td>
+                    <td>скал</td><td>скал</td>
+                    <td>скал</td><td>скал</td>
+                </tr>
+            </table>
+        </para>
+        <para>
+            <literal>v</literal> и <literal>ka</literal> становятся пустыми 
+            <literal>[]</literal>, если <literal>a</literal> пуста (либо <literal>b</literal>), или все элементы <literal>a</literal> находятся в <literal>b</literal>.
         </para>
     </refsection>
     <refsection>
         <title>Примеры</title>
+        <para>
+            <emphasis role="bold">Пример №1:</emphasis>
+        </para>
         <programlisting role="example"><![CDATA[
-a = [223;111;2;4;2;2];
-b = [2;3;21;223;123;22];
-setdiff(a,b)
-[v,k]=setdiff(string(a),string(b))
+a = grand(1, 10,"uin", 0, 9)
+b = grand(2, 4, "uin", 0, 9)
+[d, k] = setdiff(a, b);
+d, k
  ]]></programlisting>
+    <screen><![CDATA[
+--> a = grand(1, 10,"uin", 0, 9)
+ a  =
+   2.   2.   4.   5.   4.   1.   9.   5.   8.   3.
+--> b = grand(2, 4, "uin", 0, 9)
+ b  =
+   5.   0.   9.   9.
+   5.   6.   0.   4.
+--> [d, k] = setdiff(a, b);
+--> d, k
+ d  =
+   1.   2.   3.   8.
+ k  =
+   6.   1.   10.   9.
+ ]]></screen>
+        <para>
+            <emphasis role="bold">Пример №2: постолбцовая обработка</emphasis>
+        </para>
+        <programlisting role="example"><![CDATA[
+a = grand(2, 7,"uin", 0, 3)
+b = grand(2, 10, "uin", 0, 3)
+[d, k] = setdiff(a, b, "c");
+d, k
+ ]]></programlisting>
+    <screen><![CDATA[
+--> a = grand(2, 7,"uin", 0, 3)
+ a  =
+   0.   1.   0.   2.   3.   0.   2.
+   2.   2.   2.   1.   0.   1.   2.
+--> b = grand(2, 10, "uin", 0, 3)
+ b  =
+   1.   1.   3.   1.   1.   1.   3.   0.   2.   0.
+   3.   3.   2.   2.   0.   0.   1.   0.   1.   0.
+--> [d, k] = setdiff(a, b, "c");
+--> d, k
+ d  =
+   0.   0.   2.   3.
+   1.   2.   2.   0.
+ k  =
+   6.   1.   7.   5.
+ ]]></screen>
+        <para>
+            <emphasis role="bold">Пример №3: с текстом</emphasis>
+        </para>
+        <programlisting role="example"><![CDATA[
+v1 = tokens("ab  ca  ba  bb  ca  cb  ba  aa  cc  bc  ac  aa")'
+v2 = tokens("cc  ac  ca  bb  ac  bc  ab")'
+[r, k] = setdiff(v1, v2);
+r, k
+]]></programlisting>
+    <screen><![CDATA[
+--> v1 = tokens("ab  ca  ba  bb  ca  cb  ba  aa  cc  bc  ac  aa")'
+ v1  =
+!ab  ca  ac  bb  ca  cb  ba  aa  cc  bc  ac  aa  !
+--> v2 = tokens("cc  ac  ca  bb  ac  bc  ab")'
+ v2  =
+!cc  ac  ca  bb  ac  bc  ab  !
+--> [r, k] = setdiff(v1, v2);
+--> r, k
+ r  =
+!aa  ba  cb  !
+ k  =
+   8.   3.   6.
+]]></screen>
     </refsection>
     <refsection role="see also">
         <title>Смотрите также</title>
@@ -86,11 +264,31 @@ setdiff(a,b)
                 <link linkend="unique">unique</link>
             </member>
             <member>
-                <link linkend="gsort">gsort</link>
+                <link linkend="union">union</link>
             </member>
             <member>
-                <link linkend="union">union</link>
+                <link linkend="members">members</link>
+            </member>
+            <member>
+                <link linkend="vertorfind">vectorfind</link>
             </member>
         </simplelist>
     </refsection>
+    <refsection role="history">
+        <title>История</title>
+        <revhistory>
+            <revision>
+                <revnumber>&lt; 5.0</revnumber>
+                <revdescription>
+                    Функция введена.
+                </revdescription>
+            </revision>
+            <revision>
+                <revnumber>6.0.2</revnumber>
+                <revdescription>
+                    Добавлены опции "r" | "c", включая гиперматрицы.
+                </revdescription>
+            </revision>
+        </revhistory>
+    </refsection>
 </refentry>
index 75831ba..e7e8180 100644 (file)
@@ -1,8 +1,8 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) INRIA
 // Copyright (C) DIGITEO - 2011 - Allan CORNET
-//
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2018 - Samuel GOUGEON
 //
 // This file is hereby licensed under the terms of the GNU GPL v2.0,
 // pursuant to article 5.3.4 of the CeCILL v.2.1.
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-function [a, ka] = setdiff(a, b)
+function [a, ka] = setdiff(a, b, orien)
     // returns a values which are not in b
 
+    // History:
+    // * 2018 - S. Gougeon : orien="r"|"c" added, including the hypermat case
+
     rhs = argn(2);
-    if rhs <> 2 then
-        error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "setdiff", 2));
-    end
 
-    if b == [] then //b is empty reurn a!
-        ka = 1:size(a,"*");
+    // CHECKING INPUT ARGUMENTS
+    // ========================
+    if rhs < 2 | rhs > 3 then
+        msg = gettext("%s: Wrong number of input argument(s): %d or %d expected.\n");
+        error(msprintf(msg, "setdiff", 2, 3));
+    end
+    // Trivial case _whatever is b_
+    if a==[]
+        ka = []
         return
     end
-
-    [a,ka] = unique(a);
-    na = size(a,"*");
-
-    b = unique(b(:));
-
-    if type(a) == 10 then
-        [x,k] = gsort([a(:); b], "g", "i");
+    // orien
+    if ~isdef("orien","l") then
+        orien = 0
+    elseif orien~="r" & orien~="c" & orien~=1 & orien~=2
+        msg = gettext("%s: Argument #%d: Must be in the set {%s}.\n");
+        error(msprintf(msg, "setdiff", 3, "''r'',''c'',1,2"));
+    elseif orien=="c"
+        orien = 2
+    elseif orien=="r"
+        orien = 1
+    end
+    if orien==1 & size(a,2)~=size(b,2) then
+        msg = _("%s: Arguments #%d and #%d: Same numbers of columns expected.\n")
+        error(msprintf(msg, "setdiff", 1, 2))
+    end
+    if orien==2 & size(a,1)~=size(b,1) then
+        msg = _("%s: Arguments #%d and #%d: Same numbers of rows expected.\n")
+        error(msprintf(msg, "setdiff", 1, 2))
+    end
+    
+    // PROCESSING
+    // ==========
+    // "r" or "c"
+    // ----------
+    if orien then
+        it = inttype(a)
+        if ndims(a)>2 then
+            a = serialize_hypermat(a, orien)
+        elseif orien==2
+            a = a.'
+        end
+        // Trivial case
+        if b == [] then
+            ka = 1:size(a,orien);
+            if orien==1
+                ka = ka'
+            end
+            return
+        end
+        if ndims(b)>2 then
+            b = serialize_hypermat(b, orien)
+        elseif orien==2
+            b = b.'
+        end
+        [a, ka] = unique(a, "r")
+        b = unique(b, "r")
+        [c, kc] = gsort([[a iconvert(ones(a(:,1)),it)] ;
+                         [b iconvert(ones(b(:,1))*2,it)]], "lr","i")
+        k = find(or(c(1:$-1,1:$-1)~=c(2:$,1:$-1),"c") & c(1:$-1,$)==1)
+        if c($,$)==1
+            k = [k size(c,1)]
+        end
+        ka = ka(kc(k))
+        // a = a(ka,:) // in initial order
+        a = c(k,1:$-1)
+        if orien==2
+            ka = ka'
+            a = a.'
+        end
     else
-        [x,k] = gsort([a(:); b], "g", "d");
+        // by element
+        // ----------
+        [a,ka] = unique(a);
+        na = size(a,"*");
+    
+        b = unique(b(:));
+    
+        [x,k] = gsort([a(:); b], "g", "i");
+        d = find(x(2:$)==x(1:$-1));  //index of common entries in sorted table
+        if d <> [] then
+            k([d;d+1]) = [];
+        end
+    
+        keep = find(k <= na);
+        a = a(k(keep));
+        ka = ka(k(keep));
     end
-    if type(a) == 1 then x=x($:-1:1);k=k($:-1:1);,end
-    d = find(x(2:$)==x(1:$-1));  //index of common entries in sorted table
-    if d <> [] then
-        k([d;d+1]) = [];
+endfunction
+// ----------------------------------------------------------------------------
+function h = serialize_hypermat(h, orien)
+    if orien==1 then
+        dims = 1:ndims(h)
+        dims([1 2]) = [2 1]
+        h = permute(h, dims)
     end
-
-    keep = find(k <= na);
-    a = a(k(keep));
-    ka = ka(k(keep));
+    h = matrix(h, size(h,1), -1).'
 endfunction
diff --git a/scilab/modules/elementary_functions/tests/unit_tests/setdiff.dia.ref b/scilab/modules/elementary_functions/tests/unit_tests/setdiff.dia.ref
deleted file mode 100644 (file)
index 842dee6..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2009 - DIGITEO - Allan CORNET
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-// <-- CLI SHELL MODE -->
-// =============================================================================
-a = [223;111;2;4;2;2];
-b = [2;3;21;223;123;22];
-// =============================================================================
-REF_V = [4; 111];
-REF_K = [4; 2];
-[v,k]= setdiff(a,b);
-if and(v == REF_V) <> %t then bugmes();quit;end
-if and(k == REF_K) <> %t then bugmes();quit;end
-// =============================================================================
-REF_V = ['111' ; '4'];
-REF_K = [2; 4];
-[v,k] = setdiff(string(a),string(b));
-if and(v == REF_V) <> %t then bugmes();quit;end
-if and(k == REF_K) <> %t then bugmes();quit;end
-// =============================================================================
index b96e1d1..e5ceb60 100644 (file)
 // =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Scilab ( http://wwwscilaborg/ ) - This file is part of Scilab
 // Copyright (C) 2009 - DIGITEO - Allan CORNET
+// Copyright (C) 2018 - Samuel GOUGEON
 //
-//  This file is distributed under the same license as the Scilab package.
+//  This file is distributed under the same license as the Scilab package
 // =============================================================================
 // <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+// <-- ENGLISH IMPOSED -->
 // =============================================================================
+
 a = [223;111;2;4;2;2];
 b = [2;3;21;223;123;22];
+REF_K = [4 ; 2];
+for f = list(double, int8, uint8, int16, uint16, int32, uint32, int64, uint64)
+    REF_V = f([4 ; 111]);
+    [v,k]= setdiff(f(a), f(b));
+    assert_checkequal(v, REF_V);
+    assert_checkequal(k, REF_K);
+end
+
 // =============================================================================
-REF_V = [4; 111];
-REF_K = [4; 2];
-[v,k]= setdiff(a,b);
-if and(v == REF_V) <> %t then pause,end
-if and(k == REF_K) <> %t then pause,end
-// =============================================================================
+
 REF_V = ['111' ; '4'];
 REF_K = [2; 4];
 [v,k] = setdiff(string(a),string(b));
 if and(v == REF_V) <> %t then pause,end
 if and(k == REF_K) <> %t then pause,end
-// =============================================================================
\ No newline at end of file
+
+// =============================================================================
+s  = 7;
+s2 = 5;
+r  = [14   0  4  7   8  15   7  17  15  12];
+r2 = [ 2  11  1  0  15   7  10   5];
+c  = r';
+c2 = r2';
+m  = [
+   1  3  2  0  0  0  1  2  1  3
+   1  3  2  1  3  1  2  3  1  0
+];
+m2  = [
+   0  3  1  1  3  2  0  2  0
+   2  0  0  2  2  1  2  2  3
+ ];
+h = cat(3, m(:,1:6), m2(:,1:6));
+h2 = cat(3, m([2 1],1:6), m2([2 1],1:6));
+L  = list(s,  r,  c,  m,  h);
+L2 = list(s2, r2, c2, m2, h2);
+msgr = "setdiff: Arguments #1 and #2: Same numbers of columns expected.";
+msgc = "setdiff: Arguments #1 and #2: Same numbers of rows expected.";
+
+// With a=[] , orien = none|"r"|"c"
+// --------------------------------
+for i = 1:length(L)
+    o = L(i);
+    [va, ka] = setdiff([], o);
+    assert_checkequal(va, []);
+    assert_checkequal(ka, []);
+    [va, ka] = setdiff([], o, "r");
+    assert_checkequal(va, []);
+    assert_checkequal(ka, []);
+    [va, ka] = setdiff([], o, "c");
+    assert_checkequal(va, []);
+    assert_checkequal(ka, []);
+    assert_checkerror("setdiff(o, [], ''r'')", msgr);
+    assert_checkerror("setdiff(o, [], ''c'')", msgc);
+end
+
+// "r" and "c" options
+// -------------------
+for f = list(double, int8, uint8, int16, uint16, int32, uint32, int64, uint64)
+    // With row vectors
+    [rr,k] = setdiff(f(r), f([r2 0 2]), "r");
+    assert_checkequal(rr, f(r));
+    assert_checkequal(k, 1);
+    [rc,k] = setdiff(f(r), f(r2), "c");
+    assert_checkequal(rc, f([4  8  12  14  17]));
+    assert_checkequal(k,    [3  5  10   1   8]);
+
+    // With column vectors
+    [rc,k] = setdiff(f(r'), f([r2 0 2]'), "c");
+    assert_checkequal(rc, f(r'));
+    assert_checkequal(k, 1);
+    [rr,k] = setdiff(f(r'), f(r2'), "r");
+    assert_checkequal(rr, f([4  8  12  14  17]'));
+    assert_checkequal(k,    [3  5  10   1  8]');
+
+    // With matrices
+    [mc,k] = setdiff(f(m), f(m2), "c");
+    assert_checkequal(mc, f([0  1  2  3
+                             1  1  3  3]));
+    assert_checkequal(k,    [4  1  8  2]);
+    [mr,k] = setdiff(f(m'), f(m2'), "r");
+    assert_checkequal(mr, f([0  1  2  3
+                            1  1  3  3]'));
+    assert_checkequal(k,   [4  1  8  2]');
+
+    // With hypermatrices
+    [hc,k] = setdiff(f(h), f(h2), "c");
+    assert_checkequal(hc, f([0  3
+                             2  2]));
+    assert_checkequal(k,    [7 11]);
+
+    hr  = permute(h, [2 1 3]);
+    h2r = permute(h2,[2 1 3]);
+    [hr,k] = setdiff(f(hr), f(h2r), "r");
+    assert_checkequal(hr, f([0  2
+                             3  2]));
+    assert_checkequal(k,    [7 11]');
+end