FIND on a 0x0 returns a 0x1

Jaroslav Hajek highegg at gmail.com
Thu Mar 26 08:26:05 CDT 2009


On Thu, Mar 26, 2009 at 12:03 AM, John W. Eaton <jwe at octave.org> wrote:
> On 25-Mar-2009, Carsten Clark wrote:
>
> | Here's a synopsis of some testing in MATLAB (monospaced display will help):
> |
> | ZEROS          Input  Input    FIND  Output
> |                type  ISVECTOR Output  type
> | 0x0           0xOther  0       0x0     []
> | 1x0             RV     1       1x0   basic RV
> | 0x1             CV     1       0x1   basic CV
> |
> | 0x0x0         0xOther  0       0x0     []
> | 1x0x0         1xOther  0       0x1   basic CV
> | 0x1x0         0xOther  0       0x0     []
> | 1x1x0         1xOther  0       0x1   basic CV
> | 0x0x1         0xOther  0       0x0     []
> | 1x0x1           RV     1       1x0   basic RV
> | 0x1x1           CV     1       0x1   basic CV
> |
> | 1x0x1x1x1x1x1   RV     1       1x0   basic RV
> | 1x0x1x1x1x0x1 1xOther  0       0x1   basic CV
> |
> | 0x1x1x1x1x1x1   CV     1       0x1   basic CV
> | 0x1x1x1x1x0x1 0xOther  0       0x0     []
> |
> |
> | RV = row vector (1xN, 1xNx1, 1xNx1x1, ...)
> | CV = col vector (Nx1, Nx1x1, Nx1x1x1, ...)
> |
> |
> | Here's the raw MATLAB FIND output (note that [] is always 0x0 in MATLAB):
> |
> | >> find(zeros(0,0))
> | ans =
> |      []
> | >> find(zeros(1,0))
> | ans =
> |    Empty matrix: 1-by-0
> | >> find(zeros(0,1))
> | ans =
> |    Empty matrix: 0-by-1
> | >> find(zeros(0,0,0))
> | ans =
> |      []
> | >> find(zeros(1,0,0))
> | ans =
> |    Empty matrix: 0-by-1
> | >> find(zeros(0,1,0))
> | ans =
> |      []
> | >> find(zeros(1,1,0))
> | ans =
> |    Empty matrix: 0-by-1
> | >> find(zeros(0,0,1))
> | ans =
> |      []
> | >> find(zeros(1,0,1))
> | ans =
> |    Empty matrix: 1-by-0
> | >> find(zeros(0,1,1))
> | ans =
> |    Empty matrix: 0-by-1
> | >> find(zeros(1,0,1,1,1,1,1))
> | ans =
> |    Empty matrix: 1-by-0
> | >> find(zeros(1,0,1,1,1,0,1))
> | ans =
> |    Empty matrix: 0-by-1
> | >> find(zeros(0,1,1,1,1,1,1))
> | ans =
> |    Empty matrix: 0-by-1
> | >> find(zeros(0,1,1,1,1,0,1))
> | ans =
> |      []
> |
> |
> | Here's the result of MATLAB ISVECTOR on the same inputs:
> |
> | >> isvector(zeros(0,0))
> | ans =
> |      0
> | >> isvector(zeros(1,0))
> | ans =
> |      1
> | >> isvector(zeros(0,1))
> | ans =
> |      1
> | >> isvector(zeros(0,0,0))
> | ans =
> |      0
> | >> isvector(zeros(1,0,0))
> | ans =
> |      0
> | >> isvector(zeros(0,1,0))
> | ans =
> |      0
> | >> isvector(zeros(1,1,0))
> | ans =
> |      0
> | >> isvector(zeros(0,0,1))
> | ans =
> |      0
> | >> isvector(zeros(1,0,1))
> | ans =
> |      1
> | >> isvector(zeros(0,1,1))
> | ans =
> |      1
> | >> isvector(zeros(1,0,1,1,1,1,1))
> | ans =
> |      1
> | >> isvector(zeros(1,0,1,1,1,0,1))
> | ans =
> |      0
> | >> isvector(zeros(0,1,1,1,1,1,1))
> | ans =
> |      1
> | >> isvector(zeros(0,1,1,1,1,0,1))
> | ans =
> |      0
> |
> |
> | Here's a set of rules deduced from the above for find(X), where X is
> | empty.  Given the following definitions:
> |
> | - a row vector is any matrix with size >= 0 down the 2nd dimension,
> | and all other dimensions of size 1;
> |
> | - a column vector is any matrix with size >= 0 down the 1st dimension,
> | and all other dimensions of size 1;
>
> Since Matlab (and Octave) strip trailing singleton dimensions, you
> don't have to check all the trailing dimensions.  If you try to
> construct an object with all trailing dimensions == 1, then they
> should be stripped and the object should have only 2 dimensions.
>
> | the following rules seem to apply when X is empty:
> |
> | 1. If X is a row vector, return the basic empty row vector (1x0).
> | 2. If X's 1st dim is 0 and X is *not* a column vector, return [] (0x0).
> | 3. Return the basic empty column vector (0x1).
>
> OK, how about the following change?
>
>  http://hg.savannah.gnu.org/hgweb/octave/rev/12ca81f1fa99
>
> Thanks,
>
> jwe
> _______________________________________________
> Bug-octave mailing list
> Bug-octave at octave.org
> https://www-old.cae.wisc.edu/mailman/listinfo/bug-octave
>

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)'.
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).
Maybe we can use the above invariant as a test?

cheers


-- 
RNDr. Jaroslav Hajek
computing expert & GNU Octave developer
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: results_old.txt
Url: https://www-old.cae.wisc.edu/pipermail/bug-octave/attachments/20090326/9333f345/attachment-0002.txt 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bench0.m
Type: text/x-matlab
Size: 315 bytes
Desc: not available
Url : https://www-old.cae.wisc.edu/pipermail/bug-octave/attachments/20090326/9333f345/attachment-0001.bin 
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: results_new.txt
Url: https://www-old.cae.wisc.edu/pipermail/bug-octave/attachments/20090326/9333f345/attachment-0003.txt 


More information about the Bug-octave mailing list