octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #55622] for loop does not run over a matrix wi


From: Rik
Subject: [Octave-bug-tracker] [bug #55622] for loop does not run over a matrix with colums but no row
Date: Fri, 15 Feb 2019 17:24:13 -0500 (EST)
User-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko

Follow-up Comment #15, bug #55622 (project octave):

Quoting from the Matlab documentation on empty arrays


An empty array in MATLAB is an array with at least one dimension length equal
to zero. Empty arrays are useful for representing the concept of "nothing"
programmatically. For example, suppose you want to find all elements of a
vector that are less than 0, but there are none. The find function returns an
empty vector of indices, indicating that it couldn't find any elements less
than 0.

A = [1 2 3 4];
ind = find(A<0)

ind =

  1x0 empty double row vector

Many algorithms contain function calls that can return empty arrays. It is
often useful to allow empty arrays to flow through these algorithms as
function arguments instead of handling them as a special case. If you do need
to customize empty array handling, you can check for them using the isempty
function. 


The use of empty arrays, per se, is fine.  As The Mathworks point out, it is
often useful to be able to write an algorithm without having to special case
whether there will be any elements to act on.

As an example, consider transforming between 1-based indexing (which Octave
uses) to 0-based indexing (which the C language uses).  This is pretty easy,
you just need to subtract 1.


A = [1 2 3 4];
ind = find (A)
ind =

   1   2   3   4

new_ind = ind - 1
new_ind =

   0   1   2   3



And this algorithm still works well if we put in a condition


A = [1 2 3 4];
ind = find (A > 2)
ind =

   3   4

new_ind = ind - 1
new_ind =

   2   3



And finally, it still works when there are no elements


A = [1 2 3 4];
ind = find (A > 4)
ind = [](1x0)
new_ind = ind - 1
new_ind = [](1x0)


I don't see any problem with allowing empty matrices to participate in
mathematical operations.  However, confusing code-dependent issues arise if
you say that looping over empty matrices is permissible.

For example, a common coding strategy might be to calculate some collection of
elements and then loop over them like so.


for elem = collection
  ...
endfor


For the command find(), Matlab returns the empty dimension in the second
dimension (columns).  But there is nothing that guarantees that an empty
matrix has 0 columns.  User code that defines the variable collection might
choose the opposite convention and create 0xN style empty matrices in which
case the for loop is operating N times.

Or something innocuous like a transpose could upset things.

Say I have an algorithm for which I want to operate on the rows of the matrix.
 Since the for loop returns columns, I need to transpose the matrix first.


x = [1, 2; 3, 4];
for elem = x'
  elem
end
elem =

   1
   2

elem =

   3
   4



So far that's fine.  But if x is an empty matrix then the control becomes
confusingly caught up with the decision to act on rows.  In the case of find()
the 1x0 result becomes 0x1 and the loop is executed once rather than zero
times.  It's also data dependent.


x = [1 2 3 4];
idx = find (x > 4)
idx = [](1x0)
idx = find (x' > 4)
idx = [](0x1)


Lastly, this is very likely to lead to syntax errors.  Most of the time, a
programmer is going to want to do something with the loop element from the
collection and this will require an indexing operation that fails because the
element is empty.

Last example,


x = [1 2 3 4]';
idx = find (x > 4)
for var = idx
  var(1) = var(1) + 1;  % increment first element in variable
end


Under Matlab this errors out with "Index exceeds the number of array elements
(0)".  Currently, Octave has no problem with this code because it doesn't
execute the body of the for loop when the right-hand side is empty.



    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?55622>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]