jashan498

ismember updated

Dec 28th, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Octave 7.25 KB | None | 0 0
  1. ## Copyright (C) 2000-2017 Paul Kienzle
  2. ## Copyright (C) 2009 Jaroslav Hajek
  3. ##
  4. ## This file is part of Octave.
  5. ##
  6. ## Octave is free software; you can redistribute it and/or modify it
  7. ## under the terms of the GNU General Public License as published by
  8. ## the Free Software Foundation; either version 3 of the License, or
  9. ## (at your option) any later version.
  10. ##
  11. ## Octave is distributed in the hope that it will be useful, but
  12. ## WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ## GNU General Public License for more details.
  15. ##
  16. ## You should have received a copy of the GNU General Public License
  17. ## along with Octave; see the file COPYING.  If not, see
  18. ## <http://www.gnu.org/licenses/>.
  19.  
  20. ## -*- texinfo -*-
  21. ## @deftypefn  {} {@var{tf} =} ismember (@var{a}, @var{s})
  22. ## @deftypefnx {} {@var{tf} =} ismember (@var{a}, @var{s}, "rows")
  23. ## @deftypefnx {} {[@var{tf}, @var{s_idx}] =} ismember (@dots{})
  24. ##
  25. ## Return a logical matrix @var{tf} with the same shape as @var{a} which is
  26. ## true (1) if the element in @var{a} is found in @var{s} and false (0) if it
  27. ## is not.
  28. ##
  29. ## If a second output argument is requested then the index into @var{s} of each
  30. ## matching element is also returned.
  31. ##
  32. ## @example
  33. ## @group
  34. ## a = [3, 10, 1];
  35. ## s = [0:9];
  36. ## [tf, s_idx] = ismember (a, s)
  37. ##      @result{} tf = [1, 0, 1]
  38. ##      @result{} s_idx = [4, 0, 2]
  39. ## @end group
  40. ## @end example
  41. ##
  42. ## The inputs @var{a} and @var{s} may also be cell arrays.
  43. ##
  44. ## @example
  45. ## @group
  46. ## a = @{"abc"@};
  47. ## s = @{"abc", "def"@};
  48. ## [tf, s_idx] = ismember (a, s)
  49. ##      @result{} tf = [1, 0]
  50. ##      @result{} s_idx = [1, 0]
  51. ## @end group
  52. ## @end example
  53. ##
  54. ## If the optional third argument @qcode{"rows"} is given then compare rows
  55. ## in @var{a} with rows in @var{s}.  The inputs must be 2-D matrices with the
  56. ## same number of columns to use this option.
  57. ##
  58. ## @example
  59. ## @group
  60. ## a = [1:3; 5:7; 4:6];
  61. ## s = [0:2; 1:3; 2:4; 3:5; 4:6];
  62. ## [tf, s_idx] = ismember (a, s, "rows")
  63. ##      @result{} tf = logical ([1; 0; 1])
  64. ##      @result{} s_idx = [2; 0; 5];
  65. ## @end group
  66. ## @end example
  67. ##
  68. ## @seealso{lookup, unique, union, intersect, setdiff, setxor}
  69. ## @end deftypefn
  70.  
  71. ## Author: Paul Kienzle <pkienzle@users.sf.net>
  72. ## Author: Søren Hauberg <hauberg@gmail.com>
  73. ## Author: Ben Abbott <bpabbott@mac.com>
  74. ## Adapted-by: jwe
  75. ## Reimplemented using lookup & unique: Jaroslav Hajek <highegg@gmail.com>
  76.  
  77. function [tf, s_idx] = ismember (a, s, varargin)
  78.  
  79.   if (nargin < 2 || nargin > 3)
  80.     print_usage ();
  81.   endif
  82.  
  83.   ## lookup() does not handle logical values
  84.   if (islogical (a))
  85.     a = uint8 (a);
  86.   endif
  87.   if (islogical (s))
  88.     s = uint8 (s);
  89.   endif
  90.  
  91.   ## Matlab-compatible behavior (R2016b).  See bug #51187.
  92.   if (ischar (a) && rows (a) == 1 && iscell (s))
  93.     a = {a};
  94.   endif
  95.  
  96.   [a, s] = validsetargs ("ismember", a, s, varargin{:});
  97.  
  98.   ## If any of the element of input matrices is complex then it would be replaced by globally unique integer
  99.   if (isnumeric(a)&&~isreal(a)) || (isnumeric(s)&&~isreal(s))
  100.     [~, ~, u] = unique([a(:); s(:)]);
  101.     a(:) = real(u(1:numel(a)));
  102.     s(:) = real(u(numel(s)+1:end));
  103.   endif
  104.  
  105.   by_rows = nargin == 3;
  106.  
  107.   if (! by_rows)
  108.     s = s(:);
  109.     ## Check sort status, because we expect the array will often be sorted.
  110.     if (issorted (s))
  111.       is = [];
  112.     else
  113.       [s, is] = sort (s);
  114.     endif
  115.  
  116.     ## Remove NaNs from table because lookup can't handle them
  117.     if (isreal (s) && ! isempty (s) && isnan (s(end)))
  118.       s = s(1:end - sum (isnan (s)));
  119.     endif
  120.  
  121.     if (nargout > 1)
  122.       s_idx = lookup (s, a, "m");
  123.       tf = logical (s_idx);
  124.       if (! isempty (is))
  125.         s_idx(tf) = is(s_idx(tf));
  126.       endif
  127.     else
  128.       tf = lookup (s, a, "b");
  129.     endif
  130.  
  131.   else  # "rows" argument
  132.     if (isempty (a) || isempty (s))
  133.       tf = false (rows (a), 1);
  134.       s_idx = zeros (rows (a), 1);
  135.     else
  136.       if (rows (s) == 1)
  137.         tf = all (bsxfun (@eq, a, s), 2);
  138.         s_idx = double (tf);
  139.       else
  140.         ## FIXME: lookup does not support "rows", so we just use unique.
  141.         [~, ii, jj] = unique ([a; s], "rows", "last");
  142.         na = rows (a);
  143.         jj = ii(jj(1:na));
  144.         tf = jj > na;
  145.  
  146.         if (nargout > 1)
  147.           s_idx = max (0, jj - na);
  148.         endif
  149.       endif
  150.     endif
  151.   endif
  152.  
  153. endfunction
  154.  
  155.  
  156. %!assert (ismember ({""}, {"abc", "def"}), false)
  157. %!assert (ismember ("abc", {"abc", "def"}), true)
  158. %!assert (isempty (ismember ([], [1, 2])), true)
  159. %!assert (isempty (ismember ({}, {'a', 'b'})), true)
  160. %!assert (ismember ("", {"abc", "def"}), false)
  161. %!fail ("ismember ([], {1, 2})")
  162. %!fail ("ismember ({[]}, {1, 2})")
  163. %!fail ("ismember ({}, {1, 2})")
  164. %!fail ("ismember ({1}, {'1', '2'})")
  165. %!fail ("ismember (1, 'abc')")
  166. %!fail ("ismember ({'1'}, {'1' '2'},'rows')")
  167. %!fail ("ismember ([1 2 3], [5 4 3 1], 'rows')")
  168. %!assert (ismember ({"foo", "bar"}, {"foobar"}), [false false])
  169. %!assert (ismember ({"foo"}, {"foobar"}), false)
  170. %!assert (ismember ({"bar"}, {"foobar"}), false)
  171. %!assert (ismember ({"bar"}, {"foobar", "bar"}), true)
  172. %!assert (ismember ({"foo", "bar"}, {"foobar", "bar"}), [false true])
  173. %!assert (ismember ({"xfb", "f", "b"}, {"fb", "b"}), [false false true])
  174. %!assert (ismember ("1", "0123456789."), true)
  175.  
  176. %!test
  177. %! [result, s_idx] = ismember ([1, 2], []);
  178. %! assert (result, [false false]);
  179. %! assert (s_idx, [0, 0]);
  180.  
  181. %!test
  182. %! [result, s_idx] = ismember ([], [1, 2]);
  183. %! assert (result, logical ([]));
  184. %! assert (s_idx, []);
  185.  
  186. %!test
  187. %! [result, s_idx] = ismember ({"a", "b"}, "");
  188. %! assert (result, [false false]);
  189. %! assert (s_idx, [0, 0]);
  190.  
  191. %!test
  192. %! [result, s_idx] = ismember ({"a", "b"}, {});
  193. %! assert (result, [false false]);
  194. %! assert (s_idx, [0, 0]);
  195.  
  196. %!test
  197. %! [result, s_idx] = ismember ("", {"a", "b"});
  198. %! assert (result, false);
  199. %! assert (s_idx, 0);
  200.  
  201. %!test
  202. %! [result, s_idx] = ismember ({}, {"a", "b"});
  203. %! assert (result, logical ([]));
  204. %! assert (s_idx, []);
  205.  
  206. %!test
  207. %! [result, s_idx] = ismember ([1 2 3 4 5], [3]);
  208. %! assert (result, logical ([0 0 1 0 0]));
  209. %! assert (s_idx , [0 0 1 0 0]);
  210.  
  211. %!test
  212. %! [result, s_idx] = ismember ([1 6], [1 2 3 4 5 1 6 1]);
  213. %! assert (result, [true true]);
  214. %! assert (s_idx(2), 7);
  215.  
  216. %!test
  217. %! [result, s_idx] = ismember ([3,10,1], [0,1,2,3,4,5,6,7,8,9]);
  218. %! assert (result, [true false true]);
  219. %! assert (s_idx, [4, 0, 2]);
  220.  
  221. %!test
  222. %! [result, s_idx] = ismember ("1.1", "0123456789.1");
  223. %! assert (result, [true true true]);
  224. %! assert (s_idx, [12, 11, 12]);
  225.  
  226. %!test
  227. %! [result, s_idx] = ismember ([1:3; 5:7; 4:6], [0:2; 1:3; 2:4; 3:5; 4:6], "rows");
  228. %! assert (result, [true; false; true]);
  229. %! assert (s_idx, [2; 0; 5]);
  230.  
  231. %!test
  232. %! [result, s_idx] = ismember ([1.1,1.2,1.3; 2.1,2.2,2.3; 10,11,12], [1.1,1.2,1.3; 10,11,12; 2.12,2.22,2.32], "rows");
  233. %! assert (result, [true; false; true]);
  234. %! assert (s_idx, [1; 0; 2]);
  235.  
  236. %!test
  237. %! [result, s_idx] = ismember ([1:3; 5:7; 4:6; 0:2; 1:3; 2:4], [1:3], "rows");
  238. %! assert (result, logical ([1 0 0 0 1 0]'));
  239. %! assert (s_idx, [1 0 0 0 1 0]');
  240.  
  241. %!test <*51187>
  242. %! assert (ismember ('b ', {'a ', 'b '}), true);
  243.  
  244. %!test <*51187>
  245. %! abc = ['a '; 'b '; 'c '];
  246. %! assert (ismember (abc, {abc}), [false; false; false]);
Add Comment
Please, Sign In to add comment