help-octave
[Top][All Lists]
Advanced

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

Re: setdiff patch


From: Tom Holroyd (NIH/NIMH) [E]
Subject: Re: setdiff patch
Date: Tue, 03 Oct 2006 16:59:29 -0400
User-agent: Mozilla Thunderbird 1.0.7-1.1.fc3 (X11/20050929)

I'm attaching a different version of setdiff (without the patch just posted) 
that uses an auxiliary function instead of ==, allowing cell arrays of strings, 
so you can do this:

octave:1> a = { "a", "b", "c" };
octave:2> b = { "c", "d" };
octave:3> setdiff(a, b)
ans =

{
 [1,1] = a
 [1,2] = b
}

While I'm at it, I'll include a version of intersect.m with the same change.

--
Tom Holroyd, Ph.D.
We experience the world not as it is, but as we expect it to be.
## Copyright (C) 2000 Paul Kienzle
##
## 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} {} setdiff (@var{a}, @var{b})
## Return the elements in @var{a} but not in @var{b}, sorted in
## ascending order.  If @var{a} and @var{b} are both column vectors
## return a column vector, otherwise return a row vector.
## @end deftypefn
## @seealso{unique, union, intersect, setxor, ismember}

## Author: Paul Kienzle
## Adapted-by: jwe

function c = setdiff (a, b)

  if (nargin != 2)
    usage ("setdiff (a, b)");
  endif

  c = unique (a);
  if (! isempty (c) && ! isempty (b))
    ## Form a and b into combined set.
    b = unique (b);
    [dummy, idx] = sort ([c(:); b(:)]);
    ## Eliminate those elements of a that are the same as in b.
    n = length (dummy);
    c(idx(find (equal(dummy(1:n-1), dummy(2:n))))) = [];
    ## Reshape if necessary.
    if (size (c, 1) != 1 && size (b, 1) == 1)
      c = c.';
    endif
  endif

endfunction

function r = equal(a, b)
# Same as == but works for cell arrays of strings.

  r = zeros([length(a), 1], "logical");
  if iscellstr(a) && iscellstr(b)
    r = strcmp(a, b);
  else
    r = a == b;
  end

endfunction
## Copyright (C) 2000 Paul Kienzle
##
## This program 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 of the License, or
## (at your option) any later version.
##
## This program 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 this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

## -*- texinfo -*-
## @deftypefn {Function File} {} intersect(@var{a}, @var{b})
##
## Return the elements in both @var{a} and @var{b}, sorted in ascending
## order. If @var{a} and @var{b} are both column vectors return a column
## vector, otherwise return a row vector.
##
## @deftypefnx {Function File} address@hidden, @var{ia}, @var{ib}] = } 
intersect (@var{a}, @var{b})
##
## Return index vectors @var{ia} and @var{ib} such that @code{a(ia)==c} and
## @code{b(ib)==c}.
##
## @end deftypefn
## @seealso{unique, union, setxor, setdiff, ismember}

function [c,ia,ib] = intersect(a,b)
  if ( nargin != 2 )
    usage ("intersect (a, b)");
  endif

  if ( isempty (a) || isempty (b) )
    c = []; ia = []; ib = [];
    return;
  endif

  ## form a and b into sets
  [a,ja] = unique (a);
  [b,jb] = unique (b);

  c = [ a(:); b(:) ];
  [c, ic] = sort( c );              ## [a(:);b(:)](ic) == c

  ii = find( equal(c(1:end-1), c(2:end)) );

  c  = c(ii);                       ## The answer
  ia = ja(ic(ii));                  ## a(ia) == c
  ib = jb(ic(ii+1) - length(a));    ## b(ib) == c


  if ( size (b, 1) == 1 || size (a, 1) == 1 )
    c = c.';
  endif


endfunction

function r = equal(a, b)
# Same as == but works for cell arrays of strings.

  r = zeros([length(a), 1], "logical");
  if iscellstr(a) && iscellstr(b)
    r = strcmp(a, b);
  else
    r = a == b;
  end

endfunction

%!# Test the routine for index vectors ia and ib
%!test
%! a = [3 2 4 5 7 6 5 1 0 13 13];
%! b = [3 5 12 1 1 7];
%! [c,ia,ib] = intersect(a,b);
%! assert( c,[1 3 5 7]);
%! assert(ia,[8 1 7 5]);
%! assert(ib,[5 1 2 6]);
%! assert(a(ia),c);
%! assert(b(ib),c);

reply via email to

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