FIND on a 0x0 returns a 0x1

Jaroslav Hajek highegg at gmail.com
Fri Mar 27 01:23:52 CDT 2009


On Fri, Mar 27, 2009 at 4:04 AM, Carsten Clark
<tantumquantum+gnuoctave at gmail.com> wrote:
> 2009/3/26 Jaroslav Hajek <highegg at gmail.com>:
>>
>> I have made a few changes today, amongst other added Array<T>::find to
>> the "searching & sorting" methods of Array, and used it to simplify
>> Ffind. benchmark + results are attached - some cases are sped up by
>> more than 4x.
>>
>> I needed to change the compatibility adjustments but it seems I get
>> identical results.
>> My impression is that the rules can be deferred to those of indexing:
>> find(a) is equivalent to `reshape (1:numel (a), size (a))(a != 0)'.
>
> I love the elegance of this definition, but in my Octave 3.0.3 it
> returns a 0x1 given a 0x0:
>
> $ octave -qf
> octave:1> function inx = myfind(a)
>> inx = reshape (1:numel (a), size (a))(a != 0);
>> end
> octave:2> zeros(0,0)
> ans = [](0x0)
> octave:3> myfind ( zeros(0,0) )
> ans = [](0x1)
>

That's another special Matlab case missed by Octave - it seems that
indexing by all-zeros *logical* matrices gives an empty matrix. Oh
well. I've fixed this issue in the development sources. I'm constantly
amazed how many ad-hoc special cases Matlab contains. So the invariant
should hold now.


> The reason I raised this issue in the first place is that I have
> MATLAB code that looks like this:
>
>    % Start with an empty row vector of track structures.
>    tracks = repmat ( newTack(), 1, 0 );
>    ......
>    for t = find ( [tracks.active] )
>        tracks(t).stuff = calcStuff ( tracks(t).otherStuff, ... );
>    end
>
> This code breaks in Octave because the 'for' loop executes when
> 'tracks' is empty and tracks(t).otherStuff can't be dereferenced.
>
> One could certainly argue that this code is asking for trouble... but
> OTOH it's intuitive that a 'for' loop over an empty row vector should
> not execute.  (And [tracks.active] is a row vector no matter what the
> shape of 'tracks', right?)
>

No, actually, it's not - when tracks is empty, it gives a 0x0 matrix
(which is not a vector).
But I agree that we follow the Matlab quirks elsewhere, so we should
follow them here.
Matlab seems to generally treat the all-zero-dims matrices as a special case.

>
>> Btw. Matlab seems to contradict its own docs, according to Carsten's
>> quotes, in the sense that the first condition is not honored for a
>> scalar zero (which is a row vector).
>
> Yes, I'd say that MATLAB breaks its contract.  We know it returns 0x0
> [], which is neither a row vector nor a column vector.
>
> For reference, the MATLAB doc entry for FIND:
> http://www.mathworks.com/access/helpdesk/help/techdoc/ref/find.html
>
> I can only guess that they quietly added the 0x0 returning case in
> order to achieve the "intuitive" behavior on 'for' loops that I
> mentioned above.
>
>
>> Maybe we can use the above invariant as a test?
>
> I'll leave that to one of you.  Thanks for your interest in this,
> Carsten
>



-- 
RNDr. Jaroslav Hajek
computing expert & GNU Octave developer
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz



More information about the Bug-octave mailing list