# HG changeset patch # User jwe # Date 1193295437 0 # Node ID 88417316c1b00e91aa9abb215c74a94ce0cc8277 # Parent 7773c0fdefa6147640b97d400e78bebc920ad7ac [project @ 2007-10-25 06:57:16 by jwe] diff -r 7773c0fdefa6 -r 88417316c1b0 ChangeLog --- a/ChangeLog Thu Oct 25 06:06:41 2007 +0000 +++ b/ChangeLog Thu Oct 25 06:57:17 2007 +0000 @@ -1,3 +1,7 @@ +2007-10-25 John W. Eaton + + * configure.in (AH_BOTTOM): Define OCTAVE_EMPTY_CPP_ARG here. + 2007-10-24 John W. Eaton * octMakefile.in (maintainer-clean distclean): No need to delete diff -r 7773c0fdefa6 -r 88417316c1b0 configure.in --- a/configure.in Thu Oct 25 06:06:41 2007 +0000 +++ b/configure.in Thu Oct 25 06:57:17 2007 +0000 @@ -29,7 +29,7 @@ EXTERN_CXXFLAGS="$CXXFLAGS" AC_INIT -AC_REVISION($Revision: 1.587 $) +AC_REVISION($Revision: 1.588 $) AC_PREREQ(2.57) AC_CONFIG_SRCDIR([src/octave.cc]) AC_CONFIG_HEADER(config.h) @@ -1890,6 +1890,8 @@ #define SIZEOF_OCTAVE_IDX_TYPE SIZEOF_INT #endif +#define OCTAVE_EMPTY_CPP_ARG + #include "oct-dlldefs.h" #include "oct-types.h" ]) diff -r 7773c0fdefa6 -r 88417316c1b0 scripts/ChangeLog --- a/scripts/ChangeLog Thu Oct 25 06:06:41 2007 +0000 +++ b/scripts/ChangeLog Thu Oct 25 06:57:17 2007 +0000 @@ -1,3 +1,8 @@ +2007-10-25 Søren Hauberg + + * set/ismember.m: Improve handling of cell arrays. + Improve error handling. New output arg INDEX. + 2007-10-24 John W. Eaton * image/saveimage.m: Use functional form of save instead of eval. diff -r 7773c0fdefa6 -r 88417316c1b0 scripts/set/ismember.m --- a/scripts/set/ismember.m Thu Oct 25 06:06:41 2007 +0000 +++ b/scripts/set/ismember.m Thu Oct 25 06:57:17 2007 +0000 @@ -17,58 +17,67 @@ ## . ## -*- texinfo -*- -## @deftypefn {Function File} {} ismember (@var{A}, @var{S}) -## Return a matrix the same shape as @var{A} which has 1 if -## @code{A(i,j)} is in @var{S} or 0 if it isn't. +## @deftypefn {Function File} [@var{bool}, @var{index}] = ismember (@var{a}, @var{s}) +## Return a matrix @var{bool} the same shape as @var{a} which has 1 if +## @code{a(i,j)} is in @var{s} or 0 if it isn't. If a second output argument +## is requested, the indexes into @var{s} of the matching elements is +## also returned. ## @seealso{unique, union, intersection, setxor, setdiff} ## @end deftypefn ## Author: Paul Kienzle ## Adapted-by: jwe -function c = ismember (a, S) +function [c, index] = ismember (a, s) if (nargin != 2) print_usage (); endif - if (isempty (a) || isempty (S)) + ## Convert char matrices to cell arrays. + if (ischar (a)) + a = cellstr (a); + endif + if (ischar (s)) + s = cellstr (s); + endif + + ## Input checking. + if (! isa (a, class (s))) + error ("ismember: both input arguments must be the same type"); + endif + + if (iscell (a) && ! iscellstr (a)) + error ("ismember: cell arrays may only contain strings"); + endif + + if (! isnumeric(a) && ! iscell (a)) + error ("ismember: input arguments must be arrays, cell arrays, or strings"); + endif + + ## Do the actual work. + if (isempty (a) || isempty (s)) c = zeros (size (a), "logical"); else - if (iscell (a) && ! iscell (S)) - tmp{1} = S; - S = tmp; - endif - if (! iscell (a) && iscell (S)) - tmp{1} = a; - a = tmp; - endif - S = unique (S(:)); - lt = length (S); - if (lt == 1) - if (iscell (a) || iscell (S)) - c = cellfun ("length", a) == cellfun ("length", S); - idx = find (c); - if (isempty (idx)) - c = zeros (size (a), "logical"); - else - c(idx) = all (char (a(idx)) == repmat (char (S), length (idx), 1), 2); - endif + if (numel (s) == 1) + if (iscell (a)) + c = strcmp (a, s); else - c = (a == S); + ## Both A and S are matrices. + c = (a == s); endif + index = double (c); elseif (numel (a) == 1) - if (iscell (a) || iscell (S)) - c = cellfun ("length", a) == cellfun ("length", S); - idx = find (c); - if (isempty (idx)) - c = zeros (size (a), "logical"); - else - c(idx) = all (repmat (char (a), length (idx), 1) == char (S(idx)), 2); - c = any(c); - endif + if (iscell (a)) + f = find (strcmp (a, s), 1); else - c = any (a == S); + ## Both A and S are matrices. + f = find (a == s, 1); + endif + c = ! isempty (f); + index = f; + if (isempty (index)) + index = 0; endif else ## Magic: the following code determines for each a, the index i @@ -100,16 +109,23 @@ ## easy to now check membership by comparing S(a_idx) == a. This ## magic works because S starts out sorted, and because sort ## preserves the relative order of identical elements. - [v, p] = sort ([S(2:lt); a(:)]); + lt = length (s); + [s, sidx] = sort (s); + [v, p] = sort ([s(2:lt); a(:)]); idx(p) = cumsum (p <= lt-1) + 1; idx = idx(lt:end); - if (iscell (a) || iscell (S)) + if (iscell (a) || iscell (s)) c = (cellfun ("length", a) - == reshape (cellfun ("length", S(idx)), size (a))); + == reshape (cellfun ("length", s(idx)), size (a))); idx2 = find (c); - c(idx2) = all (char (a(idx2)) == char (S(idx)(idx2)), 2); + c(idx2) = all (char (a(idx2)) == char (s(idx)(idx2)), 2); + index = zeros (size (c)); + index(c) = sidx(idx(c)); else - c = (a == reshape (S (idx), size (a))); + ## Both A and S are matrices. + c = (a == reshape (s (idx), size (a))); + index = zeros (size (c)); + index(c) = sidx(idx(c)); endif endif endif @@ -120,7 +136,7 @@ %!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:.*'); %!fail ('ismember ({[]}, {1, 2})', 'error:.*'); %!assert (ismember ({'foo', 'bar'}, {'foobar'}), logical ([0, 0])) %!assert (ismember ({'foo'}, {'foobar'}), false) diff -r 7773c0fdefa6 -r 88417316c1b0 src/ChangeLog --- a/src/ChangeLog Thu Oct 25 06:06:41 2007 +0000 +++ b/src/ChangeLog Thu Oct 25 06:57:17 2007 +0000 @@ -1,5 +1,7 @@ 2007-10-25 John W. Eaton + * symtab.h (symbol_record::TYPE): Delete trailing comma in enum decl. + * ov-base.h (DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA): Use OCTAVE_EMPTY_CPP_ARG to avoid annoying Sun compiler warning. diff -r 7773c0fdefa6 -r 88417316c1b0 src/ov-base.h --- a/src/ov-base.h Thu Oct 25 06:06:41 2007 +0000 +++ b/src/ov-base.h Thu Oct 25 06:57:17 2007 +0000 @@ -60,10 +60,9 @@ // T_ID is the type id of struct objects, set by register_type(). // T_NAME is the type name of struct objects. -#define OCTAVE_EMPTY_CPP_ARG + #define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA \ DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2 (OCTAVE_EMPTY_CPP_ARG) -#undef OCTAVE_EMPTY_CPP_ARG #define DECLARE_OV_BASE_TYPEID_FUNCTIONS_AND_DATA \ DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2(virtual) diff -r 7773c0fdefa6 -r 88417316c1b0 src/symtab.h --- a/src/symtab.h Thu Oct 25 06:06:41 2007 +0000 +++ b/src/symtab.h Thu Oct 25 06:57:17 2007 +0000 @@ -76,7 +76,7 @@ COMMAND = 16, RAWCOMMAND = 32, MAPPER_FUNCTION = 64, - MEX_FUNCTION = 128, + MEX_FUNCTION = 128 }; private: