fix regression of min(sparseScalar) max(sparseScalar)
[scilab.git] / scilab / modules / elementary_functions / macros / %sp_max.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_max(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_max", 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_max", 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_max", 1));
43     end
44     siz = size(A1);
45
46     // max(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] = max(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 (mn(1)<2 | mn(2)<2) & length(k)==2
78             k = sub2ind(siz,k)
79         end
80
81     // max(A, "r"|"c"|"m")
82     // -------------------
83     elseif rhs==2 & type(elements(2))==10
84         opts = elements(2);
85         if ~or(opts==["c" "r" "m"]) then
86             msg = _("%s: Wrong value for input argument #%d: [''r'' ''c'' ''m''] expected.\n")
87             error(msprintf(msg, "%sp_max", 2))
88         end
89         if isempty(A1) then
90             m = A1
91             k = []
92             return
93         end
94         if siz(1)==1 & opts=="r"
95             m = A1
96             k = ones(1, siz(2))
97         elseif siz(2)==1 & opts=="c"
98             m = A1
99             k = ones(siz(1), 1)
100         else
101             if or(opts==["r" "m"])
102                 A1 = A1'
103             end
104             [ij, v, mn] = spget(A1)
105             // mprintf("""%s"" [%d, %d]\n", opts, siz(1), siz(2))
106             m = spzeros(mn(1), 1)
107             k = ones(mn(1), 1)
108             kk = unique(ij(:,1))
109             for j = kk'
110                 [V,K] = max(A1(j,:))    // handles Nan correctly
111                 m(j) = V
112                 k(j) = K
113             end
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         end
120
121     // max(A1,A2,...) or equivalently max(list(A1,A2,..))
122     // --------------------------------------------------
123     else
124         // m is the first matrix
125         m = elements(1);
126         if lhs>1
127             k = ones(m)
128         end
129         [m1, n1] = size(m)
130
131         // Loop on the number of input arguments
132         for i = 2:rhs
133             An = elements(i)
134             // Check if An is a sparse
135             if and(type(An) <> [1 5])  | (type(An)==1 & or(size(An)~=[1 1])) then
136                 msg = _("%s: Wrong type for input argument #%d%s: A sparse matrix or a scalar expected.\n")
137                 error(msprintf(msg, "%sp_max", i, error_list))
138             end
139             // Check if An is real
140             if ~isreal(An) then
141                 msg = _("%s: Argument #%d%s: Complex numbers not supported.\n")
142                 error(msprintf(msg, "%sp_max", i, error_list))
143             end
144             [m2, n2] = size(An)
145             // Check size
146             if (m1 <> m2 | n1 <> n2) & or([m2 n2]~=[1 1]) then
147                 msg = _("%s: Wrong size of input argument #%d%s: Same size as input argument #%d expected.\n")
148                 error(msprintf(msg, "%sp_max", i, error_list, 1))
149             end
150
151             // Processing:
152             mNan = isnan(m);
153             newNan = isnan(An);
154             pos = (m < An) | (mNan & ~newNan) | ..
155                   (mNan & newNan) // position of the last %nan, as with dense processing
156             if or([m2 n2]~=[1 1])
157                 m(pos) = An(pos)
158             else
159                 m(pos) = An
160             end
161             if lhs > 1
162                 k(pos) = i
163             end
164         end  // for
165         if length(m)<2
166             m = full(m)
167         end
168     end
169 endfunction