MatrixBerryCore
IsMemberTC.m
Go to the documentation of this file.
1 classdef IsMemberTC < mxberry.unittest.TestCase
2  methods
3  function self = IsMemberTC(varargin)
4  self = self@mxberry.unittest.TestCase(varargin{:});
5  end
6  end
7  methods (Test)
8  function self=testIsMemberJointAdv(self)
9  import mxberry.core.ismemberjoint;
10  leftList={{1,2,nan},{1,2,3,nan}};
11  rightList={{1,2,nan},{1,2,3,nan},{1,2,2,nan}};
12  [isThereVec,indThereVec]=ismemberjoint({leftList},...
13  {rightList},2);
14  self.verifyEqual(isThereVec,[true,true]);
15  self.verifyEqual(indThereVec,[1,2]);
16  end
17  function testByInputSize(self)
18  N_ISMEMBER_OUTS=2;
19  N_UNIQUE_OUTS=3;
20  %%
21  isMemberInpArgList={{[true,true,false],[1,2,0]},...
22  {[1,2,3],[1,2]},N_ISMEMBER_OUTS};
23  %
24  isMemberInpArgList={{[false,true],[0,1]},...
25  {{[1,2,3],[1,2]},{[1,2]}},...
26  N_ISMEMBER_OUTS};
27  checkMasterIsMember();
28  %
29  isMemberInpArgList={{[false,true],[0,2]},...
30  {{[1,2,3],[1,2]},{[1,2,4],[1,2]}},...
31  N_ISMEMBER_OUTS};
32  checkMasterIsMember();
33  %
34  checkMasterIsMember();
35  isMemberInpArgList={{[false,true,true],[0,2,1]},...
36  {{'alpha','beta','gamma'},{'gamma','beta'}},...
37  N_ISMEMBER_OUTS};
38  checkMasterIsMember();
39  %
40  checkIsMember(@mxberry.core.ismembercellstr);
41  checkIsMemberObjects(false);
42  checkIsMemberObjects(true);
43  %%
44  uniqInpArgList={{[1,2,3],[1;2;3],[1;2;3;3]},{[1,2,3,3]},...
45  N_UNIQUE_OUTS};
46  checkMasterUnique();
47  uniqInpArgList={{{'alpha','beta','gamma'},[1;2;4],[1;2;2;3]},...
48  {{'alpha','beta','beta','gamma'}},N_UNIQUE_OUTS};
49  checkMasterUnique();
50  checkUniqueObjects(true);
51  checkUniqueObjects(false);
52  %
53  function checkIsMemberObjects(varargin)
55  isMemberInpArgList={{[true,true,true],[1,2,3]},...
56  {EntityFactory.create([1,2,3],varargin{:}),...
57  EntityFactory.create([1,2,3],varargin{:})},...
58  N_ISMEMBER_OUTS};
59  checkMasterIsMember();
60  %
61  isMemberInpArgList={{[true,false,true],[2,0,1]},...
62  {EntityFactory.create([2,3,1],varargin{:}),...
63  EntityFactory.create([1,2],varargin{:})},...
64  N_ISMEMBER_OUTS};
65  checkMasterIsMember();
66  isMemberInpArgList={{true,2},...
67  {EntityFactory.create(2,varargin{:}),...
68  EntityFactory.create([1,2,3],varargin{:})},...
69  N_ISMEMBER_OUTS};
70  checkMasterIsMember();
71  isMemberInpArgList={{[false,true,false],[0,1,0]},...
72  {EntityFactory.create([2,3,1],varargin{:}),...
73  EntityFactory.create(3,varargin{:})},...
74  N_ISMEMBER_OUTS};
75  checkMasterIsMember();
76  %
77  isMemberInpArgList={{[false,true,false],[0,1,0]},...
78  {EntityFactory.create([2,3,1],varargin{:}),...
79  EntityFactory.create(3,varargin{:})},...
80  N_ISMEMBER_OUTS};
81  checkMasterIsMember();
82  end
83  function checkUniqueObjects(varargin)
85  uniqInpArgList={...
86  {EntityFactory.create([1,2,3],varargin{:}),[1;2;3],[1;2;3;1]},...
87  {EntityFactory.create([1,2,3,1],varargin{:})},N_UNIQUE_OUTS};
88  checkMasterUnique();
89  end
90  %
91  function checkMasterUnique()
92  checkUniq(@mxberry.core.uniquebyfunc);
93  checkUniq(@(x)mxberry.core.uniquebyfunc(x,@isequal));
94  checkUniq(@(varargin)mxberry.core.uniquebyfunc(...
95  varargin{:},@isequal,'mempreserve'));
96  checkUniq(@(varargin)mxberry.core.uniquebyfunc(...
97  varargin{:},@isequal,'memhungry'));
98  %
99  checkUniq(@fCallUniqueJoint);
100  checkUniq({@(varargin)fCallUniqueJoint(varargin{:},2);...
101  @(varargin)fCallUniqueJoint(varargin{:},1)});
102  checkUniq(@mxberry.core.unique);
103  end
104  %
105  function checkMasterIsMember()
106  checkIsMember(@mxberry.core.ismemberbyfunc);
107  checkIsMember(@(varargin)mxberry.core.ismemberbyfunc(...
108  varargin{:},@isequal));
109  checkIsMember(@mxberry.core.ismember);
110  checkIsMember(@fCallIsMemberJoint);
111  end
112  function varargout=fCallIsMemberJoint(varargin)
113  outList=cell(1,N_ISMEMBER_OUTS);
114  inpArgList=cellfun(@(x){x},varargin,'UniformOutput',false);
115  [outList{:}]=mxberry.core.ismemberjoint(inpArgList{:});
116  varargout=outList;
117  end
118  %
119  function varargout=fCallUniqueJoint(varargin)
120  outList=cell(1,N_UNIQUE_OUTS);
121  [outList{:}]=mxberry.core.uniquejoint(varargin(1),...
122  varargin{2:end});
123  outList{1}=outList{1}{1};
124  varargout=outList;
125  end
126  function checkUniq(fUniq)
127  check(fUniq,uniqInpArgList{:},1);
128  end
129  %
130  function checkIsMember(fIsMember)
131  check(fIsMember,isMemberInpArgList{:});
132  end
133  function check(fCall,outExpArgList,inpArgList,nArgOuts,nArgTransposed)
134  if iscell(fCall)
135  %this is a list of functions
136  fPlain=fCall{1};
137  fTransposed=fCall{2};
138  else
139  fPlain=fCall;
140  fTransposed=fCall;
141  end
142  %
143  if nargin<5
144  nArgTransposed=nArgOuts;
145  end
146  outActList=cell(1,nArgOuts);
147  outTranspList=outActList;
148  [outActList{:}]=fPlain(inpArgList{:});
149  %
150  isOk=isequal(outExpArgList,outActList);
151  self.verifyTrue(isOk);
152  %
153  inpTranspArgList=cellfun(@transpose,inpArgList,...
154  'UniformOutput',false);
155  [outTranspList{:}]=fTransposed(inpTranspArgList{:});
156  outList=outTranspList;
157  outList(1:nArgTransposed)=cellfun(@transpose,...
158  outTranspList(1:nArgTransposed),...
159  'UniformOutput',false);
160  %
161  isOk=isequal(outList,outActList);
162  self.verifyTrue(isOk);
163  end
164  end
165  %
166  function testEqCallCount(self)
167  N_OBJS_VEC=[3,2,5,12];
168  for iCase=1:numel(N_OBJS_VEC)
169  nObjs=N_OBJS_VEC(iCase);
170  checkMaster(nObjs);
171  end
172  %
173  function checkMaster(nObjs)
174  import mxberry.core.test.aux.EqualCallCounter;
175  %% NOT SORTABLE
176  objVec=createObjVec(nObjs,false,'checkUniqueIsMember',false);
177  nIsMemberJointCalls=EqualCallCounter.getNCalls(...
178  @()mxberry.core.ismemberjoint({objVec},{objVec(2:end)}));
179  self.verifyEqual((nObjs-1)*(nObjs-1),nIsMemberJointCalls);
180  %
181  %EqualCallCounter.checkNotSortableCalls(objVec);
182  %
183  %% SORTABLE
184  objVec=createObjVec(nObjs,true,'checkUniqueIsMember',false);
185  EqualCallCounter.checkNotSortableCalls(objVec);
186  %
187  objVec=createObjVec(nObjs,true);
188  EqualCallCounter.checkCalls(objVec,false);
189  %
190  function objVec=createObjVec(nElems,varargin)
192  1:nElems,varargin{:});
193  end
194  end
195  end
196  %
197  function self=test_ismemberjoint_simple(self)
198  import mxberry.core.ismemberjoint;
199  leftCell{1,1}=[1 2 3];
200  leftCell{2,1}={'a','b','c'};
201  leftCell{2,2}={'aa','bc','cc'};
202  leftCell{1,2}=[3 4 2];
203  %
204  rightCell{1,1}=[1 2 3 1];
205  rightCell{2,1}={'a','d','c','a'};
206  rightCell{1,2}=[3 4 2 3];
207  rightCell{2,2}={'aa','dc','cc','aa'};
208  %
209  [isMember,indMember]=ismemberjoint(leftCell,rightCell);
210 
211  expIsMember=logical([1,0,1]);
212  expIndMember=[4,0,3];
213 
214  isOk=isequal(isMember,expIsMember) && isequal(indMember,expIndMember);
215  self.verifyEqual(true,isOk);
216  end
217  function self=test_ismemberjoint_empty(self)
218  import mxberry.core.ismemberjoint;
219  [isMember,indMember]=ismemberjoint({[],[]},{[],[]});
220  self.verifyEqual(true,isempty(isMember));
221  self.verifyEqual(true,isempty(indMember));
222  %
223  [isMember,indMember]=ismemberjoint({zeros(10,0),false(10,0)},{zeros(5,0),false(5,0)},1);
224  self.verifyEqual(true,isequal(isMember,true(10,1)));
225  self.verifyEqual(true,isequal(indMember,repmat(5,10,1)));
226  end
227  function self=test_ismemberjoint(self)
228  leftCell={[1 2],{'a','b'};[3 4],{'c','d'}};
229  rightCell={[1 2 3],{'a','b','c'};[3 4 5],{'c','d','m'}};
230  isMemberVec=[];
231  indMemberVec=[];
232  %
233  isMemberExpVec=[true true];
234  indMemberExpVec=[1 2];
235  superCheck({},{2});
236  self.runAndCheckError(...
237  '[isMemberVec,indMemberVec]=mxberry.core.ismemberjoint(leftCell,rightCell,1);',...
238  'wrongInput');
239  %
240  leftCell={[1 2;11 22],...
241  {'a','b';'aa','bb'},...
242  [3 4;33 44],...
243  {'c','d';'cc','dd'}};
244  rightCell={...
245  [1 2 3;11 22 33],...
246  {'a','b','c';'aa','bb','cc'},...
247  [3 4 5;33 44 55],...
248  {'c','d','m';'cc','dd','mm'}};
249  superCheck({2});
250  for iElem=1:numel(leftCell)
251  leftCell{iElem}=transpose(leftCell{iElem});
252  rightCell{iElem}=transpose(rightCell{iElem});
253  end
254  isMemberExpVec=transpose(isMemberExpVec);
255  indMemberExpVec=transpose(indMemberExpVec);
256  superCheck({1});
257  %
258  ethRightCell=rightCell;
259  rightCell={nan(2,0),cell(2,0),nan(2,0),cell(2,0)};
260  isMemberExpVec=false(1,2);
261  indMemberExpVec=zeros(1,2);
262  superCheck({2});
263  rightCell={[],{},[],{}};
264  self.runAndCheckError(...
265  '[isMemberVec,indMemberVec]=mxberry.core.ismemberjoint(leftCell,rightCell,2);',...
266  ':wrongInput');
267  %
268  rightCell=ethRightCell;
269  leftCell={nan(3,0),cell(3,0),nan(3,0),cell(3,0)};
270  isMemberExpVec=false(1,0);
271  indMemberExpVec=zeros(1,0);
272  superCheck({2});
273  leftCell={[],{},[],{}};
274  self.runAndCheckError(...
275  '[isMemberVec,indMemberVec]=mxberry.core.ismemberjoint(leftCell,rightCell,2);',...
276  ':wrongInput');
277  %
278  function superCheck(varargin)
279  import mxberry.core.ismemberjoint;
280  for iArg=1:nargin
281  [isMemberVec,indMemberVec]=...
282  ismemberjoint(leftCell,rightCell,varargin{iArg}{:});
283  check();
284  end
285  end
286  function check()
287  self.verifyEqual(true,...
288  isequal(isMemberVec,isMemberExpVec));
289  %
290  self.verifyEqual(true,...
291  isequal(indMemberVec,indMemberExpVec));
292  end
293  end
294  %
295  function self=test_uniquejoint(self)
296  import mxberry.core.uniquejoint;
297  inpCell{1,1}=[1 2 1];
298  inpCell{2,1}={'a','b','a'};
299  inpCell{1,2}=[3 5 3];
300  inpCell{2,2}={'ddd','c','ddd'};
301  %
302  expResCell{1,1}=[1,2];
303  expResCell{1,2}=[3,5];
304  expResCell{2,1}={'a','b'};
305  expResCell{2,2}={'ddd','c'};
306  expIndList={[3;2],[1;2;1]};
307  %
308  resIndList=cell(1,2);
309  [resCell,resIndList{:}]=uniquejoint(inpCell);
310  check_results();
311  [resCell,resIndList{:}]=uniquejoint(inpCell,2);
312  check_results();
313  %
314  inpCell=cellfun(@transpose,inpCell,'UniformOutput',false);
315  expResCell=cellfun(@transpose,expResCell,'UniformOutput',false);
316  %
317  [resCell,resIndList{:}]=uniquejoint(inpCell);
318  check_results();
319  [resCell,resIndList{:}]=uniquejoint(inpCell,1);
320  check_results();
321  %
322  inpCell{1,1}=[1 3;2 4;1 3];
323  inpCell{2,1}=cat(3,{'a','b';'b','a';'a','b'},{'c','d';'e','f';'c','d'});
324  inpCell{1,2}=cat(3,[3 4 2;5 6 7;3 4 2],[1 3 2;7 4 5;1 3 2]);
325  inpCell{2,2}={'ddd';'c';'ddd'};
326  inpCell{1,3}=zeros(3,0);
327  inpCell{2,3}=false(3,4,0,2);
328  %
329  expResCell{1,1}=[1 3;2 4];
330  expResCell{1,2}=cat(3,[3 4 2;5 6 7],[1 3 2;7 4 5]);
331  expResCell{1,3}=zeros(2,0);
332  expResCell{2,1}=cat(3,{'a','b';'b','a'},{'c','d';'e','f'});
333  expResCell{2,2}={'ddd';'c'};
334  expResCell{2,3}=false(2,4,0,2);
335  expIndList={[3;2],[1;2;1]};
336  %
337  [resCell,resIndList{:}]=uniquejoint(inpCell,1);
338  check_results();
339  %
340  inpCell=cellfun(@(x)permute(x,[2 1 3:ndims(x)]),...
341  inpCell,'UniformOutput',false);
342  expResCell=cellfun(@(x)permute(x,[2 1 3:ndims(x)]),...
343  expResCell,'UniformOutput',false);
344  %
345  [resCell,resIndList{:}]=uniquejoint(inpCell,2);
346  check_results();
347 
348  function check_results()
349  isOk= isequal(resIndList,expIndList)...
350  && isequal(resCell,expResCell);
351  self.verifyEqual(true,isOk);
352  end
353  end
354  function self=test_uniquejoint_empty(self)
355  import mxberry.core.uniquejoint;
356  expResCell={zeros(1,0),zeros(1,0)};
357  expIndList={1,ones(1,10)};
358  resIndList=cell(1,2);
359  %
360  inpCell={zeros(10,0),zeros(10,0)};
361  [resCell,resIndList{:}]=uniquejoint(inpCell);
362  check_results();
363  %
364  inpCell={zeros(10,0).',zeros(10,0).'};
365  expResCell={zeros(1,0).',zeros(1,0).'};
366  [resCell,resIndList{:}]=uniquejoint(inpCell);
367  check_results();
368  %
369  inpCell={[],[]};
370  expResCell=inpCell;
371  expIndList={[],[]};
372  [resCell,resIndList{:}]=uniquejoint(inpCell);
373  check_results();
374  %
375  inpCell={zeros(0,2,5,3),false(0,4)};
376  expResCell=inpCell;
377  expIndList={nan(0,1),nan(0,1)};
378  [resCell,resIndList{:}]=uniquejoint(inpCell,1);
379  %
380  inpCell={zeros(2,5,0,3),false(4,2,0)};
381  expResCell=inpCell;
382  expIndList={nan(1,0),nan(1,0)};
383  [resCell,resIndList{:}]=uniquejoint(inpCell,3);
384  check_results();
385  %
386  inpCell={zeros(1,0),false(1,0)};
387  expResCell=inpCell;
388  expIndList={1,1};
389  [resCell,resIndList{:}]=uniquejoint(inpCell,1);
390  check_results();
391  %
392  inpCell={zeros(10,0),false(10,0)};
393  expIndList={10,ones(10,1)};
394  [resCell,resIndList{:}]=uniquejoint(inpCell,1);
395  check_results();
396  %
397  function check_results()
398  isOk= isequal(expIndList,resIndList)...
399  && isequal(resCell,expResCell);
400  self.verifyEqual(true,isOk);
401  end
402  end
403  %
404  function self=test_uniquejoint_funchandle(self)
405  import mxberry.core.uniquejoint;
406  inpCell={{@(x)ones(x),@sort,@(y)ones(y),@(x)ones(x)}};
407  %
408  expResCell={{@(x)ones(x),@(y)ones(y),@sort}};
409  expIndList={[1;3;2],[1;3;2;1]};
410  resIndList=cell(1,2);
411  %
412  [resCell,resIndList{:}]=uniquejoint(inpCell);
413  check_results();
414  [resCell,resIndList{:}]=uniquejoint(inpCell,2);
415  check_results();
416  %
417  inpCell=cellfun(@transpose,inpCell,'UniformOutput',false);
418  expResCell=cellfun(@transpose,expResCell,'UniformOutput',false);
419  %
420  [resCell,resIndList{:}]=uniquejoint(inpCell);
421  check_results();
422  [resCell,resIndList{:}]=uniquejoint(inpCell,1);
423  %
424  check_results();
425  %
426  inpCell={{@(x)ones(x),@sort;@min,@(y)ones(y);@(x)ones(x),@sort}};
427  %
428  expResCell={{@(x)ones(x),@sort;@min,@(y)ones(y)}};
429  expIndList={[1;2],[1;2;1]};
430  %
431  [resCell,resIndList{:}]=uniquejoint(inpCell,1);
432  %
433  check_results();
434  %
435  inpCell=cellfun(@(x)permute(x,[2 1 3:ndims(x)]),...
436  inpCell,'UniformOutput',false);
437  expResCell=cellfun(@(x)permute(x,[2 1 3:ndims(x)]),...
438  expResCell,'UniformOutput',false);
439  %
440  [resCell,resIndList{:}]=uniquejoint(inpCell,2);
441  %
442  check_results();
443  %
444  function check_results()
445  isOk= isequal(resIndList,expIndList)...
446  && isequal(func2strForCell(resCell),func2strForCell(expResCell));
447  self.verifyEqual(true,isOk);
448 
449  function inpVec=func2strForCell(inpVec)
450  if iscell(inpVec)
451  inpVec=cellfun(@func2strForCell,inpVec,'UniformOutput',false);
452  elseif isa(inpVec,'function_handle')&&numel(inpVec)==1
453  inpVec=func2str(inpVec);
454  end
455  end
456  end
457  end
458  function self=test_ismemberjoint_enum(self)
459  import mxberry.core.ismemberjoint;
460  enumVal=mxberry.core.test.aux.TestEnum.Alpha;
461  arrayList={[1;2],[enumVal;enumVal]};
462  [a,b]=ismemberjoint(arrayList,arrayList,1);
463  self.verifyEqual(true,isequal(a,[true;true]));
464  self.verifyEqual(true,isequal(b,[1;2]));
465  end
466  function self=test_uniquejoint_ext(self)
467  import mxberry.core.uniquejoint;
468  import mxberry.core.uniquebyfunc;
469  %
470  pathStr=fileparts(mfilename('fullpath'));
471  StData=load([pathStr ...
472  strrep('\+aux\uniquejoint_testdata.mat','\',filesep)]);
473  inputCell=cellfun(@(x)x(:),struct2cell(StData),'UniformOutput',false);
474  [~,~,~,isSorted]=uniquejoint(inputCell,1);
475  self.verifyEqual(true,isSorted);
476  %
477  nRows=200;
478  inputCell=cellfun(@(x)x(1:nRows),inputCell,'UniformOutput',false);
479  [outputCell1,indForward1Vec,indBackward1Vec]=uniquejoint(inputCell,1);
480  nUniqueRows=numel(indForward1Vec);
481  nElems=numel(inputCell);
482  outputCell2=cell(1,nElems);
483  for iElem=1:nElems
484  [~,~,outputCell2{iElem}]=uniquebyfunc(inputCell{iElem});
485  end
486  [~,indForward2Vec,indBackward2Vec]=uniquejoint(outputCell2,1);
487  outputCell2=cellfun(@(x)x(indForward2Vec),inputCell,'UniformOutput',false);
488  self.verifyEqual(nUniqueRows,numel(indForward2Vec));
489  indForwardVec=indBackward1Vec(indForward2Vec);
490  self.verifyEqual(true,~any(diff(sort(indForwardVec))==0));
491  outputCell1=cellfun(@(x)x(indForwardVec),outputCell1,'UniformOutput',false);
492  for iElem=1:nElems
493  self.verifyEqual(true,...
494  isequaln(outputCell1{iElem},outputCell2{iElem}));
495  end
496  self.verifyEqual(true,isequal(indBackward1Vec,indForwardVec(indBackward2Vec)));
497  self.verifyEqual(true,isequal(indForwardVec(indBackward2Vec(indForward1Vec)),(1:nUniqueRows).'));
498  end
499  function self=test_ismemberjointwithnulls(self)
500  leftCell={[1 2],{'a','b'};[3 4],{'c','d'}};
501  rightCell={[1 2 3],{'a','b','c'};[3 4 5],{'c','d','m'}};
502  leftIsNullCell=repmat({false(1,2)},size(leftCell));
503  rightIsNullCell=repmat({false(1,3)},size(rightCell));
504  isMemberVec=[];
505  indMemberVec=[];
506  %
507  isMemberExpVec=[true true];
508  indMemberExpVec=[1 2];
509  superCheck(2);
510  self.runAndCheckError(...
511  '[isMemberVec,indMemberVec]=mxberry.core.ismemberjointwithnulls(leftCell,leftIsNullCell,rightCell,rightIsNullCell,1);',...
512  ':wrongInput');
513  %
514  leftCell={[1 2],{'c','b'};[5 4],{'c','d'}};
515  rightCell={[1 2 3],{'a','b','c'};[3 4 5],{'c','d','m'}};
516  leftIsNullCell={[true,false],[false,false];[false,false],[true,false]};
517  rightIsNullCell={[false,false,true],[true,false,false];[false,false,false],[true,false,true]};
518  isMemberExpVec=[true true];
519  indMemberExpVec=[3 2];
520  superCheck(2);
521  self.runAndCheckError(...
522  '[isMemberVec,indMemberVec]=mxberry.core.ismemberjointwithnulls(leftCell,leftIsNullCell,rightCell,rightIsNullCell,1);',...
523  ':wrongInput');
524  %
525  leftCell={[1 2;11 22],...
526  {'a','b';'aa','bb'},...
527  [3 4;33 44],...
528  {'c','d';'cc','dd'}};
529  rightCell={...
530  [1 2 3;11 22 33],...
531  {'a','b','c';'aa','bb','cc'},...
532  [3 4 5;33 44 55],...
533  {'c','d','m';'cc','dd','mm'}};
534  leftIsNullCell=repmat({false(2,2)},size(leftCell));
535  rightIsNullCell=repmat({false(2,3)},size(rightCell));
536  isMemberExpVec=[true true];
537  indMemberExpVec=[1 2];
538  superCheck(2);
539  for iElem=1:numel(leftCell)
540  leftCell{iElem}=transpose(leftCell{iElem});
541  leftIsNullCell{iElem}=transpose(leftIsNullCell{iElem});
542  rightCell{iElem}=transpose(rightCell{iElem});
543  rightIsNullCell{iElem}=transpose(rightIsNullCell{iElem});
544  end
545  isMemberExpVec=transpose(isMemberExpVec);
546  indMemberExpVec=transpose(indMemberExpVec);
547  superCheck(1);
548  %
549  leftCell={[1 2;11 22],...
550  {'a','b';'cc','bb'},...
551  [5 4;33 44],...
552  {'c','d';'cc','dd'}};
553  rightCell={...
554  [1 2 3;11 22 33],...
555  {'a','b','c';'aa','bb','cc'},...
556  [3 4 5;33 44 55],...
557  {'c','d','m';'cc','dd','mm'}};
558  leftIsNullCell={[true,false;true,false],...
559  [true,false;false,true],...
560  [false,true;true,false],...
561  [true,false;true,false]};
562  rightIsNullCell={[false,false,true;true,false,true],...
563  [false,false,true;true,true,false],...
564  [false,true,false;true,false,true],...
565  [true,false,true;true,false,true]};
566  isMemberExpVec=[true true];
567  indMemberExpVec=[3 2];
568  superCheck(2);
569  for iElem=1:numel(leftCell)
570  leftCell{iElem}=transpose(leftCell{iElem});
571  leftIsNullCell{iElem}=transpose(leftIsNullCell{iElem});
572  rightCell{iElem}=transpose(rightCell{iElem});
573  rightIsNullCell{iElem}=transpose(rightIsNullCell{iElem});
574  end
575  isMemberExpVec=transpose(isMemberExpVec);
576  indMemberExpVec=transpose(indMemberExpVec);
577  superCheck(1);
578  %
579  ethLeftCell=leftCell;
580  ethLeftIsNullCell=leftIsNullCell;
581  ethRightCell=rightCell;
582  ethRightIsNullCell=rightIsNullCell;
583  ethIsMemberExpVec=isMemberExpVec;
584  ethIndMemberExpVec=indMemberExpVec;
585  %
586  leftIsNullCell=cellfun(@(x)x(:,1),leftIsNullCell,'UniformOutput',false);
587  rightIsNullCell=cellfun(@(x)x(:,1),rightIsNullCell,'UniformOutput',false);
588  isMemberExpVec=[false;true];
589  indMemberExpVec=[0;2];
590  superCheck(1);
591  leftCell{3}(1,2)=55;
592  isMemberExpVec=ethIsMemberExpVec;
593  indMemberExpVec=ethIndMemberExpVec;
594  superCheck(1);
595  leftCell{3}(:,2)=[];
596  leftIsNullCell{3}(:)=true;
597  rightIsNullCell{3}(:)=true;
598  superCheck(1);
599  leftCell{3}=ethLeftCell{3};
600  rightCell{3}=nan(3,0);
601  superCheck(1);
602  %
603  leftCell=ethLeftCell;
604  leftIsNullCell=ethLeftIsNullCell;
605  rightCell={nan(2,0),cell(2,0),nan(2,0),cell(2,0)};
606  rightIsNullCell=repmat({false(2,0)},size(rightCell));
607  isMemberExpVec=false(1,2);
608  indMemberExpVec=zeros(1,2);
609  superCheck(2);
610  rightCell={[],{},[],{}};
611  rightIsNullCell=repmat({false(0,0)},size(rightCell));
612  self.runAndCheckError(...
613  '[isMemberVec,indMemberVec]=mxberry.core.ismemberjointwithnulls(leftCell,rightCell,2);',...
614  ':wrongInput');
615  %
616  rightCell=ethRightCell;
617  rightIsNullCell=ethRightIsNullCell;
618  leftCell={nan(3,0),cell(3,0),nan(3,0),cell(3,0)};
619  leftIsNullCell=repmat({false(3,0)},size(leftCell));
620  isMemberExpVec=false(1,0);
621  indMemberExpVec=zeros(1,0);
622  superCheck(2);
623  leftCell={[],{},[],{}};
624  leftIsNullCell=repmat({false(0,0)},size(leftCell));
625  self.runAndCheckError(...
626  '[isMemberVec,indMemberVec]=mxberry.core.ismemberjointwithnulls(leftCell,rightCell,2);',...
627  ':wrongInput');
628  %
629  leftCell=ethLeftCell;
630  leftIsNullCell=cellfun(@(x)true(size(x)),ethLeftIsNullCell,'UniformOutput',false);
631  rightCell=ethRightCell;
632  rightIsNullCell=cellfun(@(x)true(size(x)),ethRightIsNullCell,'UniformOutput',false);
633  isMemberExpVec=[true;true];
634  indMemberExpVec=[3;3];
635  superCheck(1);
636  %
637  StAsgn=substruct('()',{2,':'});
638  rightIsNullCell=cellfun(@(x)subsasgn(x,StAsgn,true),ethRightIsNullCell,'UniformOutput',false); %#ok<SUBSASGN>
639  isMemberExpVec=[true;true];
640  indMemberExpVec=[2;2];
641  superCheck(1);
642  %
643  rightIsNullCell=ethRightIsNullCell;
644  isMemberExpVec=[false;false];
645  indMemberExpVec=[0;0];
646  superCheck(1);
647  %
648  leftIsNullCell=cellfun(@(x)subsasgn(x,StAsgn,true),ethLeftIsNullCell,'UniformOutput',false); %#ok<SUBSASGN>
649  rightIsNullCell=cellfun(@(x)true(size(x)),ethRightIsNullCell,'UniformOutput',false);
650  isMemberExpVec=[false;true];
651  indMemberExpVec=[0;3];
652  superCheck(1);
653  %
654  leftCell={[1 2;11 22],...
655  {'a','b';'cc','bb'},...
656  [5 4;33 44],...
657  {'c','d';'cc','dd'}};
658  rightCell={...
659  [1 2 3;11 22 33],...
660  {'a','b','c';'aa','bb','cc'},...
661  [3 4 5;33 44 55],...
662  {'c','d','m';'cc','dd','mm'}};
663  leftIsNullCell={[true,true;true,false],...
664  [true,false;false,true],...
665  [false,true;true,false],...
666  [true,false;true,false]};
667  rightIsNullCell={[false,false,true;true,false,true],...
668  [false,false,true;true,true,false],...
669  [false,true,false;true,false,true],...
670  [true,false,true;true,false,true]};
671  isMemberExpVec=[true true];
672  indMemberExpVec=[3 2];
673  superCheck(2);
674  %
675  leftCell={[1 2;11 22],...
676  {'a','b';'cc','bb'},...
677  [5 4;33 44],...
678  {'c','d';'cc','dd'}};
679  rightCell={...
680  [1 2 3;11 22 33],...
681  {'d','b';'aa','b'},...
682  [3 4;5 44],...
683  {'c','d','m';'cc','dd','mm'}};
684  leftIsNullCell={[true;false],...
685  [true,false;false,true],...
686  [false,true;true,false],...
687  [true;false]};
688  rightIsNullCell={[false;true],...
689  [false,true;true,false],...
690  [true,false;false,true],...
691  [false;true]};
692  isMemberExpVec=[true;false];
693  indMemberExpVec=[2;0];
694  superCheck(1);
695  %
696  function superCheck(dim)
697  [isMemberVec,indMemberVec]=...
698  mxberry.core.ismemberjointwithnulls(leftCell,leftIsNullCell,rightCell,rightIsNullCell,dim);
699  check();
700  end
701  function check()
702  self.verifyEqual(true,...
703  isequal(isMemberVec,isMemberExpVec));
704  %
705  self.verifyEqual(true,...
706  isequal(indMemberVec,indMemberExpVec));
707  end
708  end
709  function self=test_uniquejoint_performance(self)
710  inpMat=randi([1 2],8500,4);
711  checkTime(inpMat,100);
712  inpMat=randi([1 2],300,10);
713  checkTime(inpMat,100);
714  inpMat=randi([1 20],1000,20);
715  checkTime(inpMat,100);
716  inpMat=randi([1 20],4000,500);
717  checkTime(inpMat,10);
718  inpMat=randi([1 20],1000,500);
719  checkTime(inpMat,100);
720 
721  function checkTime(inpMat,nRuns)
722  import mxberry.core.uniquejoint;
723  MAX_TOLERANCE=0.95;
724  outMat1=[];
725  indForwardVec1=[];
726  indBackwardVec1=[];
727  outMat2=[];
728  indForwardVec2=[];
729  indBackwardVec2=[];
730  time1=self.runAndMeasureTime(@run1,...
731  'nRuns',nRuns,'useMedianTime',true);
732  time2=self.runAndMeasureTime(@run2,...
733  'nRuns',nRuns,'useMedianTime',true);
734  self.verifyEqual(true,isequal(outMat1,outMat2));
735  self.verifyEqual(true,isequal(indForwardVec1,indForwardVec2));
736  self.verifyEqual(true,isequal(indBackwardVec1,indBackwardVec2));
737  time1=min(time1,time2);
738  time2=self.runAndMeasureTime(@run3,...
739  'nRuns',nRuns,'useMedianTime',true);
740  self.verifyEqual(true,isequal(outMat1,outMat2));
741  self.verifyEqual(true,isequal(indForwardVec1,indForwardVec2));
742  self.verifyEqual(true,isequal(indBackwardVec1,indBackwardVec2));
743  curTolerance=max(max(time1/time2,time2/time1)-1,0);
744  messageStr=sprintf(...
745  ['Ratio error %f between chosen and ',...
746  'mininal exceeds maximal one %f'],...
747  curTolerance,MAX_TOLERANCE);
748  self.verifyEqual(true,curTolerance<MAX_TOLERANCE,messageStr);
749  function run1()
750  [outMat1,indForwardVec1,indBackwardVec1]=...
751  mxberry.core.uniquejoint({inpMat},1,'optimized');
752  end
753  function run2()
754  [outMat2,indForwardVec2,indBackwardVec2]=...
755  mxberry.core.uniquejoint({inpMat},1,'standard');
756  end
757  function run3()
758  [outMat2,indForwardVec2,indBackwardVec2]=...
759  mxberry.core.uniquejoint({inpMat},1);
760  end
761  end
762  end
763  function self=test_ismemberjoint_performance(self)
764  inpMat1=randi([1 2],10000,10);
765  inpMat2=randi([1 2],100000,10);
766  checkTime(inpMat1,inpMat2,10);
767  inpMat1=randi([1 10],500,10);
768  inpMat2=randi([1 10],1000,10);
769  checkTime(inpMat1,inpMat2,100);
770  inpMat1=randi([1 100],400,100);
771  inpMat2=randi([1 100],800,100);
772  checkTime(inpMat1,inpMat2,100);
773  inpMat1=randi([1 100],2000,100);
774  inpMat2=randi([1 100],4000,100);
775  checkTime(inpMat1,inpMat2,10);
776  inpMat1=randi([1 10],20,500);
777  inpMat2=randi([1 10],40,500);
778  checkTime(inpMat1,inpMat2,100);
779  inpMat1=randi([1 100],1000,1000);
780  inpMat2=randi([1 100],2000,1000);
781  checkTime(inpMat1,inpMat2,10,0.4);
782 
783  function checkTime(inpMat1,inpMat2,nRuns,maxTol)
784  import mxberry.core.ismemberjoint;
785  MAX_TOLERANCE_DEFAULT=1;
786  if nargin<4
787  maxTol=MAX_TOLERANCE_DEFAULT;
788  end
789  isMemberVec1=[];
790  indMemberVec1=[];
791  isMemberVec2=[];
792  indMemberVec2=[];
793  time1=self.runAndMeasureTime(@run1,...
794  'nRuns',nRuns,'useMedianTime',true);
795  time2=self.runAndMeasureTime(@run2,...
796  'nRuns',nRuns,'useMedianTime',true);
797  self.verifyEqual(true,isequal(isMemberVec1,isMemberVec2));
798  self.verifyEqual(true,isequal(indMemberVec1,indMemberVec2));
799  time1=min(time1,time2);
800  time2=self.runAndMeasureTime(@run3,...
801  'nRuns',nRuns,'useMedianTime',true);
802  self.verifyEqual(true,isequal(isMemberVec1,isMemberVec2));
803  self.verifyEqual(true,isequal(indMemberVec1,indMemberVec2));
804  curTolerance=max(max(time1/time2,time2/time1)-1,0);
805  messageStr=sprintf(['Ratio error %f between chosen ',...
806  'and mininal exceeds maximal one %f'],...
807  curTolerance,maxTol);
808  self.verifyEqual(true,...
809  curTolerance<maxTol,messageStr);
810  function run1()
811  [isMemberVec1,indMemberVec1]=...
812  mxberry.core.ismemberjoint({inpMat1},...
813  {inpMat2},1,'optimized');
814  end
815  function run2()
816  [isMemberVec2,indMemberVec2]=...
817  mxberry.core.ismemberjoint({inpMat1},...
818  {inpMat2},1,'standard');
819  end
820  function run3()
821  [isMemberVec2,indMemberVec2]=...
822  mxberry.core.ismemberjoint({inpMat1},...
823  {inpMat2},1);
824  end
825  end
826  end
827  end
828 end
function filesep()
static function create(in valMat, in varargin)
function repmat(in inpArray, in varargin)
function ismemberbyfunc(in leftVec, in rightVec, in fCompare)
ISMEMBERBYFUNC - ismember implementation for arrays of any type where an element comparison is perfor...
function ismemberjoint(in leftCArr, in rightCArr, in varargin)
ISMEMBERJOINT perform joint ismember operation for two cell arrays.
function uniquejoint(in inpCArr, in varargin)
UNIQUEJOINT perform joint unique operation for cell arrays.
function cat(in dimNum, in varargin)
function uniquebyfunc(in inpVec, in fCompare, in algoName)
UNIQUEBYFUNC unique for arrays of any type where an element comparison is performed by a specified fu...