1 function [isThereVec,indThereVec]=
ismemberjoint(leftCArr,rightCArr,varargin)
8 'incorrect number of input arguments');
11 if ~iscell(leftCArr)||~iscell(rightCArr)
13 'both arguments should be cell arrays');
22 isnWrong=isnumeric(dim)&&numel(dim)==1;
25 isnWrong=isreal(dim)&&floor(dim)==dim&&dim>=1&&isfinite(dim);
29 'scalar number expected as the third argument');
34 rightCArr=rightCArr(:);
36 nLeft=length(leftCArr);
38 if nLeft~=length(rightCArr)
40 'both arguments should have the same size');
45 'both arguments should be non-empty cells');
48 leftTypeCell=cellfun(
@class,leftCArr,
'UniformOutput',
false);
49 rightTypeCell=cellfun(
@class,rightCArr,
'UniformOutput',
false);
50 isEqualType=cellfun(@(x,y)isequal(x,y),leftTypeCell,rightTypeCell);
53 'types of corresponding input cell content should be the same');
57 isEmptyVec=cellfun(
'isempty',leftCArr)&cellfun(
'isempty',rightCArr);
58 leftCArr(isEmptyVec)=[];
59 rightCArr(isEmptyVec)=[];
60 nLeftComp=length(leftCArr);
62 isThereVec=
false(0,1);
63 indThereVec=zeros(0,1);
66 leftSize=size(leftCArr{1});
67 isEqualLeftSize=
mxberry.
core.checksize(leftCArr{:},leftSize);
70 'size of all items of the first cell array should be the same');
73 rightSize=size(rightCArr{1});
74 isEqualRightSize=
mxberry.
core.checksize(rightCArr{:},rightSize);
77 'size of all items of the second cell array should be the same');
80 nLeftElem=numel(leftCArr{1});
81 lengthLeft=length(leftCArr{1});
83 nRightElem=numel(rightCArr{1});
84 lengthRight=length(rightCArr{1});
86 if (nLeftElem~=lengthLeft)||(nRightElem~=lengthRight)
88 'all cell items should be either columns or rows ');
92 isThereVec=
false(leftSize);
93 indThereVec=nan(leftSize);
96 leftCArr=cellfun(@(x)x(:),leftCArr,
'UniformOutput',
false);
97 rightCArr=cellfun(@(x)x(:),rightCArr,
'UniformOutput',
false);
100 checkSizeIfEmpty=
true;
102 checkSizeIfEmpty=reg{2};
105 nLeftElem=size(leftCArr{1},dim);
107 %cellfun(
'size',...,dim) doesn
't work properly for cell arrays of 108 %enums so we are forced to use a slower variant here: cellfun(@(x)...) 109 isEqualLeftSize=all(cellfun(@(x)size(x,dim),leftCArr(:))==nLeftElem); 111 throwerror('wrongInput
',... 112 ['size of all items in leftCArr along %d-th
',... 113 'dimension should be the same
'],dim); 116 nRightElem=size(rightCArr{1},dim); 118 %cellfun('size
',...,dim) doesn't work properly
for cell arrays of
119 %enums so we are forced to use a slower variant here: cellfun(@(x)...)
120 isEqualRightSize=all(cellfun(@(x)size(x,dim),rightCArr)==nRightElem);
123 [
'size of all items in rightCArr along %d-th ',...
124 'dimension should be the same'],dim);
127 if checkSizeIfEmpty||(nLeftElem>0&&nRightElem>0)
129 permVec=[dim 1:dim-1 dim+1:max(vertcat(...
130 cellfun(
'ndims',leftCArr(:)),cellfun(
'ndims',rightCArr(:))))];
131 leftCArr=cellfun(@(x)permute(x,permVec),leftCArr,
'UniformOutput',
false);
132 rightCArr=cellfun(@(x)permute(x,permVec),rightCArr,
'UniformOutput',
false);
134 leftSize=cellfun(@size,leftCArr,
'UniformOutput',
false);
135 rightSize=cellfun(@size,rightCArr,
'UniformOutput',
false);
137 if ~isequal(cellfun(@(x)x(2:end),leftSize,
'UniformOutput',
false),...
138 cellfun(@(x)x(2:end),rightSize,
'UniformOutput',
false))
140 'sizes of all items in leftCArr and rightCArr '...
141 'along all dimensions save %d-th one should be the same'],dim);
147 isThereVec=false(1,0);
148 indThereVec=nan(1,0);
150 isThereVec=false(0,1);
151 indThereVec=nan(0,1);
158 isThereVec=false(1,nLeftElem);
159 indThereVec=zeros(1,nLeftElem);
161 isThereVec=false(nLeftElem,1);
162 indThereVec=zeros(nLeftElem,1);
167 isReshape=max(cellfun('length',leftSize),cellfun('length',rightSize))>2;
169 leftCArr(isReshape)=cellfun(@(x)reshape(x,nLeftElem,[]),...
170 leftCArr(isReshape),'UniformOutput',false);
171 rightCArr(isReshape)=cellfun(@(x)reshape(x,nRightElem,[]),...
172 rightCArr(isReshape),'UniformOutput',false);
174 nLeftComp=length(leftCArr);
177 %use iterative
unique operation
178 leftIndMat=zeros(nLeftElem,nLeftComp);
179 rightIndMat=zeros(nRightElem,nLeftComp);
181 leftMat=leftCArr{iRow};
182 rightMat=rightCArr{iRow};
183 if isa(rightMat,
'function_handle')
184 leftMat=func2str(leftMat);
185 rightMat=func2str(rightMat);
187 if isnumeric(rightMat)||islogical(rightMat)||ischar(rightMat)
188 [rightMat,~,rightIndMat(:,iRow)]=
mxberry.core.
uniquerows(rightMat,false,prop{:});
189 [~,leftIndMat(:,iRow)]=
mxberry.
core.ismemberrows(leftMat,rightMat,
false,prop{:});
191 isCharStr=iscellstr(rightMat);
192 if iscell(rightMat)&&~isCharStr
193 isCharStr=all(cellfun(
'isclass',rightMat(:),
'function_handle'));
195 leftMat=cellfun(@func2str,leftMat,
'UniformOutput',
false);
196 rightMat=cellfun(@func2str,rightMat,
'UniformOutput',
false);
200 nCols=size(rightMat,2);
201 leftIndColMat=nan(nLeftElem,nCols);
202 rightIndColMat=nan(nRightElem,nCols);
204 [rightVec,~,rightIndColMat(:,iCol)]=
unique(rightMat(:,iCol));
205 [~,leftIndColMat(:,iCol)]=
ismember(leftMat(:,iCol),rightVec);
208 leftIndMat(:,iRow)=leftIndColMat;
209 rightIndMat(:,iRow)=rightIndColMat;
211 [rightIndColMat,~,rightIndMat(:,iRow)]=
mxberry.
core.uniquerows(rightIndColMat,
true,prop{:});
212 [~,leftIndMat(:,iRow)]=
mxberry.
core.ismemberrows(leftIndColMat,rightIndColMat,
true,prop{:});
215 isLeftOpaque=isa(leftCArr{1},
'opaque');
216 isRightOpaque=isa(rightCArr{1},
'opaque');
218 isSortMethodDefined=ismethod(leftCArr{1},
'sort')&&...
219 ismethod(rightCArr{1},
'sort');
221 isBothOpaque=isLeftOpaque&&isRightOpaque;
224 if isSortMethodDefined
226 leftCArr{1},rightCArr{1});
228 [~,leftIndMat(:,iRow)]=...
229 mxberry.
core.ismemberbyfunc(leftCArr{1},rightCArr{1});
231 nRightElems = numel(rightCArr{iRow});
232 rightIndMat(:,iRow)=1:nRightElems;
234 [leftUniqCell,~,leftIndMat(:,iRow),isLeftSorted]=...
236 [rightUniqCell,~,rightIndMat(:,iRow),...
238 leftUniqMat=leftUniqCell{1};
239 rightUniqMat=rightUniqCell{1};
240 if ~isequaln(leftUniqMat,rightUniqMat)
241 if isLeftSorted&&isRightSorted
242 nElems=size(leftUniqMat,1);
243 [~,~,curInd]=
uniquejoint({vertcat(leftUniqMat,rightUniqMat)},1);
244 [~,curInd]=
ismember(curInd(1:nElems),curInd(nElems+1:end),
'legacy');
247 leftUniqMat,rightUniqMat);
249 leftIndMat(:,iRow)=curInd(leftIndMat(:,iRow));
258 isThereVec=
true(nLeftElem,1);
259 indThereVec=nRightElem*ones(nLeftElem,1);
262 [isThereVec,indThereVec]=
ismember(leftIndMat,rightIndMat,
'legacy');
264 isThereVec=
ismember(leftIndMat,rightIndMat,
'legacy');
268 [isThereVec,indThereVec]=
mxberry.
core.ismemberrows(leftIndMat,...
269 rightIndMat,
true,prop{:});
271 isThereVec=
mxberry.
core.ismemberrows(leftIndMat,rightIndMat,...
277 isThereVec=reshape(isThereVec,leftSize);
279 indThereVec=reshape(indThereVec,leftSize);
282 isThereVec=reshape(isThereVec,1,[]);
284 indThereVec=reshape(indThereVec,1,[]);
function throwerror(in msgTag, in varargin)
THROWERROR works similarly to built-in ERROR function in case when there is no output arguments but s...
function ismembersortableobj(in firstVec, in secVec)
ISMEMBER implementation strictly for sortable entities i.e. for those that have 1) full order defined...
function uniquerows(in inpMat, in isInteger, in forceMode)
UNIQUEROWS finds unique rows in input matrix, i.e. the more effective version of UNIQUE(. . .,'rows')
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 unique(in inpVec)
UNIQUE for arrays of any type.
function ismember(in leftVec, in rightVec, in varargin)
ISMEMBER - ismember implementation for arrays of any type.
function parseparams(in args, in propNameList, in nRegExpected, in nPropExpected)
PARSEPARAMS behaves exactly as a built-in Matlab function apart from the incorrect behavior of Matlab...