Mercurial > octave
comparison libinterp/corefcn/sub2ind.cc @ 30902:972959edc3ff
Allow sub2ind() to accept indices outside the size of the input subscripts (bug #62184)
* NEWS.8.md: Announce change in Matlab Compatibility section.
* sub2ind.cc: Add '#include "utility"' for access to std::swap.
* sub2ind.cc (Fsub2ind): Check nargout to figure out ndims of output.
For special case of vector (1-dimension), put in code to guarantee a
row vector output. Add BIST tests for bug #62184. Remove input
validation BIST which no longer applies.
* Array-util.cc (ind2sub): Remove input validation requiring index to
be within range of subscript size. Adjust code to put all remaining
elements in the final output dimension.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 05 Apr 2022 15:12:34 -0700 |
parents | a8d61c30f41a |
children | e88a07dec498 |
comparison
equal
deleted
inserted
replaced
30901:f6c74e01e294 | 30902:972959edc3ff |
---|---|
24 //////////////////////////////////////////////////////////////////////// | 24 //////////////////////////////////////////////////////////////////////// |
25 | 25 |
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 | |
30 #include <utility> | |
29 | 31 |
30 #include "Array-util.h" | 32 #include "Array-util.h" |
31 #include "oct-locbuf.h" | 33 #include "oct-locbuf.h" |
32 #include "quit.h" | 34 #include "quit.h" |
33 | 35 |
258 if (args.length () != 2) | 260 if (args.length () != 2) |
259 print_usage (); | 261 print_usage (); |
260 | 262 |
261 octave_value_list retval; | 263 octave_value_list retval; |
262 | 264 |
263 // Redimension to provided number of subscripts. | 265 int nd = (nargout == 0) ? 1 : nargout; |
266 | |
264 dim_vector dv = get_dim_vector (args(0), "ind2sub").redim (nargout); | 267 dim_vector dv = get_dim_vector (args(0), "ind2sub").redim (nargout); |
268 | |
269 // Redim for 1 will give us a column vector but we want a row vector. | |
270 if (nd == 1) | |
271 std::swap (dv(0), dv(1)); | |
265 | 272 |
266 try | 273 try |
267 { | 274 { |
268 retval = Array<octave_value> (ind2sub (dv, args(1).index_vector ())); | 275 retval = Array<octave_value> (ind2sub (dv, args(1).index_vector ())); |
276 | |
277 if (nd == 1) | |
278 retval(0) = retval(1); | |
269 } | 279 } |
270 catch (const index_exception& ie) | 280 catch (const index_exception& ie) |
271 { | 281 { |
272 error ("ind2sub: invalid index %s", ie.what ()); | 282 error ("ind2sub: invalid index %s", ie.what ()); |
273 } | 283 } |
308 %! assert (r, [1, 2, 1, 2, 1, 2, 1, 2]); | 318 %! assert (r, [1, 2, 1, 2, 1, 2, 1, 2]); |
309 %! assert (c, [1, 1, 2, 2, 3, 3, 4, 4]); | 319 %! assert (c, [1, 1, 2, 2, 3, 3, 4, 4]); |
310 %! r = ind2sub ([2, 2, 2], 1:8); | 320 %! r = ind2sub ([2, 2, 2], 1:8); |
311 %! assert (r, 1:8); | 321 %! assert (r, 1:8); |
312 | 322 |
323 ## Indexing beyond specified size (bug #62184) | |
324 %!assert <*62184> (ind2sub (1, 2), 2) | |
325 %!assert <*62184> (ind2sub ([3,3], 10), 10) | |
326 %!test <*62184> | |
327 %! [r,c] = ind2sub ([3,3], 10); | |
328 %! assert ([r, c], [1, 4]); | |
329 %!test <*62184> | |
330 %! [r,c,p] = ind2sub ([3,3], 10); | |
331 %! assert ([r, c, p], [1, 1, 2]); | |
332 | |
333 ## Test input validation | |
313 %!error <DIMS must contain integers> ind2sub ([2, -2], 3) | 334 %!error <DIMS must contain integers> ind2sub ([2, -2], 3) |
314 %!error <index out of range> ind2sub ([2, 2, 2], 1:9) | |
315 %!error <invalid index> ind2sub ([2, 2, 2], -1:8) | 335 %!error <invalid index> ind2sub ([2, 2, 2], -1:8) |
316 */ | 336 */ |
317 | 337 |
318 OCTAVE_NAMESPACE_END | 338 OCTAVE_NAMESPACE_END |