# HG changeset patch # User Rik # Date 1401038583 25200 # Node ID a5286fb173cd8c5ef266b25204e0badbd9b33000 # Parent 095fdef3d67c18c015d0fa7c72cca1242e19b8f2 Match Matlab return dimensions for find on empty sparse matrices (bug #42408). * find.cc (find_nonzero_elem_idx (const Sparse& v)): Match Matlab return dimensions for odd cases such as 0x1, 1x0, 1x1(empty) sparse matrices. The conditions are documented in Array.cc (Array::find) and are already implemented for other array types besides sparse. * find.cc (find_nonzero_elem_idx (const PermMatrix& v)): Match Matlab return dimensions for odd cases such as 0x1, 1x0, 1x1(empty) permutation matrices. diff -r 095fdef3d67c -r a5286fb173cd libinterp/corefcn/find.cc --- a/libinterp/corefcn/find.cc Fri May 16 20:01:27 2014 +0200 +++ b/libinterp/corefcn/find.cc Sun May 25 10:23:03 2014 -0700 @@ -88,9 +88,8 @@ { octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ()); - + octave_idx_type nr = v.rows (); octave_idx_type nc = v.cols (); - octave_idx_type nr = v.rows (); octave_idx_type nz = v.nnz (); // Search in the default range. @@ -138,21 +137,20 @@ count = (n_to_find > v.cidx (end_nc) - v.cidx (start_nc) ? v.cidx (end_nc) - v.cidx (start_nc) : n_to_find); - // If the original argument was a row vector, force a row vector of - // the overall indices to be returned. But see below for scalar - // case... + octave_idx_type result_nr; + octave_idx_type result_nc; - octave_idx_type result_nr = count; - octave_idx_type result_nc = 1; - - bool scalar_arg = false; - - if (v.rows () == 1) + // Default case is to return a column vector, however, if the original + // argument was a row vector, then force return of a row vector. + if (nr == 1) { result_nr = 1; result_nc = count; - - scalar_arg = (v.columns () == 1); + } + else + { + result_nr = count; + result_nc = 1; } Matrix idx (result_nr, result_nc); @@ -164,9 +162,8 @@ if (count > 0) { - // Search for elements to return. Only search the region where - // there are elements to be found using the count that we want - // to find. + // Search for elements to return. Only search the region where there + // are elements to be found using the count that we want to find. for (octave_idx_type j = start_nc, cx = 0; j < end_nc; j++) for (octave_idx_type i = v.cidx (j); i < v.cidx (j+1); i++ ) { @@ -182,14 +179,19 @@ break; } } - else if (scalar_arg) + else { - idx.resize (0, 0); + // No items found. Fixup return dimensions for Matlab compatibility. + // The behavior to match is documented in Array.cc (Array::find). + if ((nr == 0 && nc == 0) || nr == 1 & nc == 1) + { + idx.resize (0, 0); - i_idx.resize (0, 0); - j_idx.resize (0, 0); + i_idx.resize (0, 0); + j_idx.resize (0, 0); - val.resize (dim_vector (0, 0)); + val.resize (dim_vector (0, 0)); + } } switch (nargout) @@ -231,6 +233,7 @@ // There are far fewer special cases to handle for a PermMatrix. octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ()); + octave_idx_type nr = v.rows (); octave_idx_type nc = v.cols (); octave_idx_type start_nc, count; @@ -252,8 +255,6 @@ count = n_to_find; } - bool scalar_arg = (v.rows () == 1 && v.cols () == 1); - Matrix idx (count, 1); Matrix i_idx (count, 1); Matrix j_idx (count, 1); @@ -291,13 +292,22 @@ } } } - else if (scalar_arg) + else { - // Same odd compatibility case as the other overrides. - idx.resize (0, 0); - i_idx.resize (0, 0); - j_idx.resize (0, 0); - val.resize (dim_vector (0, 0)); + // FIXME: Is this case even possible? A scalar permutation matrix seems to devolve + // to a scalar full matrix, at least from the Octave command line. Perhaps + // this function could be called internally from C++ with such a matrix. + // No items found. Fixup return dimensions for Matlab compatibility. + // The behavior to match is documented in Array.cc (Array::find). + if ((nr == 0 && nc == 0) || nr == 1 & nc == 1) + { + idx.resize (0, 0); + + i_idx.resize (0, 0); + j_idx.resize (0, 0); + + val.resize (dim_vector (0, 0)); + } } switch (nargout)