Mercurial > hg > ltpda
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 |