1 | package de.uka.ipd.sdq.pcmsolver.exprsolver; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.List; |
5 | |
6 | import org.apache.log4j.Logger; |
7 | |
8 | import de.uka.ipd.sdq.pcmsolver.visitors.ExpressionHelper; |
9 | import de.uka.ipd.sdq.probfunction.ProbabilityMassFunction; |
10 | import de.uka.ipd.sdq.probfunction.math.IProbabilityDensityFunction; |
11 | import de.uka.ipd.sdq.probfunction.math.IProbabilityFunctionFactory; |
12 | import de.uka.ipd.sdq.probfunction.math.IProbabilityMassFunction; |
13 | import de.uka.ipd.sdq.probfunction.math.ISample; |
14 | import de.uka.ipd.sdq.probfunction.math.ISamplePDF; |
15 | import de.uka.ipd.sdq.probfunction.math.IUnit; |
16 | import de.uka.ipd.sdq.probfunction.math.ManagedPDF; |
17 | import de.uka.ipd.sdq.probfunction.math.PDFConfiguration; |
18 | import de.uka.ipd.sdq.probfunction.math.exception.ConfigurationNotSetException; |
19 | import de.uka.ipd.sdq.probfunction.math.exception.FunctionsInDifferenDomainsException; |
20 | import de.uka.ipd.sdq.probfunction.math.exception.IncompatibleUnitsException; |
21 | import de.uka.ipd.sdq.probfunction.math.exception.UnknownPDFTypeException; |
22 | import de.uka.ipd.sdq.spa.expression.Alternative; |
23 | import de.uka.ipd.sdq.spa.expression.Expression; |
24 | import de.uka.ipd.sdq.spa.expression.Loop; |
25 | import de.uka.ipd.sdq.spa.expression.Sequence; |
26 | import de.uka.ipd.sdq.spa.expression.Symbol; |
27 | import de.uka.ipd.sdq.spa.expression.util.ExpressionSwitch; |
28 | import de.uka.ipd.sdq.spa.resourcemodel.ResourceUsage; |
29 | import de.uka.ipd.sdq.stoex.ProbabilityFunctionLiteral; |
30 | import flanagan.complex.Complex; |
31 | |
32 | public class ExpressionSolver { |
33 | |
34 | private static Logger logger = Logger.getLogger(ExpressionSolver.class |
35 | .getName()); |
36 | |
37 | private IProbabilityFunctionFactory pfFactory = IProbabilityFunctionFactory.eINSTANCE; |
38 | |
39 | public ExpressionSolver() { |
40 | } |
41 | |
42 | public ManagedPDF getResponseTime(Expression expr) { |
43 | return (ManagedPDF) exprSwitch.doSwitch(expr); |
44 | } |
45 | |
46 | private ExpressionSwitch exprSwitch = new ExpressionSwitch() { |
47 | |
48 | @Override |
49 | public Object caseAlternative(Alternative object) { |
50 | |
51 | // Do the logging: |
52 | logger.debug("Visit Alternative"); |
53 | |
54 | ManagedPDF leftManagedPDF = (ManagedPDF) doSwitch(object |
55 | .getLeftOption().getRegexp()); |
56 | ManagedPDF rightManagedPDF = (ManagedPDF) doSwitch(object |
57 | .getRightOption().getRegexp()); |
58 | |
59 | if (leftManagedPDF == null && rightManagedPDF != null) |
60 | return rightManagedPDF; |
61 | else if (leftManagedPDF != null && rightManagedPDF == null) |
62 | return leftManagedPDF; |
63 | else if (leftManagedPDF == null && rightManagedPDF == null) { |
64 | return null; |
65 | } |
66 | |
67 | IProbabilityDensityFunction leftPDF = leftManagedPDF |
68 | .getPdfFrequencyDomain(); |
69 | IProbabilityDensityFunction rightPDF = rightManagedPDF |
70 | .getPdfFrequencyDomain(); |
71 | |
72 | double leftProb = object.getLeftOption().getProbability(); |
73 | double rightProb = object.getRightOption().getProbability(); |
74 | |
75 | IProbabilityDensityFunction resultPDF = null; |
76 | try { |
77 | resultPDF = leftPDF.scale(leftProb).add( |
78 | rightPDF.scale(rightProb)); |
79 | } catch (FunctionsInDifferenDomainsException e) { |
80 | e.printStackTrace(); |
81 | } catch (UnknownPDFTypeException e) { |
82 | e.printStackTrace(); |
83 | } catch (IncompatibleUnitsException e) { |
84 | e.printStackTrace(); |
85 | } |
86 | |
87 | return new ManagedPDF(resultPDF, true); |
88 | } |
89 | |
90 | @Override |
91 | public Object caseLoop(Loop object) { |
92 | |
93 | // Do the logging: |
94 | logger.debug("Visit Loop"); |
95 | |
96 | ManagedPDF innerManagedPDF = (ManagedPDF) doSwitch(object |
97 | .getRegExp()); |
98 | if (innerManagedPDF == null) |
99 | return null; |
100 | |
101 | IProbabilityMassFunction iterations = getIterPMF(object); |
102 | |
103 | reconfigureForLoopBody(innerManagedPDF, iterations); |
104 | |
105 | ISamplePDF innerPDF = innerManagedPDF.getSamplePdfFrequencyDomain(); |
106 | ISamplePDF resultPDF = null; |
107 | ISamplePDF tempPDF = null; |
108 | try { |
109 | resultPDF = ManagedPDF.createZeroFunction() |
110 | .getSamplePdfFrequencyDomain(); |
111 | tempPDF = ManagedPDF.createDiracImpulse() |
112 | .getSamplePdfFrequencyDomain(); |
113 | } catch (ConfigurationNotSetException e) { |
114 | e.printStackTrace(); |
115 | } |
116 | |
117 | int pos = 0; |
118 | List<ISample> samples = iterations.getSamples(); |
119 | try { |
120 | for (ISample sample : samples) { |
121 | Integer nextPos = (Integer) sample.getValue(); |
122 | while (pos < nextPos) { |
123 | tempPDF = (ISamplePDF) tempPDF.mult(innerPDF); |
124 | pos++; |
125 | } |
126 | resultPDF = (ISamplePDF) resultPDF.add(tempPDF.scale(sample |
127 | .getProbability())); |
128 | } |
129 | } catch (FunctionsInDifferenDomainsException e) { |
130 | e.printStackTrace(); |
131 | } catch (UnknownPDFTypeException e) { |
132 | e.printStackTrace(); |
133 | } catch (IncompatibleUnitsException e) { |
134 | e.printStackTrace(); |
135 | } |
136 | |
137 | return new ManagedPDF(resultPDF, true); |
138 | } |
139 | |
140 | /** |
141 | * Adjusts the maximum domain size of the managed PDFs, if the function |
142 | * resulting from convoluting the inner loop PDFs would need more |
143 | * sampling points. |
144 | * |
145 | * @param innerManagedPDF |
146 | * @param iterations |
147 | */ |
148 | private void reconfigureForLoopBody(ManagedPDF innerManagedPDF, |
149 | IProbabilityMassFunction iterations) { |
150 | |
151 | int maxDomainSize = (int) (getMaxIterations(iterations) * getLargestSamplingValue(innerManagedPDF)); |
152 | |
153 | try { |
154 | PDFConfiguration config = PDFConfiguration |
155 | .getCurrentConfiguration(); |
156 | int currentDomainSize = config.getNumSamplingPoints(); |
157 | if (currentDomainSize < maxDomainSize) { |
158 | double distance = config.getDistance(); |
159 | IUnit unit = config.getUnit(); |
160 | logger.debug("Adjusting MaxDomainSize from " |
161 | + currentDomainSize + " to " + maxDomainSize); |
162 | PDFConfiguration.setCurrentConfiguration(maxDomainSize, |
163 | distance, unit); |
164 | } |
165 | } catch (ConfigurationNotSetException e1) { |
166 | e1.printStackTrace(); |
167 | } |
168 | } |
169 | |
170 | private double getLargestSamplingValue(ManagedPDF innerManagedPDF) { |
171 | ISamplePDF innerSamplePDF = innerManagedPDF |
172 | .getSamplePdfTimeDomain(); |
173 | |
174 | double largestValue = 0.0; |
175 | List<Complex> list = innerSamplePDF.getValues(); |
176 | for (int i = list.size() - 1; i >= 0; i--) { |
177 | Complex z = list.get(i); |
178 | double prob = ((double) Math.round(z.getReal() * 10000.0)) / 10000.0; |
179 | if (prob > 0.0) { |
180 | largestValue = i; |
181 | break; |
182 | } |
183 | } |
184 | return largestValue; |
185 | } |
186 | |
187 | private int getMaxIterations(IProbabilityMassFunction iterations) { |
188 | List<ISample> sampleList = iterations.getSamples(); |
189 | int maxIterations = 0; |
190 | for (int i = sampleList.size() - 1; i >= 0; i--) { |
191 | ISample sample = sampleList.get(i); |
192 | if (sample.getProbability() != 0.0) { |
193 | maxIterations = (Integer) sample.getValue(); |
194 | break; |
195 | } |
196 | } |
197 | return maxIterations; |
198 | } |
199 | |
200 | private IProbabilityMassFunction getIterPMF(Loop object) { |
201 | String iter = object.getIterationsString(); |
202 | try { |
203 | int iterInt = Integer.parseInt(iter); |
204 | ISample sample = pfFactory.createSample(iterInt, 1.0); |
205 | List<ISample> sampleList = new ArrayList<ISample>(); |
206 | sampleList.add(sample); |
207 | IUnit unit = pfFactory.createDefaultUnit(); |
208 | return pfFactory.createProbabilityMassFunction(sampleList, |
209 | unit, true); |
210 | } catch (NumberFormatException e) { |
211 | ProbabilityFunctionLiteral loopLiteral = (ProbabilityFunctionLiteral) ExpressionHelper |
212 | .parseToExpression(object.getIterationsString()); |
213 | ProbabilityMassFunction loopPMF = (ProbabilityMassFunction) loopLiteral |
214 | .getFunction_ProbabilityFunctionLiteral(); |
215 | // return pfFactory.transformToPMF( object.getIterationsPMF() ); |
216 | return pfFactory.transformToPMF(loopPMF); |
217 | } |
218 | } |
219 | |
220 | @Override |
221 | public Object caseSequence(Sequence object) { |
222 | |
223 | // Do the logging: |
224 | logger.debug("Visit Sequence"); |
225 | |
226 | ManagedPDF leftManagedPDF = (ManagedPDF) doSwitch(object |
227 | .getLeftRegExp()); |
228 | ManagedPDF rightManagedPDF = (ManagedPDF) doSwitch(object |
229 | .getRightRegExp()); |
230 | |
231 | if (leftManagedPDF == null && rightManagedPDF != null) |
232 | return rightManagedPDF; |
233 | else if (leftManagedPDF != null && rightManagedPDF == null) |
234 | return leftManagedPDF; |
235 | else if (leftManagedPDF == null && rightManagedPDF == null) { |
236 | return null; |
237 | } |
238 | |
239 | IProbabilityDensityFunction leftPDF = leftManagedPDF |
240 | .getPdfFrequencyDomain(); |
241 | IProbabilityDensityFunction rightPDF = rightManagedPDF |
242 | .getPdfFrequencyDomain(); |
243 | |
244 | IProbabilityDensityFunction resultPDF = null; |
245 | try { |
246 | resultPDF = leftPDF.mult(rightPDF); |
247 | } catch (FunctionsInDifferenDomainsException e) { |
248 | e.printStackTrace(); |
249 | } catch (UnknownPDFTypeException e) { |
250 | e.printStackTrace(); |
251 | } catch (IncompatibleUnitsException e) { |
252 | e.printStackTrace(); |
253 | } |
254 | |
255 | return new ManagedPDF(resultPDF, true); |
256 | } |
257 | |
258 | @Override |
259 | public Object caseSymbol(Symbol object) { |
260 | |
261 | // Do the logging: |
262 | logger.debug("Visit Symbol: " + object.getName()); |
263 | |
264 | List<ResourceUsage> resourceUsageList = (List<ResourceUsage>) object |
265 | .getResourceUsages(); |
266 | IProbabilityDensityFunction resultPDF = null; |
267 | for (ResourceUsage resourceUsage : resourceUsageList) { |
268 | ManagedPDF managedPDF = new ManagedPDF(resourceUsage |
269 | .getUsageTime(), true); |
270 | IProbabilityDensityFunction iPDF = managedPDF |
271 | .getPdfFrequencyDomain(); |
272 | |
273 | if (resultPDF == null) { |
274 | resultPDF = iPDF; |
275 | } else { |
276 | try { |
277 | resultPDF = resultPDF.mult(iPDF); // add up resource |
278 | // demands |
279 | } catch (FunctionsInDifferenDomainsException e) { |
280 | e.printStackTrace(); |
281 | } catch (UnknownPDFTypeException e) { |
282 | e.printStackTrace(); |
283 | } catch (IncompatibleUnitsException e) { |
284 | e.printStackTrace(); |
285 | } |
286 | } |
287 | |
288 | } |
289 | if (resultPDF == null) |
290 | return null; |
291 | else |
292 | return new ManagedPDF(resultPDF, true); |
293 | } |
294 | |
295 | }; |
296 | |
297 | } |