comparison m-toolbox/classes/@smodel/elementOp.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % ELEMENTOP applies the given operator to the input smodels.
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % DESCRIPTION: ELEMENTOP applies the given operator to the input smodels.
5 %
6 % CALL: a = elementOp(callerIsMethod, op, opname, opsym, infoObj, pl, fcnArgIn, varNames)
7 %
8 % PARAMETERS: op - MATLAB operation name
9 % opname - Name for displaying
10 % opsym - Operation symbol
11 % infoObj - minfo object
12 % pl - default plist
13 % fcnArgIn - Input argument list of the calling fcn.
14 % varNames - Variable names of the input
15 %
16 % VERSION: $Id: elementOp.m,v 1.14 2011/05/10 20:43:09 mauro Exp $
17 %
18 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19
20 function varargout = elementOp(varargin)
21
22 import utils.const.*
23
24 % Settings
25 callerIsMethod = varargin{1};
26 op = varargin{2};
27 opname = varargin{3};
28 opsym = varargin{4};
29
30 infoObj = varargin{5};
31 pl = varargin{6};
32
33 fcnArgIn = varargin{7};
34 varNames = varargin{8};
35
36 if numel(fcnArgIn) ~= 2 && numel(fcnArgIn) ~= 3
37 error('### ');
38 end
39
40 mdl1 = fcnArgIn{1};
41 mdl2 = fcnArgIn{2};
42
43 %%%%%%%%%% Convert numbers into a symbolic model object %%%%%%%%%%
44 if isnumeric(mdl1) || ischar(mdl1)
45 expr = mdl1;
46 varNames{1} = num2str(expr);
47 % Create an array with the same size of the second input
48 mdl1 = smodel.newarray(size(mdl2));
49 % Copy the object and replace the expression
50 for ii = 1:numel(mdl2)
51 mdl1(ii) = copy(mdl2(ii), true);
52 mdl1(ii).yunits = '';
53 mdl1(ii).expr = msym(expr);
54 % Do not duplicate yunits in case of product/division
55 if ~strcmpi(op, 'times') && ~strcmpi(op, 'rdivide')
56 mdl1(ii).yunits = mdl2(ii).yunits;
57 end
58 end
59 end
60 if isnumeric(mdl2) || ischar(mdl2)
61 expr = mdl2;
62 varNames{2} = num2str(expr);
63 % Create an array with the same size of the first input
64 mdl2 = smodel.newarray(size(mdl1));
65 % Copy the object and replace the expression
66 for ii = 1:numel(mdl1)
67 mdl2(ii) = copy(mdl1(ii), true);
68 mdl2(ii).yunits = '';
69 mdl2(ii).expr = msym(expr);
70
71 % Do not duplicate yunits in case of product/division
72 if ~strcmpi(op, 'times') && ~strcmpi(op, 'rdivide')
73 mdl2(ii).yunits = mdl1(ii).yunits;
74 end
75 end
76 end
77
78 % Convert cdata aos into a smodel object
79 if isa(mdl2, 'ao')
80 if isa(mdl2.data, 'cdata') && numel(mdl2.data.y) == 1
81 expr = mdl2.y;
82 % Create an array with the same size of the first input
83 mdl2 = smodel.newarray(size(mdl1));
84 % Copy the object and replace the expression
85 for ii = 1:numel(mdl1)
86 mdl2(ii) = copy(mdl1(ii), true);
87 mdl2(ii).expr = msym(expr);
88
89 end
90 else
91 error('### It is not possible to apply %s to the two objects!', opname);
92 end
93 end
94
95 %%%%%%%%%% If the first or second input is only one object then %%%%%%%%%%
96 %%%%%%%%%% resize the input to the size of the other object. %%%%%%%%%%
97 if numel(mdl1) == 1 && numel(mdl1) ~= numel(mdl2)
98 mdl1(1:numel(mdl2)) = mdl1;
99 mdl1 = reshape(mdl1, size(mdl2));
100 end
101 if numel(mdl2) == 1 && numel(mdl2) ~= numel(mdl1)
102 mdl2(1:numel(mdl1)) = mdl2;
103 mdl2 = reshape(mdl2, size(mdl1));
104 end
105
106 if ~all(size(mdl1) == size(mdl2))
107 error('### The Input objects must have the same size. Size of model1 [%d %d], model2 [%d %d]', size(mdl1,1), size(mdl1,2), size(mdl2,1), size(mdl2,2));
108 end
109
110 %%%%%%%%%% Add each element inside the array %%%%%%%%%%
111 mdl = smodel.newarray(size(mdl1));
112 for kk = 1:numel(mdl1)
113 switch opsym
114 case {'.*', '*'}
115 if any(strcmp(mdl1(kk).expr.s, {'0','(0)'})) || any(strcmp(mdl2(kk).expr.s, {'0','(0)'}))
116 % 0*something = 0
117 mdl(kk).expr = msym(['0']);
118 else
119 mdl(kk).expr = msym(['(' mdl1(kk).expr.s ')' opsym '(' mdl2(kk).expr.s ')']);
120 end
121 case {'./', '/'}
122 if any(strcmp(mdl1(kk).expr.s, {'0','(0)'}))
123 % 0/something = 0
124 mdl(kk).expr = msym(['0']);
125 else
126 mdl(kk).expr = msym(['(' mdl1(kk).expr.s ')' opsym '(' mdl2(kk).expr.s ')']);
127 end
128 case '+'
129 if any(strcmp(mdl1(kk).expr.s, {'0','(0)'}))
130 % 0 + something = something
131 mdl(kk).expr = msym([mdl2(kk).expr.s]);
132 elseif any(strcmp(mdl2(kk).expr.s, {'0','(0)'}))
133 % something + 0 = something
134 mdl(kk).expr = msym([mdl1(kk).expr.s]);
135 else
136 mdl(kk).expr = msym(['(' mdl1(kk).expr.s ')' opsym '(' mdl2(kk).expr.s ')']);
137 end
138 otherwise
139 mdl(kk).expr = msym(['(' mdl1(kk).expr.s ')' opsym '(' mdl2(kk).expr.s ')']);
140 end
141
142 mdl(kk).name = ['(' mdl1(kk).name ')' opsym '(' mdl2(kk).name ')'];
143
144 % Merge parameters, alias, xvar, tran fields
145 smodel.mergeFields(mdl1(kk), mdl2(kk), mdl(kk), 'params', 'values');
146 smodel.mergeFields(mdl1(kk), mdl2(kk), mdl(kk), 'aliasNames', 'aliasValues');
147 smodel.mergeFields(mdl1(kk), mdl2(kk), mdl(kk), 'xvar', 'xvals');
148 smodel.mergeFields(mdl1(kk), mdl2(kk), mdl(kk), 'xvar', 'xunits');
149 smodel.mergeFields(mdl1(kk), mdl2(kk), mdl(kk), 'xvar', 'trans');
150
151 % Take care of units
152 if strcmpi(op,'times')
153 mdl(kk).yunits = simplify(unit(unit(mdl1(kk).yunits).*unit(mdl2(kk).yunits)));
154 elseif strcmpi(op,'rdivide')
155 mdl(kk).yunits = simplify(unit(unit(mdl1(kk).yunits)./unit(mdl2(kk).yunits)));
156 else
157 mdl(kk).yunits = mdl1(kk).yunits;
158 if mdl1(kk).yunits ~= mdl2(kk).yunits
159 error('### Y units should be equal for %s', opname);
160 end
161 end
162
163 % Add history
164 if ~callerIsMethod
165 inname1 = varNames{1};
166 inname2 = varNames{2};
167 if numel(fcnArgIn{1}) > 1
168 [ii, jj] = ind2sub(size(fcnArgIn{1}), kk);
169 inname1 = sprintf('%s(%d,%d)', inname1, ii, jj);
170 end
171 if numel(fcnArgIn{2}) > 1
172 [ii, jj] = ind2sub(size(fcnArgIn{2}), kk);
173 inname2 = sprintf('%s(%d,%d)', inname2, ii, jj);
174 end
175 mdl(kk).addHistory(infoObj, pl, {inname1, inname2}, [mdl1(kk).hist mdl2(kk).hist]);
176 end
177 end
178
179 varargout{1} = mdl;
180
181 end
182
183