[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
ismember bugs
From: |
Søren Hauberg |
Subject: |
ismember bugs |
Date: |
Sat, 11 Aug 2007 01:44:41 +0200 |
User-agent: |
Thunderbird 1.5.0.12 (X11/20070604) |
Hi,
I just had a look at the 'ismember' bugs (to see the bugs, run 'test
ismember'). I find the 'ismember' code fairly hard to read, so I rewrote
the function from scratch. I've attached the result. Assuming the
'cellstr' bug that I just reported to the bugs-list is fixed this
implementation fixes the bugs. The downside is that my new
implementation is quite a bit more slow (too slow). It depends on the
'cellfun' function, which then is the slow part. I don't consider this
an alternative to the current implementation, but I'm posting the
implementation here in case somebody wants to see the code.
Søren
## Copyright (C) 2007 Soren Hauberg
##
## This file is part of Octave.
##
## Octave is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2, or (at your option)
## any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING. If not, write to the Free
## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA.
## -*- texinfo -*-
## @deftypefn {Function File} address@hidden, @var{idx}] = ismember (@var{A},
@var{S})
## Return a matrix the same shape as @var{A} which has @code{true} if
## @code{A(i,j)} is in @var{S} or @code{false} if it isn't.
## @seealso{unique, union, intersection, setxor, setdiff}
## @end deftypefn
function [bool, idx] = ismember (a, S, r)
# XXX: We need to support the 'rows' argument as well.
if (nargin != 2 && nargin != 3)
print_usage ();
endif
## Check for 'rows' argument
use_rows = false;
if (nargin == 3 && strcmp(r, "rows"))
warning("ismember: ignoring third argument (FIX ME!)");
use_rows = true;
endif
## Convert char matrices to cell arrays
if (ischar(a))
a = cellstr(a);
endif
if (ischar(S))
S = cellstr(S);
endif
## Input checking (this check is for matlab compatibility)
if ( !isa(a, class(S)) )
error("ismember: both input arguments must be the same type");
endif
## Take action depending on the type of 'a' and 'S'
if (isempty(a) || isempty(S))
idx = zeros(size(a));
elseif ( iscellstr(a) && iscellstr(S) )
idx = cellstr_ismember(a(:)', S(:)');
elseif (ismatrix(a) && ismatrix(S))
idx = vector_ismember(a(:)', S(:)');
else
error("ismember: input must be either matrices or cell arrays of strings");
endif
## Reshape output
idx = reshape(idx, size(a));
bool = (idx > 0);
endfunction
## Implementation for 'a' and 'S' being cell arrays of strings
function idx = cellstr_ismember(a, S)
# 'f(x)' is like 'find(strcmp(x,S),1)', except it returns 0 when no match is
found
f = @(x) max(strcmp(x, S).*(1:length(S)));
idx = cellfun(f, a);
endfunction
## Implementation for 'a' and 'S' being vectors
function idx = vector_ismember(a, S)
# 'f(x)' is like 'find(strcmp(x,S),1)', except it returns 0 when no match is
found
f = @(x) max(strcmp(x, S).*(1:length(S)));
idx = arrayfun(f, a);
endfunction
%!assert (ismember ({''}, {'abc', 'def'}), false);
%!assert (ismember ('abc', {'abc', 'def'}), true);
%!assert (isempty (ismember ([], [1, 2])), true);
%!xtest assert (ismember ('', {'abc', 'def'}), false);
%!xtest fail ('ismember ([], {1, 2})', 'error:.*');
%!fail ('ismember ({[]}, {1, 2})', 'error:.*');
%!assert (ismember ({'foo', 'bar'}, {'foobar'}), logical ([0, 0]))
%!assert (ismember ({'foo'}, {'foobar'}), false)
%!assert (ismember ({'bar'}, {'foobar'}), false)
%!assert (ismember ({'bar'}, {'foobar', 'bar'}), true)
%!assert (ismember ({'foo', 'bar'}, {'foobar', 'bar'}), logical ([0, 1]))
%!assert (ismember ({'xfb', 'f', 'b'}, {'fb', 'b'}), logical ([0, 0, 1]))
- ismember bugs,
Søren Hauberg <=