Path: news.mathworks.com!not-for-mail
From: <HIDDEN>
Newsgroups: comp.soft-sys.matlab
Subject: Re: ismember - getting wrong result
Date: Sun, 15 Mar 2009 22:28:00 +0000 (UTC)
Organization: Universit&#228;t Heidelberg
Lines: 57
Message-ID: <gpjvdg$p4b$1@fred.mathworks.com>
References: <gpb180$5uv$1@fred.mathworks.com> <gpcnal$rr6$1@fred.mathworks.com> <K4Jul.132944$2h5.128860@newsfe11.iad> <gpgjc1$8sg$1@fred.mathworks.com> <gpis2u$dsi$1@fred.mathworks.com>
Reply-To: <HIDDEN>
NNTP-Posting-Host: webapp-03-blr.mathworks.com
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 8bit
X-Trace: fred.mathworks.com 1237156080 25739 172.30.248.38 (15 Mar 2009 22:28:00 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Sun, 15 Mar 2009 22:28:00 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 869888
Xref: news.mathworks.com comp.soft-sys.matlab:525086


Dear Bruno Luong!

> I have optimize the code (mostly for speed). Before I submit to FEX, I would like to get your feedback.

Your approach does match the needs. In my eyes, the short question should by answered by a short algorith. What do you think of this version:

------------------------------------- 8<---------------------------
function [AEx, BI] = ismemberf(A, B, Tol)
% Jan Simon, 15-Mar-2009
AEx = false(size(A));
nA  = numel(A);
nB  = numel(B);
if nA
   if nargout == 1  % Create BI on demand only
      if nA <= nB
         B = B(:);
         for iA = 1:nA
            AEx(iA) = any(abs(B - A(iA)) <= Tol);
         end
      else  % Faster for: nB < nA
         A  = A(:);
         on = true;  % Slightly faster to call the function TRUE once only
         for iB = 1:nB
            AEx(abs(B(iB) - A) <= Tol) = on;
         end
      end
      
   else  % Create BI in addition:
      on = true;
      BI = zeros(size(A));
      B  = B(:);
      for iA = 1:nA
         match = (abs(B - A(iA)) <= Tol);
         if any(match)
            AEx(iA)  = on;
            matchInd = find(match);
            BI(iA)   = matchInd(length(matchInd));
         end
      end
   end
end

return;
---------------------------------------------------->8--------------------

The different branches for increasing the speed let this grow a little bit. It should be easy to change the check from absolute to relative tolerance, e.g.:
  (abs(B - A(iA)) / A(iA) <= Tol)

Thanks to Matlab's JIT this piece of code might be fast enough for the demands.
I'd hesitate to copy this to the FEX, because it is not smart at all. But it works and its simplicity might be helpful for beginners.

Questions: Is this still true in R2009a:
  matchInd(length(matchInd))  is faster than
  matchInd(end)  is faster than
  find(match, 1, 'last')  ?

Kind regards, Jan