fix regression of min(sparseScalar) max(sparseScalar)
[scilab.git] / scilab / modules / elementary_functions / macros / %sp_min.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2010 - Scilab Enterprises - Adeline CARNIS
3 // Copyright (C) 2012 - 2016 - Scilab Enterprises
4 // Copyright (C) 2018 - Samuel GOUGEON
5 //
6 // This file is hereby licensed under the terms of the GNU GPL v2.0,
7 // pursuant to article 5.3.4 of the CeCILL v.2.1.
8 // This file was originally licensed under the terms of the CeCILL v2.1,
9 // and continues to be available under such terms.
10 // For more information, see the COPYING file which you should have received
11 // along with this program.
12
13 function [m, k] = %sp_min(varargin)
14     [lhs, rhs] = argn(0);
15
16     elements = varargin;
17     error_list = "";
18
19     // If the first argument is a list, it retrieves the number of sparse
20     // matrices in list
21     if type(varargin(1)) == 15 then
22         if rhs <> 1 then
23             msg = _("%s: Wrong size of input argument: %d expected.\n")
24             error(msprintf(msg, "%sp_min", 1))
25         end
26
27         rhs = length(varargin(1))
28         elements = varargin(1)
29         error_list = _(" (in list)")
30
31         // If the second argument of list is not a sparse -> ERROR
32         if rhs == 2 & type(elements(2)) <> 5 then
33             msg = _("%s: Wrong type for input argument #%d: A sparse matrix expected.\n")
34             error(msprintf(msg, "%sp_min", 1))
35         end
36     end
37
38     A1 = elements(1);   // Is necessarily a sparse, due to the %sp_ prefix
39     // Check if A1 is real
40     if ~isreal(A1) then
41         msg = _("%s: Argument #%d: Complex numbers not supported.\n")
42         error(msprintf(msg, "%sp_min", 1));
43     end
44     siz = size(A1);
45
46     // min(A)
47     // ------
48     if rhs==1
49         if isempty(A1) then
50             m = []
51             k = []
52             return
53         end
54         // Retrieves entries of sparse matrix
55         [ij, v, mn] = spget(A1)
56
57         // Matrix of zeros:
58         if v==[] then
59             m = 0
60             k = 1
61         else
62             [m, k] = min(v);
63             k = ij(k,:)
64             if m>0 then
65                 i = find(A1(:)==0,1)
66                 if i~=[]
67                     m = 0
68                     k = i
69                 end
70             end
71         end
72         if length(m)<2
73             m = full(m)
74         end
75         if mn(1)>1 & mn(2)>1 & length(k)==1
76             k = ind2sub(siz, k)
77         elseif length(k)==2
78             k = sub2ind(siz,k)
79         end
80
81     // min(A, "r"|"c"|"m")
82     // -------------------
83     elseif rhs==2 & type(elements(2))==10
84         if isempty(A1) then
85             m = A1
86             k = []
87             return
88         end
89         opts = elements(2);
90         if ~or(opts==["c","r","m"]) then
91             msg = _("%s: Wrong value for input argument #%d: [''r'' ''c'' ''m''] expected.\n")
92             error(msprintf(msg, "%sp_min", 2))
93         end
94         if or(opts==["r" "m"])
95             A1 = A1'
96         end
97         [ij, v, mn] = spget(A1)
98         m = spzeros(mn(1), 1)
99         k = ones(mn(1), 1)
100         ind = gsort([ij(:,1) v ij(:,2)], "lr", "i") // Row  Val  Col
101         [tmp, kk] = unique(ind(:,1))
102         tab = ind(kk,:)
103         [i v K] = (tab(:,1), tab(:,2), tab(:,3))
104         ind = find(v>0)
105         for j = ind
106             kk = find(A1(i(j),:)==0,1)
107             if kk ~= []
108                 v(j) = 0
109                 K(j) = kk
110             end
111         end
112         m(i) = v
113         k(i) = K
114         // If opts = 'r' or 'm', the result is returned in row vector
115         if or(opts==["r" "m"]) then
116             m = m'
117             k = k'
118         end
119
120     // min(A1,A2,...) or equivalently min(list(A1,A2,..))
121     // --------------------------------------------------
122     else
123         // m is the first matrix
124         m = elements(1);
125         if lhs>1
126             k = ones(m)
127         end
128         [m1, n1] = size(m)
129
130         // Loop on the number of input arguments
131         for i = 2:rhs
132             An = elements(i)
133             // Check if An is a sparse
134             if and(type(An) <> [1 5])  | (type(An)==1 & or(size(An)~=[1 1])) then
135                 msg = _("%s: Wrong type for input argument #%d%s: A sparse matrix or a scalar expected.\n")
136                 error(msprintf(msg, "%sp_min", i, error_list))
137             end
138             // Check if An is real
139             if ~isreal(An) then
140                 msg = _("%s: Argument #%d%s: Complex numbers not supported.\n")
141                 error(msprintf(msg, "%sp_min", i, error_list))
142             end
143             [m2, n2] = size(An)
144             // Check size
145             if (m1 <> m2 | n1 <> n2) & or([m2 n2]~=[1 1]) then
146                 msg = _("%s: Wrong size of input argument #%d%s: Same size as input argument #%d expected.\n")
147                 error(msprintf(msg, "%sp_min", i, error_list, 1))
148             end
149
150             // Processing:
151             mNan = isnan(m);
152             newNan = isnan(An);
153             pos = (m > An) | (mNan & ~newNan) | ..
154                   (mNan & newNan) // position of the last %nan, as with dense processing
155             if or([m2 n2]~=[1 1])
156                 m(pos) = An(pos)
157             else
158                 m(pos) = An
159             end
160             if lhs > 1
161                 k(pos) = i
162             end
163         end  // for
164         if length(m)<2
165             m = full(m)
166         end
167     end
168 endfunction