MatrixBerryCore
binaryunionstruct.m
Go to the documentation of this file.
1 function varargout=binaryunionstruct(leftStruct,rightStruct,fieldOpCell,leftFieldOpCell,rightFieldOpCell)
2 import mxberry.core.throwerror;
3 if nargin<2
4  throwerror('incorrectInput',...
5  'there should be at least 2 arguments');
6 end
7 %
8 sizeStructVec=size(leftStruct);
9 if ~(isstruct(leftStruct)&&isstruct(rightStruct)&&...
10  mxberry.core.checksize(leftStruct,rightStruct,sizeStructVec))
11  throwerror('incorrectInput',...
12  'first and second inputs should be structure arrays of the same size');
13 end
14 %
15 nDims=ndims(leftStruct);
16 %
17 if nargin<=2
18  fieldOpCell={@binarynotdefined};
19 elseif isa(fieldOpCell,'function_handle')
20  fieldOpCell={fieldOpCell};
21 end
22 %
23 
24 nOps=length(fieldOpCell);
25 %
26 if nargin<=4
27  rightFieldOpCell=repmat({@(x)deal(x)},1,nOps);
28  if nargin<=3
29  leftFieldOpCell=repmat({@(x)deal(x)},1,nOps);
30  end
31 
32 end
33 %
34 if isa(leftFieldOpCell,'function_handle')
35  leftFieldOpCell={leftFieldOpCell};
36 end
37 %
38 if isa(rightFieldOpCell,'function_handle')
39  rightFieldOpCell={rightFieldOpCell};
40 end
41 %
42 isValid=auxcheckfuncell(fieldOpCell);
43 if ~isValid
44  throwerror('incorrectInput',...
45  ['the third argument(fieldOpCell) should be a function handle',...
46  'or cell array of function handles']);
47 end
48 %
49 isValid=auxcheckfuncell(leftFieldOpCell);
50 if ~isValid
51  throwerror('incorrectInput',...
52  ['the fourth argument(leftFieldOpCell) should be a function ',...
53  'handle or cell array of function handles']);
54 end
55 %
56 isValid=auxcheckfuncell(rightFieldOpCell);
57 if ~isValid
58  throwerror('incorrectInput',...
59  ['the fifth argument(rightFieldOpCell) should be a function ',...
60  'handle or cell array of function handles']);
61 end
62 %
63 leftFieldList=fieldnames(leftStruct);
64 rightFieldList=fieldnames(rightStruct);
65 unitedFieldList=reshape(union(leftFieldList,rightFieldList),[],1);
66 isLeftField=ismember(unitedFieldList,leftFieldList);
67 isRightField=ismember(unitedFieldList,rightFieldList);
68 isCommonField=isLeftField&isRightField;
69 %
70 nFields=length(unitedFieldList);
71 nFieldOps=length(fieldOpCell);
72 %
73 nArgout=nargout;
74 %this cell array will contain result
75 resCell=cell(nArgout,nFields);
76 %this field is a temporary variable containing result for a specific field
77 resTmpCell=cell(nArgout,1);
78 %
79 for iField=1:nFields
80  fieldName=unitedFieldList{iField};
81  if isCommonField(iField)
82  for iFieldOp=1:nFieldOps
83  %
84  fieldOp=fieldOpCell{iFieldOp};
85  %
86  [resTmpCell{:}]=cellfun(fieldOp,...
87  reshape({leftStruct.(fieldName)},sizeStructVec),...
88  reshape({rightStruct.(fieldName)},sizeStructVec),...
89  'UniformOutput',false);
90  %
91  updaterescell();
92  %
93  end
94  elseif isLeftField(iField)
95  for iFieldOp=1:nFieldOps
96  leftFieldOp=leftFieldOpCell{iFieldOp};
97  %
98  [resTmpCell{:}]=cellfun(leftFieldOp,reshape(...
99  {leftStruct.(fieldName)},sizeStructVec),...
100  'UniformOutput',false);
101  %
102  updaterescell();
103  %
104  end
105  else
106  for iFieldOp=1:nFieldOps
107  rightFieldOp=rightFieldOpCell{iFieldOp};
108  %
109  [resTmpCell{:}]=cellfun(rightFieldOp,reshape(...
110  {rightStruct.(fieldName)},sizeStructVec),...
111  'UniformOutput',false);
112  %
113  updaterescell();
114  %
115  end
116  end
117 end
118 %
119 unitedFieldList=transpose(unitedFieldList);
120 %
121 varargout=cell(1,nArgout);
122 for iOut=1:nArgout
123  defCell=[unitedFieldList;resCell(iOut,:)];
124  varargout{iOut}=struct(defCell{:});
125 end
126  function updaterescell
127  resCell(:,iField)=cellfun(@(x,y)cat(nDims+1,x,y),...
128  resCell(:,iField),resTmpCell,'UniformOutput',false);
129  end
130 end
131 
132 function varargout=binarynotdefined(varargin)
133 varargout{:}=[];
134 mxberry.core.throwerror('illegalOperation',...
135  ['common fields cannot be processed by default, ',...
136  'binary operation required']);
137 end
138 
139 function isValid=auxcheckfuncell(fieldOpCell)
140 isValid=iscell(fieldOpCell);
141 if ~isValid
142  isAllFuncVec=cellfun(@(x)isa(x,'function_handle'),fieldOpCell);
143  isValid=all(isAllFuncVec);
144 end
145 end
function updaterescell()
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 binaryunionstruct(in leftStruct, in rightStruct, in fieldOpCell, in leftFieldOpCell, in rightFieldOpCell)
BINARYUNIONSTRUCT applies a set of binary operations to the fields of two structures, each operation can return multiple results.
function auxcheckfuncell(in fieldOpCell)
function repmat(in inpArray, in varargin)
function binarynotdefined(in varargin)
function ismember(in leftVec, in rightVec, in varargin)
ISMEMBER - ismember implementation for arrays of any type.
function cat(in dimNum, in varargin)