1 | package de.uka.ipd.sdq.probfunction.math; |
2 | |
3 | import java.util.List; |
4 | |
5 | import org.antlr.runtime.ANTLRStringStream; |
6 | import org.antlr.runtime.CommonTokenStream; |
7 | import org.antlr.runtime.RecognitionException; |
8 | import org.eclipse.emf.common.util.EList; |
9 | |
10 | import de.uka.ipd.sdq.probfunction.BoxedPDF; |
11 | import de.uka.ipd.sdq.probfunction.ContinuousSample; |
12 | import de.uka.ipd.sdq.probfunction.ProbabilityDensityFunction; |
13 | import de.uka.ipd.sdq.probfunction.SamplePDF; |
14 | import de.uka.ipd.sdq.probfunction.math.exception.ConfigurationNotSetException; |
15 | import de.uka.ipd.sdq.probfunction.math.exception.FunctionNotInFrequencyDomainException; |
16 | import de.uka.ipd.sdq.probfunction.math.exception.FunctionNotInTimeDomainException; |
17 | import de.uka.ipd.sdq.probfunction.math.exception.ProbabilityFunctionException; |
18 | import de.uka.ipd.sdq.probfunction.math.exception.StringNotPDFException; |
19 | import de.uka.ipd.sdq.probfunction.math.exception.UnknownPDFTypeException; |
20 | import de.uka.ipd.sdq.probfunction.math.util.MathTools; |
21 | import de.uka.ipd.sdq.probfunction.print.ProbFunctionPrettyPrint; |
22 | import de.uka.ipd.sdq.stoex.ProbabilityFunctionLiteral; |
23 | import de.uka.ipd.sdq.stoex.parser.StochasticExpressionsLexer; |
24 | import de.uka.ipd.sdq.stoex.parser.StochasticExpressionsParser; |
25 | |
26 | /** |
27 | * To be continued... |
28 | * |
29 | * @author jens |
30 | * |
31 | */ |
32 | public class ManagedPDF { |
33 | |
34 | private IProbabilityDensityFunction pdfTimeDomain; |
35 | |
36 | private ISamplePDF samplePdfTimeDomain; |
37 | |
38 | private IBoxedPDF boxedPdfTimeDomain; |
39 | |
40 | private IProbabilityDensityFunction pdfFrequencyDomain; |
41 | |
42 | private ISamplePDF samplePdfFrequencyDomain; |
43 | |
44 | private ProbabilityDensityFunction modelPDF; |
45 | |
46 | private BoxedPDF modelBoxedPDF; |
47 | |
48 | private SamplePDF modelSamplePDF; |
49 | |
50 | private boolean useConfiguration = false; |
51 | |
52 | private static String pdfAsString; |
53 | |
54 | private double meanValue; |
55 | |
56 | private ISamplePDF cumulativeDistributionFunction; |
57 | |
58 | private static IProbabilityFunctionFactory pfFactory = IProbabilityFunctionFactory.eINSTANCE; |
59 | |
60 | private ManagedPDF() { |
61 | reset(); |
62 | } |
63 | |
64 | public ManagedPDF(ProbabilityDensityFunction pdf) { |
65 | this(); |
66 | this.useConfiguration = false; |
67 | setModelPdf(pdf); |
68 | } |
69 | |
70 | public ManagedPDF(IProbabilityDensityFunction pdf) { |
71 | this(); |
72 | this.useConfiguration = false; |
73 | setPdf(pdf); |
74 | } |
75 | |
76 | public ManagedPDF(IProbabilityDensityFunction pdf, boolean useConfiguration) { |
77 | this(); |
78 | this.useConfiguration = useConfiguration; |
79 | setPdf(pdf); |
80 | } |
81 | |
82 | public ManagedPDF(ProbabilityDensityFunction pdf, boolean useConfiguration) { |
83 | this(); |
84 | this.useConfiguration = useConfiguration; |
85 | setModelPdf(pdf); |
86 | } |
87 | |
88 | public ManagedPDF(double distance, |
89 | List<Double> values, IUnit unit, boolean useConfiguration) { |
90 | this.useConfiguration = useConfiguration; |
91 | IProbabilityDensityFunction pdf = pfFactory.createSamplePDFFromMeasurements(distance, values, unit); |
92 | setPdf(pdf); |
93 | } |
94 | |
95 | private void reset() { |
96 | this.pdfFrequencyDomain = null; |
97 | this.samplePdfFrequencyDomain = null; |
98 | this.pdfTimeDomain = null; |
99 | this.samplePdfTimeDomain = null; |
100 | this.boxedPdfTimeDomain = null; |
101 | this.modelPDF = null; |
102 | this.modelBoxedPDF = null; |
103 | this.modelSamplePDF = null; |
104 | this.pdfAsString = null; |
105 | this.cumulativeDistributionFunction = null; |
106 | this.meanValue = -1; |
107 | } |
108 | |
109 | public IProbabilityDensityFunction getPdfTimeDomain() { |
110 | if (pdfTimeDomain == null) { |
111 | if (modelPDF != null) { |
112 | try { |
113 | pdfTimeDomain = IProbabilityFunctionFactory.eINSTANCE |
114 | .transformToPDF(modelPDF); |
115 | } catch (ProbabilityFunctionException e) { |
116 | e.printStackTrace(); |
117 | throw new RuntimeException(e); |
118 | } |
119 | } else if (pdfFrequencyDomain != null) |
120 | try { |
121 | pdfTimeDomain = pdfFrequencyDomain |
122 | .getInverseFourierTransform(); |
123 | } catch (FunctionNotInFrequencyDomainException e) { |
124 | e.printStackTrace(); |
125 | throw new RuntimeException(e); |
126 | } |
127 | } |
128 | return pdfTimeDomain; |
129 | } |
130 | |
131 | public IBoxedPDF getBoxedPdfTimeDomain() { |
132 | if (this.boxedPdfTimeDomain == null) { |
133 | try { |
134 | this.boxedPdfTimeDomain = pfFactory |
135 | .transformToBoxedPDF(getPdfTimeDomain()); |
136 | } catch (ProbabilityFunctionException e) { |
137 | e.printStackTrace(); |
138 | throw new RuntimeException(e); |
139 | } |
140 | } |
141 | return this.boxedPdfTimeDomain; |
142 | } |
143 | |
144 | public ISamplePDF getSamplePdfTimeDomain() { |
145 | if (this.samplePdfTimeDomain == null) { |
146 | try { |
147 | this.samplePdfTimeDomain = pfFactory |
148 | .transformToSamplePDF(getPdfTimeDomain()); |
149 | } catch (UnknownPDFTypeException e) { |
150 | e.printStackTrace(); |
151 | throw new RuntimeException(e); |
152 | } |
153 | } |
154 | return this.samplePdfTimeDomain; |
155 | |
156 | } |
157 | |
158 | public ISamplePDF getSamplePdfFrequencyDomain() { |
159 | if (this.samplePdfFrequencyDomain == null) { |
160 | try { |
161 | this.samplePdfFrequencyDomain = pfFactory |
162 | .transformToSamplePDF(getPdfFrequencyDomain()); |
163 | } catch (UnknownPDFTypeException e) { |
164 | e.printStackTrace(); |
165 | throw new RuntimeException(e); |
166 | } |
167 | } |
168 | return this.samplePdfFrequencyDomain; |
169 | } |
170 | |
171 | public IProbabilityDensityFunction getPdfFrequencyDomain() { |
172 | if (pdfFrequencyDomain == null) { |
173 | if (this.getPdfTimeDomain() != null) |
174 | try { |
175 | pdfFrequencyDomain = this.getPdfTimeDomain() |
176 | .getFourierTransform(); |
177 | } catch (FunctionNotInTimeDomainException e) { |
178 | e.printStackTrace(); |
179 | throw new RuntimeException(e); |
180 | } |
181 | } |
182 | return pdfFrequencyDomain; |
183 | } |
184 | |
185 | private void setPdf(IProbabilityDensityFunction pdf) { |
186 | reset(); |
187 | if (pdf.isInFrequencyDomain()) { |
188 | pdfFrequencyDomain = pdf; |
189 | } else { |
190 | pdfTimeDomain = pdf; |
191 | } |
192 | adjustToConfiguration(); |
193 | } |
194 | |
195 | private void setModelPdf(ProbabilityDensityFunction pdf) { |
196 | reset(); |
197 | this.modelPDF = pdf; |
198 | adjustToConfiguration(); |
199 | } |
200 | |
201 | private void adjustToConfiguration() { |
202 | try { |
203 | if (useConfiguration) { |
204 | try { |
205 | PDFConfiguration config = PDFConfiguration |
206 | .getCurrentConfiguration(); |
207 | if (config != null) { |
208 | IProbabilityDensityFunction pdf = getPdfTimeDomain(); |
209 | ISamplePDF samplePDF = null; |
210 | boolean changed = false; |
211 | |
212 | if (!(pdf instanceof ISamplePDF)) { |
213 | changed = true; |
214 | samplePDF = pfFactory.transformToSamplePDF(pdf); |
215 | } else { |
216 | samplePDF = (ISamplePDF) pdf; |
217 | } |
218 | |
219 | if (!config.getUnit().equals(samplePDF.getUnit())) { |
220 | changed = true; |
221 | // TODO correct conversion of units!! |
222 | samplePDF = pfFactory.createSamplePDFFromComplex( |
223 | samplePDF.getDistance(), samplePDF |
224 | .getValues(), false, config |
225 | .getUnit()); |
226 | } |
227 | |
228 | if (!MathTools.equalsDouble(config.getDistance(), |
229 | samplePDF.getDistance())) { |
230 | changed = true; |
231 | samplePDF = samplePDF |
232 | .getFunctionWithNewDistance(config |
233 | .getDistance()); |
234 | } |
235 | |
236 | if (config.getNumSamplingPoints() > samplePDF |
237 | .numberOfSamples()) { |
238 | changed = true; |
239 | samplePDF.expand(config.getNumSamplingPoints()); |
240 | } |
241 | |
242 | if (changed) { |
243 | setPdf(samplePDF); |
244 | } |
245 | } |
246 | } catch (ConfigurationNotSetException e) { |
247 | System.err.println("No configuration for pdf's found!"); |
248 | } |
249 | } |
250 | } catch (ProbabilityFunctionException e) { |
251 | e.printStackTrace(); |
252 | throw new RuntimeException(e); |
253 | } |
254 | } |
255 | |
256 | public ProbabilityDensityFunction getModelPdf() { |
257 | try { |
258 | if (this.modelPDF == null) { |
259 | this.modelPDF = IProbabilityFunctionFactory.eINSTANCE |
260 | .transformToModelPDF(this.getPdfTimeDomain()); |
261 | } |
262 | } catch (ProbabilityFunctionException e) { |
263 | e.printStackTrace(); |
264 | throw new RuntimeException(e); |
265 | } |
266 | return this.modelPDF; |
267 | } |
268 | |
269 | public boolean isComplete() { |
270 | // TODO: Check new unit model |
271 | return true; |
272 | } |
273 | |
274 | public static ManagedPDF createDiracImpulse() |
275 | throws ConfigurationNotSetException { |
276 | return createImpulseAt(0); |
277 | } |
278 | |
279 | public static ManagedPDF createImpulseAt(int pos) |
280 | throws ConfigurationNotSetException { |
281 | PDFConfiguration config = PDFConfiguration.getCurrentConfiguration(); |
282 | IProbabilityDensityFunction pdf = pfFactory |
283 | .createImpulseAt(pos, config.getNumSamplingPoints(), config |
284 | .getDistance(), config.getUnit()); |
285 | return new ManagedPDF(pdf, true); |
286 | } |
287 | |
288 | public static ManagedPDF createZeroFunction() |
289 | throws ConfigurationNotSetException { |
290 | PDFConfiguration config = PDFConfiguration.getCurrentConfiguration(); |
291 | IProbabilityDensityFunction pdf = pfFactory |
292 | .createZeroFunction(config.getNumSamplingPoints(), config |
293 | .getDistance(), config.getUnit()); |
294 | return new ManagedPDF(pdf, true); |
295 | } |
296 | |
297 | @Override |
298 | public String toString() { |
299 | if (pdfAsString == null) { |
300 | ProbabilityDensityFunction pdf = getModelBoxedPdf(); |
301 | ProbFunctionPrettyPrint pp = new ProbFunctionPrettyPrint(); |
302 | pdfAsString = (String) pp.doSwitch(pdf); |
303 | } |
304 | return pdfAsString; |
305 | } |
306 | |
307 | // private static ProbabilityFunctionLiteral parse(String s) throws RecognitionException { |
308 | // StochasticExpressionsLexer lexer = new StochasticExpressionsLexer( |
309 | // new ANTLRStringStream(s)); |
310 | // StochasticExpressionsParser parser = new StochasticExpressionsParser( |
311 | // new CommonTokenStream(lexer)); |
312 | // return (ProbabilityFunctionLiteral)parser.expression(); |
313 | // } |
314 | // |
315 | // @SuppressWarnings("deprecation") |
316 | // public static ManagedPDF createFromString(String pdfAsString) |
317 | // throws RecognitionException, |
318 | // StringNotPDFException { |
319 | // ProbabilityFunctionLiteral value = parse(pdfAsString); |
320 | // try { |
321 | // ProbabilityDensityFunction pdf = (ProbabilityDensityFunction) value |
322 | // .getFunction_ProbabilityFunctionLiteral(); |
323 | // return new ManagedPDF(pdf); |
324 | // } catch (ClassCastException e) { |
325 | // throw new StringNotPDFException(); |
326 | // } |
327 | // } |
328 | |
329 | public BoxedPDF getModelBoxedPdf() { |
330 | if (modelBoxedPDF == null) { |
331 | try { |
332 | modelBoxedPDF = pfFactory |
333 | .transformToModelBoxedPDF(getBoxedPdfTimeDomain()); |
334 | } catch (ProbabilityFunctionException e) { |
335 | e.printStackTrace(); |
336 | throw new RuntimeException(e); |
337 | } |
338 | } |
339 | return modelBoxedPDF; |
340 | } |
341 | |
342 | public SamplePDF getModelSamplePDF() { |
343 | if (modelSamplePDF == null) { |
344 | try { |
345 | modelSamplePDF = pfFactory |
346 | .transformToModelSamplePDF(getSamplePdfTimeDomain()); |
347 | } catch (UnknownPDFTypeException e) { |
348 | e.printStackTrace(); |
349 | throw new RuntimeException(e); |
350 | } |
351 | } |
352 | return modelSamplePDF; |
353 | } |
354 | |
355 | public double getMeanValue() { |
356 | if (this.meanValue < 0) { |
357 | try { |
358 | meanValue = this.getPdfTimeDomain().getArithmeticMeanValue(); |
359 | } catch (ProbabilityFunctionException e) { |
360 | e.printStackTrace(); |
361 | throw new RuntimeException(e); |
362 | } |
363 | } |
364 | return meanValue; |
365 | } |
366 | |
367 | public double getExpectedValue() { |
368 | BoxedPDF boxedPDF = getModelBoxedPdf(); |
369 | EList<ContinuousSample> sampleList = boxedPDF.getSamples(); |
370 | double result = 0.0; |
371 | for (ContinuousSample sample : sampleList){ |
372 | Double value = sample.getValue(); |
373 | result += value.doubleValue() * sample.getProbability(); |
374 | } |
375 | return result; |
376 | } |
377 | |
378 | public ISamplePDF getCumulativeDistributionFunction() { |
379 | if (this.cumulativeDistributionFunction == null) { |
380 | try { |
381 | this.cumulativeDistributionFunction = (ISamplePDF) this |
382 | .getSamplePdfTimeDomain().getCumulativeFunction(); |
383 | } catch (FunctionNotInTimeDomainException e) { |
384 | e.printStackTrace(); |
385 | throw new RuntimeException(e); |
386 | } |
387 | } |
388 | return this.cumulativeDistributionFunction; |
389 | } |
390 | |
391 | public double probEquals(ManagedPDF pdf) { |
392 | try { |
393 | return getSamplePdfTimeDomain().probabilisticEquals( |
394 | pdf.getSamplePdfTimeDomain()); |
395 | } catch (ProbabilityFunctionException e) { |
396 | e.printStackTrace(); |
397 | throw new RuntimeException(e); |
398 | } |
399 | } |
400 | |
401 | public double probGreaterThan(ManagedPDF pdf) { |
402 | ISamplePDF cdfA = this.getCumulativeDistributionFunction(); |
403 | ISamplePDF pdfA = this.getSamplePdfTimeDomain(); |
404 | int size = pdfA.getValues().size(); |
405 | double distance = pdfA.getDistance(); |
406 | pdf.adjustPDF(distance, size); |
407 | ISamplePDF pdfB = pdf.getSamplePdfTimeDomain(); |
408 | |
409 | double prob = 0; |
410 | for (int i = 0; i < size; i++) { |
411 | prob += pdfB.getValueAsDouble(i) |
412 | * (1 - cdfA.getValueAsDouble(i)); |
413 | } |
414 | return prob; |
415 | } |
416 | |
417 | public double probGreaterOrEqualThan(ManagedPDF pdf) { |
418 | ISamplePDF pdfA = this.getSamplePdfTimeDomain(); |
419 | ISamplePDF cdfA = this.getCumulativeDistributionFunction(); |
420 | int size = pdfA.getValues().size(); |
421 | double distance = pdfA.getDistance(); |
422 | pdf.adjustPDF( distance, size); |
423 | ISamplePDF pdfB = pdf.getSamplePdfTimeDomain(); |
424 | |
425 | double prob = 0; |
426 | for (int i = 0; i < size; i++) { |
427 | prob += pdfB.getValueAsDouble(i) |
428 | * (1 - cdfA.getValueAsDouble(i) + pdfA.getValueAsDouble(i)); |
429 | } |
430 | return prob; |
431 | } |
432 | |
433 | public double probLessThan(ManagedPDF pdf) { |
434 | return pdf.probGreaterThan(this); |
435 | } |
436 | |
437 | public void adjustPDF(double distance, int size) { |
438 | try { |
439 | ISamplePDF sPDF = this.getSamplePdfTimeDomain(); |
440 | |
441 | sPDF = sPDF.getFunctionWithNewDistance(distance); |
442 | if (size > sPDF.getValues().size()) { |
443 | sPDF.expand(size); |
444 | } |
445 | this.setPdf(sPDF); |
446 | } catch (ProbabilityFunctionException e) { |
447 | e.printStackTrace(); |
448 | throw new RuntimeException(e); |
449 | } |
450 | } |
451 | |
452 | @Override |
453 | public Object clone() throws CloneNotSupportedException { |
454 | return new ManagedPDF(this.getPdfTimeDomain()); |
455 | } |
456 | |
457 | public boolean usesConfiguration(){ |
458 | return this.useConfiguration; |
459 | } |
460 | |
461 | public static ManagedPDF createFromString(String spec) throws RecognitionException, StringNotPDFException { |
462 | ProbabilityFunctionLiteral value = parse(spec); |
463 | try { |
464 | ProbabilityDensityFunction pdf = (ProbabilityDensityFunction) value |
465 | .getFunction_ProbabilityFunctionLiteral(); |
466 | return new ManagedPDF(pdf); |
467 | } catch (ClassCastException e) { |
468 | throw new StringNotPDFException(); |
469 | } |
470 | } |
471 | private static ProbabilityFunctionLiteral parse(String s) throws RecognitionException { |
472 | StochasticExpressionsLexer lexer = new StochasticExpressionsLexer( |
473 | new ANTLRStringStream(s)); |
474 | StochasticExpressionsParser parser = new StochasticExpressionsParser( |
475 | new CommonTokenStream(lexer)); |
476 | return (ProbabilityFunctionLiteral)parser.expression(); |
477 | } |
478 | |
479 | } |