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