Mercurial > octave
comparison libinterp/corefcn/pow2.cc @ 30719:a885bdb22374
maint: tweaks to cset a7c4fb821d64 (pow2).
* pow2.cc: Add #include for "lo-array-errwarn.h" to get access
to octave::err_nonconformant error function. Replace calls to
error() with calls to octave::err_nonconformant() for mismatched
input dimensions. Rename warning to "Octave:pow2:imaginary-ignored".
Add BIST tests for input validation.
* warning_ids.m: Add new ID "Octave:pow2:imaginary-only"
author | Rik <rik@octave.org> |
---|---|
date | Sun, 06 Feb 2022 15:47:43 -0800 |
parents | 555676697eef |
children | e88a07dec498 |
comparison
equal
deleted
inserted
replaced
30718:95ee9b9605cc | 30719:a885bdb22374 |
---|---|
26 #if defined (HAVE_CONFIG_H) | 26 #if defined (HAVE_CONFIG_H) |
27 # include "config.h" | 27 # include "config.h" |
28 #endif | 28 #endif |
29 | 29 |
30 #include <cmath> | 30 #include <cmath> |
31 | |
32 #include "lo-array-errwarn.h" | |
31 | 33 |
32 #include "defun.h" | 34 #include "defun.h" |
33 #include "error.h" | 35 #include "error.h" |
34 #include "errwarn.h" | 36 #include "errwarn.h" |
35 | 37 |
44 if (f.numel () == e.numel () || e.numel () == 1) | 46 if (f.numel () == e.numel () || e.numel () == 1) |
45 y = Array<T> (f.dims ()); | 47 y = Array<T> (f.dims ()); |
46 else if (f.numel () == 1) | 48 else if (f.numel () == 1) |
47 y = Array<T> (e.dims ()); | 49 y = Array<T> (e.dims ()); |
48 else | 50 else |
49 error ("pow2: Input dimensions must agree."); | 51 octave::err_nonconformant ("pow2", f.dims (), e.dims ()); |
50 | 52 |
51 octave_idx_type f_inc = (f.numel () == 1) ? 0 : 1; | 53 octave_idx_type f_inc = (f.numel () == 1) ? 0 : 1; |
52 octave_idx_type e_inc = (e.numel () == 1) ? 0 : 1; | 54 octave_idx_type e_inc = (e.numel () == 1) ? 0 : 1; |
53 | 55 |
54 for (octave_idx_type i = 0; i < y.numel (); i++) | 56 for (octave_idx_type i = 0; i < y.numel (); i++) |
77 int ee = static_cast<int> (e.xelem (f.ridx (i), col - 1)); | 79 int ee = static_cast<int> (e.xelem (f.ridx (i), col - 1)); |
78 y.data (i) = std::ldexp (f.data (i), ee); | 80 y.data (i) = std::ldexp (f.data (i), ee); |
79 } | 81 } |
80 } | 82 } |
81 else | 83 else |
82 error ("pow2: Input dimensions must agree."); | 84 octave::err_nonconformant ("pow2", f.dims (), e.dims ()); |
83 } | 85 } |
84 | 86 |
85 OCTAVE_NAMESPACE_BEGIN | 87 OCTAVE_NAMESPACE_BEGIN |
86 | 88 |
87 DEFUN (pow2, args, , | 89 DEFUN (pow2, args, , |
164 | 166 |
165 if (! args(1).isfloat ()) | 167 if (! args(1).isfloat ()) |
166 err_wrong_type_arg ("pow2", args(1)); | 168 err_wrong_type_arg ("pow2", args(1)); |
167 | 169 |
168 if (args(0).iscomplex () || args(1).iscomplex ()) | 170 if (args(0).iscomplex () || args(1).iscomplex ()) |
169 warning_with_id ("Octave:pow2:only-real", | 171 warning_with_id ("Octave:pow2:imaginary-ignored", |
170 "pow2: Imaginary part is ignored."); | 172 "pow2: imaginary part is ignored"); |
171 | 173 |
172 // Note: Matlab R2021a errors on `pow2 (sparse (f), single (e))`, | 174 // Note: Matlab R2021a errors on `pow2 (sparse (f), single (e))`, |
173 // but sparsity in f determines output and can significantly | 175 // but sparsity in f determines output and can significantly |
174 // reduce computation, e.g. `N=1e5; pow2(speye(N),sparse(N,N))`. | 176 // reduce computation, e.g. `N=1e5; pow2(speye(N),sparse(N,N))`. |
175 if (args(0).issparse ()) | 177 if (args(0).issparse ()) |
250 %!test | 252 %!test |
251 %! fcns = {@double, @single, @complex, @sparse}; | 253 %! fcns = {@double, @single, @complex, @sparse}; |
252 %! f = [2 2]; | 254 %! f = [2 2]; |
253 %! e = [2 2]; | 255 %! e = [2 2]; |
254 %! z = [8 8]; | 256 %! z = [8 8]; |
255 %! warning ("off", "Octave:pow2:only-real", "local"); | 257 %! warning ("off", "Octave:pow2:imaginary-ignored", "local"); |
256 %! for i = 1:numel (fcns) | 258 %! for i = 1:numel (fcns) |
257 %! fcn = fcns{i}; | 259 %! fcn = fcns{i}; |
258 %! assert (pow2 (fcn (f), fcn (e)), real (fcn (z))); | 260 %! assert (pow2 (fcn (f), fcn (e)), real (fcn (z))); |
259 %! endfor | 261 %! endfor |
260 | 262 |
268 ## Only real part is taken into account. | 270 ## Only real part is taken into account. |
269 %!test | 271 %!test |
270 %! f = [1+1i, 1]; | 272 %! f = [1+1i, 1]; |
271 %! e = 2; | 273 %! e = 2; |
272 %! z = [4, 4]; | 274 %! z = [4, 4]; |
273 %! warning ("off", "Octave:pow2:only-real", "local"); | 275 %! warning ("off", "Octave:pow2:imaginary-ignored", "local"); |
274 %! assert (pow2 (f, e), z); | 276 %! assert (pow2 (f, e), z); |
275 | 277 |
276 %!test | 278 %!test |
277 %! f = 1; | 279 %! f = 1; |
278 %! e = [1+1i, 1]; | 280 %! e = [1+1i, 1]; |
279 %! z = [2, 2]; | 281 %! z = [2, 2]; |
280 %! warning ("off", "Octave:pow2:only-real", "local"); | 282 %! warning ("off", "Octave:pow2:imaginary-ignored", "local"); |
281 %! assert (pow2 (f, e), z); | 283 %! assert (pow2 (f, e), z); |
282 | 284 |
283 %!test | 285 %!test |
284 %! f = [1/2, pi/4, -3/4, 1/2, 1-eps()/2, 1/2]; | 286 %! f = [1/2, pi/4, -3/4, 1/2, 1-eps()/2, 1/2]; |
285 %! e = [1, 2, 2, -51, 1024, -1021]; | 287 %! e = [1, 2, 2, -51, 1024, -1021]; |
309 %! N = 1e3; | 311 %! N = 1e3; |
310 %! assert (pow2 (speye (N), sparse (N,N)), speye (N)); | 312 %! assert (pow2 (speye (N), sparse (N,N)), speye (N)); |
311 %! assert (pow2 (sparse (0), speye (N)), sparse(N,N)); | 313 %! assert (pow2 (sparse (0), speye (N)), sparse(N,N)); |
312 | 314 |
313 %!error <Invalid call> pow2 () | 315 %!error <Invalid call> pow2 () |
316 %!error <Invalid call> pow2 (1,2,3) | |
317 %!error <wrong type argument> pow2 (int8 (1)) | |
318 %!error <wrong type argument> pow2 (2, int8 (1)) | |
319 %!warning <imaginary part is ignored> pow2 (i, 2); | |
320 %!warning <imaginary part is ignored> pow2 (2, i); | |
321 %!error <pow2: nonconformant arguments> pow2 ([1,2], [3,4,5]) | |
322 %!error <pow2: nonconformant arguments> pow2 (sparse ([1,2]), sparse ([3,4,5])) | |
314 */ | 323 */ |
315 | 324 |
316 OCTAVE_NAMESPACE_END | 325 OCTAVE_NAMESPACE_END |