1 function [unqCArr,indRight2LeftVec,indLeft2RightVec,isSorted]=
uniquejoint(inpCArr,varargin)
9 'incorrect number of input arguments');
14 'cell array expected as the first argument');
21 'an input argument should be non-empty cell array');
30 isnWrong=isnumeric(indDim)&&numel(indDim)==1;
32 indDim=double(indDim);
33 isnWrong=isreal(indDim)&&floor(indDim)==indDim&&indDim>=1&&...
38 'scalar number expected as the second argument');
43 inpSizeVec=size(inpCArr{1});
44 isEqualSize=
mxberry.
core.checksize(inpCArr{:},inpSizeVec);
47 'size of all items of the first cell array should be the same');
50 isnColumn=inpSizeVec(1)<=1;
51 %turn all cell elements into columns
53 inpArr=cellfun(@transpose,inpCArr,
'UniformOutput',
false);
58 nInpElem=numel(inpArr{1});
59 lengthInp=max(inpSizeVec);
61 nInpElem=size(inpCArr{1},indDim);
63 %cellfun(
'size',...,dim) doesn
't work properly for cell arrays of 64 %enums so we are forced to use a slower variant here: cellfun(@(x)...) 65 isEqualSize=all(cellfun(@(x)size(x,indDim),inpCArr(:))==nInpElem); 68 throwerror('wrongInput
',... 69 ['size of all items in inpCell along %d-th
',... 70 'dimension should be the same
'],indDim); 73 inpSizeVec=cellfun(@size,inpCArr,'UniformOutput
',false); 74 nDimsVec=cellfun('length
',inpSizeVec(:)); 76 permVec=[indDim 1:indDim-1 indDim+1:max(nDimsVec)]; 77 inpArr=cellfun(@(x)reshape(permute(x,permVec),nInpElem,[]),... 78 inpCArr,'UniformOutput
',false); 81 isReshape=cellfun('length
',inpSizeVec)>2; 83 inpArr(isReshape)=cellfun(@(x)reshape(x,nInpElem,[]),... 84 inpArr(isReshape),'UniformOutput
',false); 92 unqCArr=cellfun(@(x)x(1,:),inpArr,'UniformOutput
',false); 94 unqCArr=cellfun(@transpose,unqCArr,'UniformOutput
',false); 97 indLeft2RightVec=ones(1,lengthInp); 104 indRight2LeftVec=nan(0,1); 105 indLeft2RightVec=nan(0,1); 107 indRight2LeftVec=nan(1,0); 108 indLeft2RightVec=nan(1,0); 115 if (nInpElem~=lengthInp) 116 throwerror('wrongInput
',... 117 'all cell items should be either columns or rows
'); 123 %apply iterative unique operation 124 indMat=zeros(nInpElem,nInp); 125 isnSorted=false(1,nInp); 128 if isa(inpMat,'function_handle
') 129 inpMat=func2str(inpMat); 131 if isnumeric(inpMat)||islogical(inpMat)||ischar(inpMat) 132 [~,~,indMat(:,iRow)]=mxberry.core.uniquerows(inpMat,false,prop{:}); 133 elseif isstruct(inpMat) 134 curMat=reshape(mxberry.core.num2cell(... 135 permute(struct2cell(inpMat),[2 3 1]),[1 2]),1,[]); 136 [~,~,indMat(:,iRow)]=uniquejoint(curMat,1); 138 nCols=size(inpMat,2); 139 isCharStr=iscellstr(inpMat); 140 isNumCell=iscell(inpMat)&&~isCharStr; 146 isIntCell=all(cellfun(@(x)isinteger(x)||islogical(x),inpMat)); 148 isNumCell=all(cellfun(@isnumeric,inpMat)); 151 isStructCell=all(cellfun('isclass
',inpMat,'struct')); 153 isCharStr=all(cellfun('isclass
',inpMat,'function_handle
')); 155 inpMat=cellfun(@func2str,inpMat,'UniformOutput
',false); 157 isCharCell=all(cellfun(@iscellstr,inpMat)); 161 inpMat=reshape(inpMat,[],nCols); 163 indColMat=nan(nInpElem,nCols); 166 [~,~,indColMat(:,iCol)]=unique(inpMat(:,iCol),'legacy
'); 168 elseif isNumCell||isStructCell||isCharCell 170 inpVec=inpMat(:,iCol); 171 curIndMat=zeros(nInpElem,2); 173 inpMat=cellfun(@orderfields,inpVec,'UniformOutput
',false); 174 curMat=cellfun(@fieldnames,inpVec,'UniformOutput
',false); 175 [sizeVars,~,curIndMat(:,1)]=unique(cellfun('prodofsize
',curMat),... 177 nVars=size(sizeVars,1); 179 isVar=curIndMat(:,1)==iVar; 180 [~,~,curIndMat(isVar,2)]=uniquejoint({horzcat(curMat{isVar}).'},1);
182 [~,~,curMat]=
mxberry.
core.uniquerows(curIndMat,
true,prop{:});
183 transformFunc=@(x)reshape(struct2cell(reshape(x,1,numel(x))),1,[]);
186 transformFunc=@(x)reshape(x,1,[]);
189 transformFunc=@(x)reshape(
double(x),1,[]);
191 [sizeVars,~,curIndMat(:,1)]=
mxberry.
core.uniquerows(...
192 [cellfun(
'ndims',inpVec),...
193 cellfun(
'prodofsize',inpVec),curMat],
true,prop{:});
194 nVars=size(sizeVars,1);
197 isVar=curIndMat(:,1)==iVar;
198 curMat=[cellfun(@size,inpVec(isVar),
'UniformOutput',
false),...
199 cellfun(transformFunc,inpVec(isVar),
'UniformOutput',
false)];
200 nElems=size(curMat,1);
201 curMat=horzcat(curMat{:});
203 nDims=sizeVars(iVar,1);
206 transpose(reshape(curMat(1:nDims*nElems),[],nElems)),...
207 transpose(reshape(curMat(nDims*nElems+1:end),[],nElems))];
209 [~,~,curIndMat(isVar,2)]=
mxberry.
core.uniquerows(curMat,isIntCell,prop{:});
211 curMat=[{vertcat(curMat{:,1})},
mxberry.
core.num2cell(curMat(:,2:end),1)];
216 [~,~,indColMat(:,iCol)]=
mxberry.
core.uniquerows(curIndMat,
true,prop{:});
218 indColMat(:,iCol)=curIndMat(:,2);
221 elseif isa(inpMat,
'opaque')&&ismethod(inpMat,
'sort')
226 isnSorted(iRow)=true;
232 indMat(:,iRow)=indColMat;
238 isSorted=~any(isnSorted);
240 indMat=[indMat(:,~isnSorted) indMat(:,isnSorted)];
243 isBackwardInd=nargout>2;
247 indLeft2RightVec=ones(nInpElem,1);
251 [~,indRight2LeftVec,indLeft2RightVec]=
unique(indMat);
253 [~,indRight2LeftVec]=
unique(indMat);
257 [~,indRight2LeftVec,indLeft2RightVec]=
mxberry.
core.uniquerows(indMat,
true,prop{:});
259 [~,indRight2LeftVec]=
mxberry.
core.uniquerows(indMat,
true,prop{:});
264 %index inpCell, not inpArray since an initial size should be preserved
265 unqCArr=cellfun(@(x)(x(indRight2LeftVec)),inpCArr,
'UniformOutput',
false);
267 if all(nDimsVec>=indDim)
268 nOutElem=length(indRight2LeftVec);
269 inpSizeVec=cellfun(@(x)[nOutElem x([1:indDim-1 indDim+1:end])],inpSizeVec,...
270 'UniformOutput',
false);
274 @(x,y)ipermute(reshape(x(indRight2LeftVec,:),y),permVec),...
275 inpCArr,inpSizeVec,
'UniformOutput',
false);
278 @(x,y)reshape(x(indRight2LeftVec,:),y),...
279 inpCArr,inpSizeVec,
'UniformOutput',
false);
function uniquesortableobj(in inpVec)
UNIQUE implementation strictly for sortable entities i.e. for those that have 1) full order defined b...
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 uniquerows(in inpMat, in isInteger, in forceMode)
UNIQUEROWS finds unique rows in input matrix, i.e. the more effective version of UNIQUE(. . .,'rows')
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 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...
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...