1 function [isMemberVec,indMemberVec]=
ismemberjointwithnulls(leftCVec,leftIsNullCVec,rightCVec,rightIsNullCVec,dim)
8 throwerror(
'wrongInput',
'Incorrect number of input arguments');
11 checkgen(leftIsNullCVec,[
'iscell(x)&&isequal(size(x),' ...
12 mat2str(size(leftCVec))
')']);
14 checkgen(rightIsNullCVec,[
'iscell(x)&&isequal(size(x),' ...
15 mat2str(size(rightCVec))
')']);
16 nElems=numel(leftCVec);
20 'First four arguments should be non-empty cell arrays');
22 checkgen(rightCVec,[
'numel(x)==' num2str(nElems)]);
27 checkgen(dim,
'isnumeric(x)&&numel(x)==1');
29 checkgen(dim,
'isreal(x)&&floor(x)==x&&x>=1&&isfinite(x)');
33 leftIsNullCVec=leftIsNullCVec(:);
34 rightCVec=rightCVec(:);
35 rightIsNullCVec=rightIsNullCVec(:);
36 checkgen(leftIsNullCVec,
'all(cellfun(''islogical'',x))');
37 checkgen(rightIsNullCVec,
'all(cellfun(''islogical'',x))');
38 nDimsCVec=cellfun(
'ndims',leftIsNullCVec);
39 nMaxDims=max(max(nDimsCVec),dim);
40 isDecrDims=nDimsCVec==2;
41 isDecrDims(isDecrDims)=cellfun(
'size',leftIsNullCVec(isDecrDims),2)==1;
42 nDimsCVec(isDecrDims)=1;
43 nDimsCVec=
num2cell(max(nDimsCVec,dim));
46 permIndVec=[dim 1:dim-1 dim+1:nMaxDims];
48 [nLeftElem,leftSizeCVec,leftIsNullSizeCVec,...
49 leftCVec,leftIsNullCVec,isnLeftValueVec]=...
51 'left',leftCVec,leftIsNullCVec,nDimsCVec,
false(nElems,1));
52 [nRightElem,rightSizeCVec,rightIsNullSizeCVec,...
53 rightCVec,rightIsNullCVec,isnRightValueVec]=...
55 'right',rightCVec,rightIsNullCVec,nDimsCVec,isnLeftValueVec);
57 isMemberVec=
false(1,nLeftElem);
58 indMemberVec=zeros(1,nLeftElem);
60 isMemberVec=
false(nLeftElem,1);
61 indMemberVec=zeros(nLeftElem,1);
63 if ~isequal(leftIsNullSizeCVec,rightIsNullSizeCVec)
65 'leftIsNullCVec and rightIsNullCVec are not consistent in size');
67 if nLeftElem==0||nRightElem==0
70 if all(isnLeftValueVec)
71 rightIsNullMat=all(horzcat(rightIsNullCVec{:}),2);
72 indLeft2RightNullVec=find(rightIsNullMat,1,
'last');
73 if ~isempty(indLeft2RightNullVec)
75 indMemberVec(:)=indLeft2RightNullVec;
78 elseif all(isnRightValueVec)
79 leftIsNullMat=all(horzcat(leftIsNullCVec{:}),2);
80 isMemberVec(:)=leftIsNullMat;
81 indMemberVec(leftIsNullMat)=nRightElem;
84 isnSizeVec=~(isnLeftValueVec|isnRightValueVec);
86 isnSizeVec(isnSizeVec)=~cellfun(@isequal,...
87 leftSizeCVec(isnSizeVec),rightSizeCVec(isnSizeVec));
90 leftIndMat=zeros(nLeftElem,nElems);
91 rightIndMat=zeros(nRightElem,nElems);
93 if isnLeftValueVec(iElem)
94 isRightNullVec=all(rightIsNullCVec{iElem},2);
95 if ~all(isRightNullVec)
96 isnLeftValueVec(iElem)=
false;
97 leftIndMat(:,iElem)=1;
98 rightIndMat(isRightNullVec,iElem)=1;
101 elseif isnSizeVec(iElem)
102 isLeftNullVec=all(leftIsNullCVec{iElem},2);
103 isRightNullVec=all(rightIsNullCVec{iElem},2);
104 if any(isLeftNullVec)&&any(isRightNullVec)
105 leftIndMat(:,iElem)=double(isLeftNullVec);
106 rightIndMat(:,iElem)=double(~isRightNullVec)+1;
112 [leftIsNullMat,~,indLeftNullVec]=
mxberry.
core.uniquerows(...
113 leftIsNullCVec{iElem},
true);
114 [rightIsNullMat,~,indRightNullVec]=
mxberry.
core.uniquerows(...
115 rightIsNullCVec{iElem},
true);
116 [isLeft2RightNullVec,indLeft2RightNullVec]=...
117 mxberry.
core.ismemberrows(leftIsNullMat,rightIsNullMat,
true);
118 if ~all(isLeft2RightNullVec)
119 indLeft2RightNullVec=indLeft2RightNullVec(isLeft2RightNullVec);
120 leftIsNullMat=leftIsNullMat(isLeft2RightNullVec,:);
121 leftIndVec=cumsum(
double(isLeft2RightNullVec),1);
122 leftIndVec(~isLeft2RightNullVec)=0;
123 indLeftNullVec=leftIndVec(indLeftNullVec);
125 nLeftRows=size(leftIsNullMat,1);
130 leftMat=leftCVec{iElem};
131 rightMat=rightCVec{iElem};
132 for iLeftRow=1:nLeftRows
133 isnNullColVec=leftIsNullMat(iLeftRow,:);
134 isLeftNullVec=indLeftNullVec==iLeftRow;
135 isRightNullVec=indRightNullVec==indLeft2RightNullVec(iLeftRow);
136 if all(isnNullColVec)
138 rightIndMat(isRightNullVec,iElem)=iInd;
139 leftIndMat(isLeftNullVec,iElem)=iInd;
142 isnNullColVec=~isnNullColVec;
144 {rightMat(isRightNullVec,isnNullColVec,:)},1);
145 nInds=max(rightIndVec);
146 rightIndVec=rightIndVec+iInd;
147 rightIndMat(isRightNullVec,iElem)=rightIndVec;
149 {leftMat(isLeftNullVec,isnNullColVec,:)},...
151 if any(isLeft2RightVec)
152 isLeftNullVec(isLeftNullVec)=isLeft2RightVec;
153 leftIndMat(isLeftNullVec,iElem)=...
154 indLeft2RightVec(isLeft2RightVec)+iInd;
159 if any(isnLeftValueVec)
160 leftIndMat(:,isnLeftValueVec)=[];
161 rightIndMat(:,isnLeftValueVec)=[];
165 [isMemberVec(:),indMemberVec(:)]=
mxberry.
core.ismemberrows(...
166 leftIndMat,rightIndMat,
true);
168 isMemberVec(:)=
mxberry.
core.ismemberrows(leftIndMat,rightIndMat,
true);
170 function [nElems,valueSizeCVec,isNullSizeCVec,valueCVec,isNullCVec,isnValueVec]=
checkValueAndIsNullConsistency(nameStr,valueCVec,isNullCVec,nDimsCVec,isnValueVec)
172 valueSizeCVec=cellfun(@(x,y)[size(x) ones(1,max(y-ndims(x),0))],...
173 valueCVec,nDimsCVec,
'UniformOutput',
false);
174 isNullSizeCVec=cellfun(@(x,y)[size(x) ones(1,max(y-ndims(x),0))],...
175 isNullCVec,nDimsCVec,
'UniformOutput',
false);
176 if ~all(cellfun(@(x,y,z)isequal(x(1:z),y(1:z)),...
177 valueSizeCVec,isNullSizeCVec,nDimsCVec))
179 [nameStr
'CVec is not consitent with ' ...
180 nameStr
'IsNullCVec in size']);
182 nElems=sort(cellfun(@(x)x(dim),isNullSizeCVec));
183 if any(diff(nElems)~=0)
185 'Cells in ' nameStr 'CVec and ' nameStr 'IsNullCVec '...
186 'must have the same size along dimension dim=%d'],dim);
190 isNullCVec=cellfun(@(x)reshape(permute(x,permIndVec),nElems,[]),...
191 isNullCVec,'UniformOutput',false);
193 isCurVec=cellfun('prodofsize',isNullSizeCVec)>2;
195 isNullCVec(isCurVec)=cellfun(@(x)reshape(x,nElems,[]),...
196 isNullCVec(isCurVec),'UniformOutput',false);
199 isNullSizeCVec=cellfun(@(x)x([1:dim-1 dim+1:numel(x)]),...
200 isNullSizeCVec,'UniformOutput',false);
204 isCurVec=~isnValueVec;
205 isCurVec(isCurVec)=~cellfun(@(x)all(x(:)),isNullCVec(isCurVec));
206 isnValueVec=~isCurVec;
210 nColsVec=
num2cell(cellfun('size',isNullCVec(isCurVec),2));
212 valueCVec(isCurVec)=cellfun(@(x,y)reshape(permute(x,...
213 [permIndVec nMaxDims+1:ndims(x)]),nElems,y,[]),...
214 valueCVec(isCurVec),nColsVec,'UniformOutput',false);
216 valueCVec(isCurVec)=cellfun(@(x,y)reshape(x,nElems,y,[]),...
217 valueCVec(isCurVec),nColsVec,'UniformOutput',false);
219 valueSizeCVec(isCurVec)=cellfun(@(x)x([1:dim-1 dim+1:numel(x)]),...
220 valueSizeCVec(isCurVec),'UniformOutput',false);
function num2cell(in inpArray, in varargin)
NUM2CELL is an extension of Matlab built-in function "num2cell" designed to work correctly with empty...
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 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 checkgen(in x, in typeSpec, in varargin)
CHECKGEN checks a generic condition provided by typeSpec string in the following format: 'isnumeric(x...
function checkValueAndIsNullConsistency(in nameStr, in valueCVec, in isNullCVec, in nDimsCVec, in isnValueVec)
function ismemberjointwithnulls(in leftCVec, in leftIsNullCVec, in rightCVec, in rightIsNullCVec, in dim)
ISMEMBERJOINTWITHNULLS perform joint ismember operation for two cell arrays for which also cell array...