* Bug 15734 fixed: intersect() dit not support complex numbers 25/20725/11
Samuel GOUGEON [Mon, 21 Jan 2019 06:25:28 +0000 (07:25 +0100)]
  http://bugzilla.scilab.org/15734

  + speed up: ka and kb were computed while not requested

Change-Id: Ie502fbf2bea4d5a1f2ad24833351c34b2c1ef841

scilab/CHANGES.md
scilab/modules/elementary_functions/help/en_US/setoperations/intersect.xml
scilab/modules/elementary_functions/help/fr_FR/setoperations/intersect.xml
scilab/modules/elementary_functions/macros/intersect.sci
scilab/modules/elementary_functions/tests/nonreg_tests/bug_15734.tst [new file with mode: 0644]
scilab/modules/elementary_functions/tests/unit_tests/intersect.dia.ref [deleted file]
scilab/modules/elementary_functions/tests/unit_tests/intersect.tst

index 25d3e8c..573c164 100644 (file)
@@ -142,6 +142,7 @@ Feature changes and additions
 * Booleans and encoded integers can now be concatenated together, as in `[%f int8(-5)]`.
 * `gsort` can now perform multilevel sorting. This noticeably allows to sort completely complex numbers.
 * `factorial(n)` can be used now from n=171 up to n=10^14.
+* `intersect()` now supports complex numbers.
 
 
 Help pages:
