Mercurial > octave
comparison libinterp/corefcn/sparse-xpow.cc @ 31234:a1318deb4584
sparse-xpow.cc: Improve consistency between sparse and full matrices (bug #63080)
sparse-xpow.cc: Return 0x0 matrix for empty inputs of all sizes.
Return early for all-zeros matrix with positive power.
Add FIXME for all-zeros matrix with negative power.
Add BISTs.
author | Arun Giridhar <arungiridhar@gmail.com> |
---|---|
date | Tue, 20 Sep 2022 09:00:02 -0400 |
parents | a026fb2be108 |
children | b542b88ad3b6 |
comparison
equal
deleted
inserted
replaced
31233:95fa3182f00c | 31234:a1318deb4584 |
---|---|
64 octave_value retval; | 64 octave_value retval; |
65 | 65 |
66 octave_idx_type nr = a.rows (); | 66 octave_idx_type nr = a.rows (); |
67 octave_idx_type nc = a.cols (); | 67 octave_idx_type nc = a.cols (); |
68 | 68 |
69 if (nr == 0 || nc == 0) | |
70 return SparseMatrix(); | |
71 | |
72 // If we are here, A is not empty ==> A needs to be square. | |
69 if (nr != nc) | 73 if (nr != nc) |
70 error ("for A^b, A must be a square matrix. Use .^ for elementwise power."); | 74 error ("for A^b, A must be a square matrix. Use .^ for elementwise power."); |
71 | |
72 if (nr == 0 && nc == 0) | |
73 return a; | |
74 | 75 |
75 if (! xisint (b)) | 76 if (! xisint (b)) |
76 error ("use full(a) ^ full(b)"); | 77 error ("use full(a) ^ full(b)"); |
77 | 78 |
78 int btmp = static_cast<int> (b); | 79 int btmp = static_cast<int> (b); |
98 | 99 |
99 octave_idx_type info; | 100 octave_idx_type info; |
100 double rcond = 0.0; | 101 double rcond = 0.0; |
101 MatrixType mattyp (a); | 102 MatrixType mattyp (a); |
102 | 103 |
104 // FIXME: This causes an error if the input sparse matrix is all-zeros. | |
105 // That behavior is inconsistent with A ^ b when A is a full all-zeros | |
106 // matrix, which just returns Inf of the same size with a warning. | |
103 atmp = a.inverse (mattyp, info, rcond, 1); | 107 atmp = a.inverse (mattyp, info, rcond, 1); |
104 | 108 |
105 if (info == -1) | 109 if (info == -1) |
106 warning ("inverse: matrix singular to machine precision, rcond = %g", rcond); | 110 warning ("inverse: matrix singular to machine precision, rcond = %g", rcond); |
107 } | 111 } |
108 else | 112 else |
109 atmp = a; | 113 atmp = a; |
114 | |
115 if (atmp.nnz() == 0) // Fast return for all-zeros matrix | |
116 return atmp; | |
110 | 117 |
111 SparseMatrix result (atmp); | 118 SparseMatrix result (atmp); |
112 | 119 |
113 btmp--; | 120 btmp--; |
114 | 121 |
170 octave_value retval; | 177 octave_value retval; |
171 | 178 |
172 octave_idx_type nr = a.rows (); | 179 octave_idx_type nr = a.rows (); |
173 octave_idx_type nc = a.cols (); | 180 octave_idx_type nc = a.cols (); |
174 | 181 |
175 if (nr == 0 || nc == 0 || nr != nc) | 182 if (nr == 0 || nc == 0) |
183 return SparseMatrix(); | |
184 | |
185 // If we are here, A is not empty ==> A needs to be square. | |
186 if (nr != nc) | |
176 error ("for A^b, A must be a square matrix. Use .^ for elementwise power."); | 187 error ("for A^b, A must be a square matrix. Use .^ for elementwise power."); |
177 | 188 |
178 if (! xisint (b)) | 189 if (! xisint (b)) |
179 error ("use full(a) ^ full(b)"); | 190 error ("use full(a) ^ full(b)"); |
180 | 191 |
208 if (info == -1) | 219 if (info == -1) |
209 warning ("inverse: matrix singular to machine precision, rcond = %g", rcond); | 220 warning ("inverse: matrix singular to machine precision, rcond = %g", rcond); |
210 } | 221 } |
211 else | 222 else |
212 atmp = a; | 223 atmp = a; |
224 | |
225 if (atmp.nnz() == 0) // Fast return for all-zeros matrix | |
226 return atmp; | |
213 | 227 |
214 SparseComplexMatrix result (atmp); | 228 SparseComplexMatrix result (atmp); |
215 | 229 |
216 btmp--; | 230 btmp--; |
217 | 231 |
299 } | 313 } |
300 | 314 |
301 /* | 315 /* |
302 %!assert (sparse (2) .^ [3, 4], sparse ([8, 16])) | 316 %!assert (sparse (2) .^ [3, 4], sparse ([8, 16])) |
303 %!assert <47775> (sparse (2i) .^ [3, 4], sparse ([-0-8i, 16])) | 317 %!assert <47775> (sparse (2i) .^ [3, 4], sparse ([-0-8i, 16])) |
318 | |
319 %!test <*63080> | |
320 %! Z = sparse ([]); | |
321 %! A = sparse (zeros (0, 2)); | |
322 %! B = sparse (zeros (2, 0)); | |
323 %! assert (Z ^ 1, Z); | |
324 %! assert (Z ^ 0, Z); | |
325 %! assert (Z ^ -1, Z); | |
326 %! assert (A ^ 1, Z); | |
327 %! assert (A ^ 0, Z); | |
328 %! assert (A ^ -1, Z); | |
329 %! assert (B ^ 1, Z); | |
330 %! assert (B ^ 0, Z); | |
331 %! assert (B ^ -1, Z); | |
332 | |
333 %!test <*63080> | |
334 %! A = sparse (zeros (2, 2)); | |
335 %! assert (A ^ 1, A); | |
336 %! assert (A ^ 0, sparse (eye (2, 2))); | |
337 | |
338 %!test <63080> | |
339 %! A = sparse (zeros (2, 2)); | |
340 %! assert (A ^ -1, sparse (inf (2, 2))); | |
341 | |
304 */ | 342 */ |
305 | 343 |
306 // -*- 1 -*- | 344 // -*- 1 -*- |
307 octave_value | 345 octave_value |
308 elem_xpow (double a, const SparseMatrix& b) | 346 elem_xpow (double a, const SparseMatrix& b) |
801 result.maybe_compress (true); | 839 result.maybe_compress (true); |
802 | 840 |
803 return result; | 841 return result; |
804 } | 842 } |
805 | 843 |
844 | |
806 OCTAVE_NAMESPACE_END | 845 OCTAVE_NAMESPACE_END |