5fd2e79dab64f31bebfb2987410ae9098885b40a
[scilab.git] / scilab / modules / elementary_functions / macros / intersect.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) INRIA - Serge Steer
3 // Copyright (C) DIGITEO - 2011 - Allan CORNET
4 //
5 // Copyright (C) 2012 - 2016 - Scilab Enterprises
6 //
7 // This file is hereby licensed under the terms of the GNU GPL v2.0,
8 // pursuant to article 5.3.4 of the CeCILL v.2.1.
9 // This file was originally licensed under the terms of the CeCILL v2.1,
10 // and continues to be available under such terms.
11 // For more information, see the COPYING file which you should have received
12 // along with this program.
13
14 function [x_out, ka_out, kb_out] = intersect(a_in, b_in, orient)
15     // returns the vector of common values of two vectors
16
17     rhs = argn(2);
18     if rhs < 2 then
19         error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "intersect", 2));
20     end
21
22     if ( (a_in == [])| (b_in == []) ) then
23         x_out = [];
24         ka_out = [];
25         kb_out = [];
26         return
27     end
28     if argn(2)<3 then
29         //remove duplicate values in a_in and b_in
30         [a, ka] = unique(matrix(a_in, 1, -1));
31         [b, kb] = unique(matrix(b_in, 1, -1));
32         kab = [ka, -kb];
33         //find duplicated values in [a_in,b_in],
34         [x,ksort] = gsort([a, b], "g", "i"); //sort the array
35
36         kab = kab(ksort); //apply [a_in,b_in] sorting permutation to kab
37         keq = find( x(2:$) == x(1:$-1) ); // find consecutive equal values index
38
39         if keq == [] then
40             //the intersection is empty
41             x_out = [];
42             ka_out = [];
43             kb_out = [];
44         else
45             x_out = x(keq); //the intersection values in increasing order
46             if argn(1) > 1 then //build the output index
47                 // each duplicated value appear twice  and only twice and in
48                 // consecutive positions keq(i) and keq(i)+1 in the sorted array x
49                 kab = kab([keq keq+1]);
50
51                 //the positive values correspond to a_in index while the negative to b_in index.
52                 ka_out = kab(kab > 0); //select index of intersection elements in a_in
53                 kb_out = -kab(kab < 0); //select index of intersection elements in b_in
54
55                 //insure that a_in(ka_out)==x_out and b_in(kb_out)==x_out.
56                 //I was'nt able to find a simple way.
57                 [s, k] = gsort(a_in(ka_out), "g", "i");
58                 ka_out = ka_out(k);
59                 [s, k] = gsort(b_in(kb_out),"g","i");
60                 kb_out = kb_out(k);
61             end
62         end
63     elseif  orient==1|orient=="r" then
64         //remove duplicate rows in a_in and b_in
65         [a, ka] = unique(a_in, "r");
66         [b, kb] = unique(b_in, "r");
67         kab = [ka; -kb];
68         //find duplicated rows in [a_in;b_in],
69
70         [x,ksort] = gsort([a; b], "lr", "i"); //sort the rows
71
72         kab = kab(ksort);//apply [a_in,b_in] sorting permutation to kab
73         keq = find(and(x(2:$,:) == x(1:$-1,:),"c")) // find index of consecutive equal values
74
75         if keq == [] then
76             //the intersection is empty
77             x_out = [];
78             ka_out = [];
79             kb_out = [];
80         else
81             x_out = x(keq,:); //the intersection values in increasing order
82
83             if argn(1)>1 then //build the output index
84
85                 // each duplicated value appear twice  and only twice and in
86                 // consecutive positions keq(i) and keq(i)+1 in the sorted array x
87                 kab = kab([keq keq+1]);
88
89                 //the positive values correspond to a_in index while the negative to b_in index.
90                 ka_out = kab(kab>0); //select index of intersection elements in a_in
91                 kb_out = -kab(kab<0); //select index of intersection elements in b_in
92
93                 //insure that a_in(ka_out,:)==x_out and b_in(kb_out,:)==x_out.
94                 //I was'nt able to find a simple way.
95                 [s,k]=gsort(a_in(ka_out,:),"lr","i"); ka_out=ka_out(k)
96                 [s,k]=gsort(b_in(kb_out,:),"lr","i"); kb_out=kb_out(k)
97
98
99             end
100         end
101     elseif  orient==2|orient=="c" then
102         //remove duplicate columns in a_in and b_in
103         [a,ka]=unique(a_in,"c");
104
105         [b,kb]=unique(b_in,"c");
106         kab=[ka, -kb];
107         //find duplicated rows in [a_in;b_in],
108         [x,ksort] = gsort([a b],"lc","i"); //sort the rows
109
110         kab = kab(ksort);//apply [a_in,b_in] sorting permutation to kab
111         keq = find(and(x(:,2:$) == x(:,1:$-1),"r")) // find index of consecutive equal values
112
113         if keq == [] then
114             //the intersection is empty
115             x_out = [];
116             ka_out = [];
117             kb_out = [];
118         else
119             x_out =x(:,keq); //the intersection values in increasing order
120
121             if argn(1)>1 then //build the output index
122
123                 // each duplicated value appear twice  and only twice and in
124                 // consecutive positions keq(i) and keq(i)+1 in the sorted array x
125                 kab=kab([keq keq+1]);
126
127                 //the positive values correspond to a_in index while the negative to b_in index.
128                 ka_out = kab(kab>0); //select index of intersection elements in a_in
129                 kb_out = -kab(kab<0); //select index of intersection elements in b_in
130
131                 //insure that a_in(ka_out,:)==x_out and b_in(kb_out,:)==x_out.
132                 //I was'nt able to find a simple way.
133                 [s,k]=gsort(a_in(:,ka_out),"lc","i"); ka_out=ka_out(k)
134                 [s,k]=gsort(b_in(:,kb_out),"lc","i"); kb_out=kb_out(k)
135             end
136         end
137
138     else
139         error(msprintf(gettext("%s: Wrong value for input argument #%d: %d,''%s'',%d or ''%s'' expected\n"),"intersect",3,1,"r",2,"c"));
140     end
141
142 endfunction