@@ -281,6 +282,7 @@ Bug Fixes
 * [#15595](http://bugzilla.scilab.org/show_bug.cgi?id=15595): `unique()` was not able to return distinct values in their original order, without sorting them. A `keepOrder` option now allows it.
 * [#15668](http://bugzilla.scilab.org/show_bug.cgi?id=15668): `save(filename)` saved all predefined Scilab constants %e %pi etc.. (regression)
 * [#15715](http://bugzilla.scilab.org/show_bug.cgi?id=15715): `%nan` indices crashed Scilab.
+* [#15734](http://bugzilla.scilab.org/show_bug.cgi?id=15734): `intersect()` did not support complex numbers.
 * [#15742](http://bugzilla.scilab.org/show_bug.cgi?id=15742): The `compatibility_functions` module should be merged in the `m2sci` one.
 * [#15581](http://bugzilla.scilab.org/show_bug.cgi?id=15581): display of complex matrix was ugly.
 * [#15628](http://bugzilla.scilab.org/show_bug.cgi?id=15628): `with_tk` was a duplicate of `with_module('tclsci')`. It is removed.
index 2038204..fcf8a18 100644 (file)
             <varlistentry>
                 <term>a, b</term>
                 <listitem>
-                    <para>
-                        vectors, matrices or hypermatrices of encoded integers, decimal real
-                        numbers, or text. <varname>a</varname> and <varname>b</varname> must have
-                        the same datatype, but have independent sizes.
-                        For text inputs, UTF characters are accepted.
-                    </para>
+                    vectors, matrices or hypermatrices of encoded integers, real or complex
+                    numbers, or text. <varname>a</varname> and <varname>b</varname> must have
+                    the same datatype, but have independent sizes.
+                    For text inputs, UTF characters are accepted.
+                    <para/>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>orient</term>
                 <listitem>
-                    <para>
-                        flag with possible values : 1 or "r", 2 or "c". Can't be used if
-                        <varname>a</varname> or/and <varname>b</varname> is an hypermatrix.
-                    </para>
+                    flag with possible values : 1 or "r", 2 or "c". Can't be used if
+                    <varname>a</varname> or/and <varname>b</varname> is an hypermatrix.
+                    <para/>
                 </listitem>
             </varlistentry>
             <varlistentry>
             <varlistentry>
                 <term>ka</term>
                 <listitem>
-                    <para>
-                        row vector of indices in <varname>a</varname>.
-                    </para>
+                    row vector of indices in <varname>a</varname>.
+                    <para/>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>kb</term>
                 <listitem>
-                    <para>
-                        row vector of indices in <varname>b</varname>.
-                    </para>
+                    row vector of indices in <varname>b</varname>.
+                    <para/>
                 </listitem>
             </varlistentry>
         </variablelist>
     <refsection>
         <title>Description</title>
         <para>
-            <literal>intersect(a,b)</literal> returns a row vector of unduplicated sorted values
-            present in both <literal>a</literal> and <literal>b</literal> arrays.
+            <literal>intersect(a,b)</literal> returns a row vector of unduplicated values
+            present in both <literal>a</literal> and <literal>b</literal> arrays. Values are
+            sorted in increasing order
+            <itemizedlist>
+                <listitem>
+                    for complex numbers : par increasing magnitudes, then by increasing phases
+                </listitem>
+                <listitem>
+                    for text : in alphabetical order.
+                </listitem>
+            </itemizedlist>
         </para>
         <warning>
             Two NaN elements are always considered as different. So NaN or rows or columns having
@@ -271,4 +276,15 @@ M, ka, kb
             </member>
         </simplelist>
     </refsection>
+    <refsection role="history">
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revdescription>
+                    complex numbers are now accepted.
+                </revdescription>
+            </revision>
+        </revhistory>
+    </refsection>
 </refentry>
index 2ab8d4e..7ba3b1b 100644 (file)
             <varlistentry>
                 <term>a, b</term>
                 <listitem>
-                    <para>
-                        vecteurs, matrices ou hypermatrices d'entiers encodés, de nombres décimaux
-                        réels, ou de texte. <varname>a</varname> et <varname>b</varname> doivent
-                        être du même type de données, mais ont des tailles indépendantes.
-                        Pour les données texte, les caractères UTF sont admis.
-                    </para>
+                    vecteurs, matrices ou hypermatrices d'entiers encodés, de nombres réels ou
+                    complexes, ou de texte. <varname>a</varname> et <varname>b</varname> doivent
+                    être du même type de données, mais ont des tailles indépendantes.
+                    Pour les données texte, les caractères UTF sont admis.
+                    <para/>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>orient</term>
                 <listitem>
-                    <para>
-                        indicateur de traitement par colonnes ou lignes. Valeurs possibles :
-                        1 ou "r", 2 ou "c". Ne peut pas être utilisé lorsque <varname>a</varname>
-                        ou/et <varname>b</varname> est une hypermatrice.
-                    </para>
+                    indicateur de traitement par colonnes ou lignes. Valeurs possibles :
+                    1 ou "r", 2 ou "c". Ne peut pas être utilisé lorsque <varname>a</varname>
+                    ou/et <varname>b</varname> est une hypermatrice.
+                    <para/>
                 </listitem>
             </varlistentry>
             <varlistentry>
             <varlistentry>
                 <term>ka</term>
                 <listitem>
-                    <para>
-                        Vecteur ligne d'indices dans <varname>a</varname>.
-                    </para>
+                    Vecteur ligne d'indices dans <varname>a</varname>.
+                    <para/>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>kb</term>
                 <listitem>
-                    <para>
-                        Vecteur lignes d'indices dans <varname>b</varname>.
-                    </para>
+                    Vecteur lignes d'indices dans <varname>b</varname>.
+                    <para/>
                 </listitem>
             </varlistentry>
         </variablelist>
         <para>
             <literal>intersect(a,b)</literal> produit un vecteur ligne des éléments dédoublonnés
             présents à la fois dans les tableaux <literal>a</literal> et <literal>b</literal>,
-            triés en ordre croissant.
+            triés en ordre croissant
+            <itemizedlist>
+                <listitem>
+                    pour les nombres complexes : par modules croissants, puis par phases croissantes.
+                </listitem>
+                <listitem>
+                    pour le texte : par ordre alphabétique.
+                </listitem>
+            </itemizedlist>
         </para>
         <warning>
             Deux éléments NaN étant toujours considérés comme différents, NaN ou les lignes ou
@@ -274,4 +278,15 @@ M, ka, kb
             </member>
         </simplelist>
     </refsection>
+    <refsection role="history">
+        <title>Historique</title>
+        <revhistory>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revdescription>
+                    Les nombres complexes sont désormais acceptés.
+                </revdescription>
+            </revision>
+        </revhistory>
+    </refsection>
 </refentry>
index 5fd2e79..6ddb663 100644 (file)
@@ -1,8 +1,8 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) INRIA - Serge Steer
 // Copyright (C) DIGITEO - 2011 - Allan CORNET
-//
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2019 - 2020 - 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.
 function [x_out, ka_out, kb_out] = intersect(a_in, b_in, orient)
     // returns the vector of common values of two vectors
 
-    rhs = argn(2);
+    [lhs, rhs] = argn();
+    x_out = []
+    ka_out = []
+    kb_out = []
+
     if rhs < 2 then
-        error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "intersect", 2));
+        msg = gettext("%s: Wrong number of input arguments: %d or %d expected.\n")
+        error(msprintf(msg, "intersect", 2, 3))
     end
 
-    if ( (a_in == [])| (b_in == []) ) then
-        x_out = [];
-        ka_out = [];
-        kb_out = [];
+    if a_in == [] | b_in == [] then
         return
     end
-    if argn(2)<3 then
-        //remove duplicate values in a_in and b_in
+    aIsComplex = type(a_in)==1 && ~isreal(a_in);
+    bIsComplex = type(b_in)==1 && ~isreal(b_in);
+
+    // Without orientation
+    // -------------------
+    if ~isdef("orient","l") then
+        if lhs == 1
+            a = unique(matrix(a_in, 1, -1));
+            b = unique(matrix(b_in, 1, -1));
+            if aIsComplex | bIsComplex
+                x = gsort([a, b], "g", ["i" "i"], list(abs, atan));
+            else
+                x = gsort([a, b], "g", "i");
+            end
+            keq = find( x(2:$) == x(1:$-1) ); // find consecutive equal values index
+            if keq <> [] then
+                x_out = x(keq); //the intersection values in increasing order
+            end
+            return
+        end
+        // lhs > 1
+        // .......
         [a, ka] = unique(matrix(a_in, 1, -1));
         [b, kb] = unique(matrix(b_in, 1, -1));
         kab = [ka, -kb];
-        //find duplicated values in [a_in,b_in],
-        [x,ksort] = gsort([a, b], "g", "i"); //sort the array
-
-        kab = kab(ksort); //apply [a_in,b_in] sorting permutation to kab
-        keq = find( x(2:$) == x(1:$-1) ); // find consecutive equal values index
-
-        if keq == [] then
-            //the intersection is empty
-            x_out = [];
-            ka_out = [];
-            kb_out = [];
+        // find duplicated values in [a_in,b_in],
+        // sort the array
+        if aIsComplex | bIsComplex then
+            [x, ksort] = gsort([a, b], "g", ["i" "i"], list(abs, atan));
         else
-            x_out = x(keq); //the intersection values in increasing order
-            if argn(1) > 1 then //build the output index
-                // each duplicated value appear twice  and only twice and in
-                // consecutive positions keq(i) and keq(i)+1 in the sorted array x
-                kab = kab([keq keq+1]);
-
-                //the positive values correspond to a_in index while the negative to b_in index.
-                ka_out = kab(kab > 0); //select index of intersection elements in a_in
-                kb_out = -kab(kab < 0); //select index of intersection elements in b_in
+            [x, ksort] = gsort([a, b], "g", "i");
+        end
+        kab = kab(ksort); // apply [a_in,b_in] sorting permutation to kab
+        keq = find( x(2:$) == x(1:$-1) ); // find consecutive equal values index
 
-                //insure that a_in(ka_out)==x_out and b_in(kb_out)==x_out.
-                //I was'nt able to find a simple way.
+        if keq <> [] then
+            x_out = x(keq); // the intersection values in increasing order
+            // each duplicated value appear twice  and only twice and in
+            // consecutive positions keq(i) and keq(i)+1 in the sorted array x
+            kab = kab([keq keq+1])
+
+            // the positive values correspond to a_in index while the negative to b_in index.
+            ka_out = kab(kab > 0) // select index of intersection elements in a_in
+            // insure that a_in(ka_out)==x_out and b_in(kb_out)==x_out.
+            // I was'nt able to find a simple way.
+            if aIsComplex
+                [s, k] = gsort(a_in(ka_out), "g", ["i" "i"], list(abs, atan));
+            else
                 [s, k] = gsort(a_in(ka_out), "g", "i");
-                ka_out = ka_out(k);
-                [s, k] = gsort(b_in(kb_out),"g","i");
-                kb_out = kb_out(k);
             end
-        end
-    elseif  orient==1|orient=="r" then
-        //remove duplicate rows in a_in and b_in
-        [a, ka] = unique(a_in, "r");
-        [b, kb] = unique(b_in, "r");
-        kab = [ka; -kb];
-        //find duplicated rows in [a_in;b_in],
+            ka_out = ka_out(k)
 
-        [x,ksort] = gsort([a; b], "lr", "i"); //sort the rows
+            if lhs > 2
+                kb_out = -kab(kab < 0); //select index of intersection elements in b_in
+                if bIsComplex
+                    [s, k] = gsort(b_in(kb_out), "g", ["i" "i"], list(abs, atan));
+                else
+                    [s, k] = gsort(b_in(kb_out), "g", "i");
+                end
+                kb_out = kb_out(k);
+            end
+        end  // keq <> []
+        return
+    end  // rhs < 3
 
-        kab = kab(ksort);//apply [a_in,b_in] sorting permutation to kab
+    // WITH an ORIENTATION
+    // -------------------
+    if ndims(a_in) > 2 | ndims(b_in) > 2 then
+        msg = gettext("%s: Argument #%d: Orientation not supported for hypermatrix.\n")
+        error(msprintf(msg, "intersect", 3))
+    end
+    columnwise = orient==2 | orient=="c"
+    if columnwise then
+        a_in = a_in.'
+        b_in = b_in.'
+    end
+    if and(orient <> [1 2]) & and(orient <> ["r" "c"]) then
+        msg = gettext("%s: Argument #%d: Must be in the set {%s}.\n")
+        error(msprintf(msg, "intersect", 3, "1,''r'',2,''c''"))
+    end
+    // row-wise processing
+    // -------------------
+    if lhs == 1 then
+        a = unique(a_in, "r");
+        b = unique(b_in, "r");
+        if aIsComplex | bIsComplex
+            x = gsort([a ; b], "lr", ["i" "i"], list(abs, atan))
+        else
+            x = gsort([a ; b], "lr", "i")
+        end
         keq = find(and(x(2:$,:) == x(1:$-1,:),"c")) // find index of consecutive equal values
 
         if keq == [] then
-            //the intersection is empty
-            x_out = [];
-            ka_out = [];
-            kb_out = [];
+            return
         else
             x_out = x(keq,:); //the intersection values in increasing order
-
-            if argn(1)>1 then //build the output index
-
-                // each duplicated value appear twice  and only twice and in
-                // consecutive positions keq(i) and keq(i)+1 in the sorted array x
-                kab = kab([keq keq+1]);
-
-                //the positive values correspond to a_in index while the negative to b_in index.
-                ka_out = kab(kab>0); //select index of intersection elements in a_in
-                kb_out = -kab(kab<0); //select index of intersection elements in b_in
-
-                //insure that a_in(ka_out,:)==x_out and b_in(kb_out,:)==x_out.
-                //I was'nt able to find a simple way.
-                [s,k]=gsort(a_in(ka_out,:),"lr","i"); ka_out=ka_out(k)
-                [s,k]=gsort(b_in(kb_out,:),"lr","i"); kb_out=kb_out(k)
-
-
-            end
         end
-    elseif  orient==2|orient=="c" then
-        //remove duplicate columns in a_in and b_in
-        [a,ka]=unique(a_in,"c");
 
-        [b,kb]=unique(b_in,"c");
-        kab=[ka, -kb];
-        //find duplicated rows in [a_in;b_in],
-        [x,ksort] = gsort([a b],"lc","i"); //sort the rows
+    else
+        // ka requested : lhs > 1
+        // ............
+        [a, ka] = unique(a_in, "r");
+        [b, kb] = unique(b_in, "r");
+        kab = [ka; -kb];
+        if aIsComplex | bIsComplex
+            [x,ksort] = gsort([a; b], "lr", ["i" "i"], list(abs, atan));
+        else
+            [x,ksort] = gsort([a; b], "lr", "i");
+        end
 
         kab = kab(ksort);//apply [a_in,b_in] sorting permutation to kab
-        keq = find(and(x(:,2:$) == x(:,1:$-1),"r")) // find index of consecutive equal values
+        keq = find(and(x(2:$,:) == x(1:$-1,:),"c")) // find index of consecutive equal values
 
         if keq == [] then
-            //the intersection is empty
-            x_out = [];
-            ka_out = [];
-            kb_out = [];
+            return
         else
-            x_out =x(:,keq); //the intersection values in increasing order
+            x_out = x(keq,:); //the intersection values in increasing order
 
-            if argn(1)>1 then //build the output index
+            kab = kab([keq keq+1]);
 
-                // each duplicated value appear twice  and only twice and in
-                // consecutive positions keq(i) and keq(i)+1 in the sorted array x
-                kab=kab([keq keq+1]);
+            //the positive values correspond to a_in index while the negative to b_in index.
+            ka_out = kab(kab>0); //select index of intersection elements in a_in
+            //insure that a_in(ka_out,:)==x_out and b_in(kb_out,:)==x_out.
+            //I was'nt able to find a simple way.
+            if aIsComplex
+                [s, k] = gsort(a_in(ka_out,:), "lr", ["i" "i"], list(abs, atan));
+            else
+                [s, k] = gsort(a_in(ka_out,:), "lr", "i");
+            end
+            ka_out = matrix(ka_out(k), 1, -1)
 
-                //the positive values correspond to a_in index while the negative to b_in index.
-                ka_out = kab(kab>0); //select index of intersection elements in a_in
+            if lhs > 2 then
                 kb_out = -kab(kab<0); //select index of intersection elements in b_in
-
-                //insure that a_in(ka_out,:)==x_out and b_in(kb_out,:)==x_out.
-                //I was'nt able to find a simple way.
-                [s,k]=gsort(a_in(:,ka_out),"lc","i"); ka_out=ka_out(k)
-                [s,k]=gsort(b_in(:,kb_out),"lc","i"); kb_out=kb_out(k)
+                if bIsComplex
+                    [s, k] = gsort(b_in(kb_out,:), "lr", ["i" "i"], list(abs, atan));
+                else
+                    [s, k] = gsort(b_in(kb_out,:), "lr", "i");
+                end
+                kb_out = matrix(kb_out(k),1,-1)
             end
         end
-
-    else
-        error(msprintf(gettext("%s: Wrong value for input argument #%d: %d,''%s'',%d or ''%s'' expected\n"),"intersect",3,1,"r",2,"c"));
     end
 
+    // Columnwise post-processing
+    // ..........................
+    if columnwise then
+        x_out = x_out.'
+    end
 endfunction
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_15734.tst b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_15734.tst
new file mode 100644 (file)
index 0000000..771b91c
--- /dev/null
@@ -0,0 +1,21 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2019 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 15734 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/15734
+//
+// <-- Short Description -->
+// intersect() failed with complex numbers
+
+Zc = [%i,-%i];
+assert_checkequal(intersect(Zc,Zc), [-%i %i]);
+assert_checkequal(intersect(Zc,conj(Zc)), [-%i %i]);
diff --git a/scilab/modules/elementary_functions/tests/unit_tests/intersect.dia.ref b/scilab/modules/elementary_functions/tests/unit_tests/intersect.dia.ref
deleted file mode 100644 (file)
index 441633a..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) ????-2008 - INRIA
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-// <-- CLI SHELL MODE -->
-[v,ka,kb] = intersect([],[]);
-if v <> [] then bugmes();quit;end
-if ka <> [] then bugmes();quit;end
-if kb <> [] then bugmes();quit;end
-[v,ka,kb] = intersect([1 2],[3 4]);
-if v <> [] then bugmes();quit;end
-if ka <> [] then bugmes();quit;end
-if kb <> [] then bugmes();quit;end
-A = [ 1 8 4 5 2 1];
-B = [ 9 7 4 2 1 4];
-[v,ka,kb] = intersect(A,B);
-if or(A(ka) <> B(kb)) then bugmes();quit;end
-if or(A(ka) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B))  then bugmes();quit;end
-if (or(v<>[1,2,4])) then bugmes();quit;end
-A = 'a'+string(A);
-B = 'b'+string(B);
-[v,ka,kb] = intersect(A,B);
-if or(A(ka) <> B(kb)) then bugmes();quit;end
-if or(A(ka) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B))  then bugmes();quit;end
-if v <> [] then bugmes();quit;end
-A = [ "elt1" "elt3" "elt4"];
-B = [ "elt5" "elt1" "elt3"];
-[v, ka, kb] = intersect(A,B);
-if or(A(ka) <> B(kb)) then bugmes();quit;end
-if or(A(ka) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B))  then bugmes();quit;end
-if (or(v<>["elt1","elt3"])) then bugmes();quit;end
-A = [ "elt1" "elt3" "elt4"];
-B = [ "elt5" "elt6" "elt2" "elt1" "elt3"];
-[v, ka, kb] = intersect(A,B);
-if or(A(ka) <> B(kb)) then bugmes();quit;end
-if or(A(ka) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B))  then bugmes();quit;end
-if (or(v<>["elt1","elt3"])) then bugmes();quit;end
-//with integers
-A = int16([ 1 8 4 5 2 1]);
-B = int16([ 9 7 4 2 1 4]);
-[v, ka, kb]=intersect(A,B);
-if or(A(ka) <> B(kb)) then bugmes();quit;end
-if or(A(ka) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B))  then bugmes();quit;end
-if (or(v<>int16([1,2,4]))) then bugmes();quit;end
-A = uint8([ 1 8 4 5 2 1]);
-B = uint8([ 9 7 4 2 1 4]);
-[v, ka, kb]=intersect(A,B);
-if or(A(ka) <> B(kb)) then bugmes();quit;end
-if or(A(ka) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B))  then bugmes();quit;end
-if (or(v<>uint8([1,2,4]))) then bugmes();quit;end
-//with matrices
- A = [0,0,1,1 1;
-      0,1,1,1,1;
-      2,0,1,1,1;
-      0,2,2,2,2;
-      2,0,1,1,1;
-      0,0,1,1,3];
-B = [1,0,1;
-     1,0,2;
-     1,2,3;
-     2,0,4;
-     1,2,5;
-     3,0,6];
-[v,ka,kb] = intersect(A,B,'c');
-if or(A(:,ka) <> B(:,kb)) then bugmes();quit;end
-if or(A(:,ka) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B,'c'))  then bugmes();quit;end
-if (or(v<>[0,1;0,1;2,1;0,2;2,1;0,3])) then bugmes();quit;end
-A=A';B=B';
-[v,ka,kb] = intersect(A,B,'r');
-if or(A(ka,:) <> B(kb,:)) then bugmes();quit;end
-if or(A(ka,:) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B,'r'))  then bugmes();quit;end
-if (or(v<>[0,0,2,0,2,0;1,1,1,2,1,3])) then bugmes();quit;end
-A=uint32(A);B=uint32(B);
-[v,ka,kb] = intersect(A,B,'r');
-if or(A(ka,:) <> B(kb,:)) then bugmes();quit;end
-if or(A(ka,:) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B,'r'))  then bugmes();quit;end
-if (or(v<>uint32([0,0,2,0,2,0;1,1,1,2,1,3]))) then bugmes();quit;end
-//with Nan
- A = [0,0,1,1 1;
-      0,1,1,1,1;
-      2,0,1,1,1;
-      0,2,2,2,2;
-      2,0,1,1,1;
-      0,0,1,1,%nan];
-B = [1,0,1;
-     1,0,2;
-     1,2,3;
-     2,0,4;
-     1,2,5;
-     %nan,0,6];
-[v,ka,kb] = intersect(A,B,'c');
-if or(A(:,ka) <> B(:,kb)) then bugmes();quit;end
-if or(A(:,ka) <> v) then bugmes();quit;end
-if or(v<>intersect(A,B,'c'))  then bugmes();quit;end
-if (or(v<>[0;0;2;0;2;0])) then bugmes();quit;end
-// =============================================================================
index 970e508..2c3e62f 100644 (file)
@@ -1,23 +1,23 @@
 // =============================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) ????-2008 - INRIA
+// Copyright (C) 2020 - Samuel GOUGEON
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
 
 // <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
 
-[v,ka,kb] = intersect([],[]);
-if v <> [] then pause,end
-if ka <> [] then pause,end
-if kb <> [] then pause,end
+[v, ka, kb] = intersect([],[]);
+assert_checkequal(v, []);
+assert_checkequal(ka, []);
+assert_checkequal(kb, []);
 
 [v,ka,kb] = intersect([1 2],[3 4]);
-if v <> [] then pause,end
-if ka <> [] then pause,end
-if kb <> [] then pause,end
-
-
+assert_checkequal(v, []);
+assert_checkequal(ka, []);
+assert_checkequal(kb, []);
 
 
 A = [ 1 8 4 5 2 1];
@@ -29,6 +29,8 @@ if or(A(ka) <> v) then pause,end
 if or(v<>intersect(A,B))  then pause,end
 if (or(v<>[1,2,4])) then pause,end
 
+// With texts
+// ----------
 A = 'a'+string(A);
 B = 'b'+string(B);
 [v,ka,kb] = intersect(A,B);
@@ -46,7 +48,6 @@ if or(A(ka) <> v) then pause,end
 if or(v<>intersect(A,B))  then pause,end
 if (or(v<>["elt1","elt3"])) then pause,end
 
-
 A = [ "elt1" "elt3" "elt4"];
 B = [ "elt5" "elt6" "elt2" "elt1" "elt3"];
 
@@ -56,7 +57,13 @@ if or(A(ka) <> v) then pause,end
 if or(v<>intersect(A,B))  then pause,end
 if (or(v<>["elt1","elt3"])) then pause,end
 
-//with integers
+// UTF-8
+A = strsplit("هو برنامج علمي كبير ""Scilab""")'
+B = strsplit("فهو حر ومفتوح")'
+assert_checkequal(intersect(A,B),[" "  "ر"  "م"  "ه"  "و"]);
+
+// with integers
+// ------------
 A = int16([ 1 8 4 5 2 1]);
 B = int16([ 9 7 4 2 1 4]);
 
@@ -75,8 +82,9 @@ if or(A(ka) <> v) then pause,end
 if or(v<>intersect(A,B))  then pause,end
 if (or(v<>uint8([1,2,4]))) then pause,end
 
-//with matrices
- A = [0,0,1,1 1;
+// With orientation: Common rows or columns
+// ----------------------------------------
+A = [0,0,1,1 1;
       0,1,1,1,1;
       2,0,1,1,1;
       0,2,2,2,2;
@@ -88,46 +96,103 @@ B = [1,0,1;
      2,0,4;
      1,2,5;
      3,0,6];
+[v, ka, kb] = intersect(A,B,'c');
+assert_checkequal(v, A(:,ka));
+assert_checkequal(A(:,ka), B(:,kb));
+assert_checkequal(intersect(A,B,'c'), v);
+assert_checkequal(v, [0,1;0,1;2,1;0,2;2,1;0,3]);
+
+A = A'; B = B';
+[v, ka, kb] = intersect(A, B, 'r');
+assert_checkequal(v, A(ka,:));
+assert_checkequal(A(ka,:), B(kb,:));
+assert_checkequal(intersect(A,B,'r'), v);
+assert_checkequal(v, [0,1;0,1;2,1;0,2;2,1;0,3]');
+
+A32 = uint32(A);
+B32 = uint32(B);
+[v, ka, kb] = intersect(A32, B32, 'r');
+assert_checkequal(v, A32(ka,:));
+assert_checkequal(A32(ka,:), B32(kb,:));
+assert_checkequal(intersect(A32,B32,'r'), v);
+assert_checkequal(v, uint32([0,1;0,1;2,1;0,2;2,1;0,3]'));
+
+// with Nan
+// --------
+assert_checkequal(intersect(%nan,%nan), []);
+assert_checkequal(intersect([1 -2 %nan 3 6], [%nan 1:3]), [1 3]);
+
+[A, B] = (A.', B.');
+A($) = %nan;
+B(6,1) = %nan;
 [v,ka,kb] = intersect(A,B,'c');
-if or(A(:,ka) <> B(:,kb)) then pause,end
-if or(A(:,ka) <> v) then pause,end
-if or(v<>intersect(A,B,'c'))  then pause,end
-if (or(v<>[0,1;0,1;2,1;0,2;2,1;0,3])) then pause,end
-
-A=A';B=B';
-[v,ka,kb] = intersect(A,B,'r');
-if or(A(ka,:) <> B(kb,:)) then pause,end
-if or(A(ka,:) <> v) then pause,end
-if or(v<>intersect(A,B,'r'))  then pause,end
-if (or(v<>[0,0,2,0,2,0;1,1,1,2,1,3])) then pause,end
-
-A=uint32(A);B=uint32(B);
-[v,ka,kb] = intersect(A,B,'r');
-if or(A(ka,:) <> B(kb,:)) then pause,end
-if or(A(ka,:) <> v) then pause,end
-if or(v<>intersect(A,B,'r'))  then pause,end
-if (or(v<>uint32([0,0,2,0,2,0;1,1,1,2,1,3]))) then pause,end
-
-//with Nan
- A = [0,0,1,1 1;
-      0,1,1,1,1;
-      2,0,1,1,1;
-      0,2,2,2,2;
-      2,0,1,1,1;
-      0,0,1,1,%nan];
-B = [1,0,1;
-     1,0,2;
-     1,2,3;
-     2,0,4;
-     1,2,5;
-     %nan,0,6];
-
-[v,ka,kb] = intersect(A,B,'c');
-if or(A(:,ka) <> B(:,kb)) then pause,end
-if or(A(:,ka) <> v) then pause,end
-if or(v<>intersect(A,B,'c'))  then pause,end
-if (or(v<>[0;0;2;0;2;0])) then pause,end
-
-
-
-// =============================================================================
+assert_checkequal(v, A(:,ka));
+assert_checkequal(A(:,ka), B(:,kb));
+assert_checkequal(intersect(A,B,'c'), v);
+assert_checkequal(v, [0;0;2;0;2;0]);
+
+// With complex numbers
+// --------------------
+m = [
+  "[1+%i,1+%i,1,0,0,%i,1,1,1,0,1+%i,0,%i,%i,%i,1+%i,1+%i,0,1,1,1,0,0,%i;"
+  "1,0,%i,0,%i,1,1,0,%i,1,0,0,1,1,1+%i,1,1,%i,1+%i,%i,1,0,1+%i,0]"
+  ];
+m = evstr(m).';
+m1 = m(1:$/2,:);
+m2 = m($/2+1:$,:);
+/*         m1           row#           m2
+   1. + i     1. + 0.i    1    0. + i     1. + 0.i
+   1. + i     0. + 0.i    2    0. + i     1. + 0.i
+   1. + 0.i   0. + i      3    0. + i     1. + i
+   0. + 0.i   0. + 0.i    4    1. + i     1. + 0.i
+   0. + 0.i   0. + i      5    1. + i     1. + 0.i
+   0. + i     1. + 0.i    6    0. + 0.i   0. + i
+   1. + 0.i   1. + 0.i    7    1. + 0.i   1. + i
+   1. + 0.i   0. + 0.i    8    1. + 0.i   0. + i
+   1. + 0.i   0. + i      9    1. + 0.i   1. + 0.i
+   0. + 0.i   1. + 0.i   10    0. + 0.i   0. + 0.i
+   1. + i     0. + 0.i   11    0. + 0.i   1. + i
+   0. + 0.i   0. + 0.i   12    0. + i     0. + 0.i
+*/
+// by element
+[x, y] = (m1(1:6,1), m2(1:6,2));
+i = intersect(x, y);
+ref = [1 %i 1+%i];
+
+assert_checkequal(i, ref);
+[i, k1, k2] = intersect(x, y);
+assert_checkequal(i, ref);
+assert_checkequal(i, x(k1).');
+assert_checkequal(i, y(k2).');
+assert_checkequal(k1, [3 6 1]);
+assert_checkequal(k2, [1 6 3]);
+
+// "r": common rows
+i = intersect(m1,m2,"r");
+ref = evstr(["[0,0,1,1,%i,1+%i;";"0,%i,1,%i,1,1]"]).';
+/*
+   0. + 0.i   0. + 0.i
+   0. + 0.i   0. + i
+   1. + 0.i   1. + 0.i
+   1. + 0.i   0. + i
+   0. + i     1. + 0.i
+   1. + i     1. + 0.i
+*/
+assert_checkequal(i, ref);
+[i, k1, k2] = intersect(m1,m2,"r");
+assert_checkequal(i, ref);
+assert_checkequal(i, m1(k1,:));
+assert_checkequal(i, m2(k2,:));
+assert_checkequal(k1, [4  5  7  3  6  1]);
+assert_checkequal(k2, [10 6  9  8  1  4]);
+
+// "c": common columns
+[m1, m2, ref] = (m1.', m2.', ref.');
+i = intersect(m1, m2, "c");
+assert_checkequal(i, ref);
+[i, k1, k2] = intersect(m1, m2, "c");
+assert_checkequal(i, ref);
+assert_checkequal(i, m1(:,k1));
+assert_checkequal(i, m2(:,k2));
+assert_checkequal(k1, [4  5  7  3  6  1]);
+assert_checkequal(k2, [10 6  9  8  1  4]);