1 | /** |
2 | * |
3 | */ |
4 | package de.uka.ipd.sdq.probfunction.math.impl; |
5 | |
6 | import java.util.ArrayList; |
7 | import java.util.Arrays; |
8 | import java.util.Iterator; |
9 | import java.util.List; |
10 | |
11 | import de.uka.ipd.sdq.probfunction.math.IProbabilityDensityFunction; |
12 | import de.uka.ipd.sdq.probfunction.math.IRandomGenerator; |
13 | import de.uka.ipd.sdq.probfunction.math.ISamplePDF; |
14 | import de.uka.ipd.sdq.probfunction.math.IUnit; |
15 | import de.uka.ipd.sdq.probfunction.math.exception.DomainNotNumbersException; |
16 | import de.uka.ipd.sdq.probfunction.math.exception.FunctionNotInTimeDomainException; |
17 | import de.uka.ipd.sdq.probfunction.math.exception.FunctionsInDifferenDomainsException; |
18 | import de.uka.ipd.sdq.probfunction.math.exception.IncompatibleUnitsException; |
19 | import de.uka.ipd.sdq.probfunction.math.exception.InvalidSampleValueException; |
20 | import de.uka.ipd.sdq.probfunction.math.exception.NegativeDistanceException; |
21 | import de.uka.ipd.sdq.probfunction.math.exception.ProbabilityFunctionException; |
22 | import de.uka.ipd.sdq.probfunction.math.exception.ProbabilitySumNotOneException; |
23 | import de.uka.ipd.sdq.probfunction.math.exception.SizeTooSmallException; |
24 | import de.uka.ipd.sdq.probfunction.math.exception.UnitNameNotSetException; |
25 | import de.uka.ipd.sdq.probfunction.math.exception.UnitNotSetException; |
26 | import de.uka.ipd.sdq.probfunction.math.exception.UnknownPDFTypeException; |
27 | import de.uka.ipd.sdq.probfunction.math.exception.UnorderedDomainException; |
28 | import de.uka.ipd.sdq.probfunction.math.util.MathTools; |
29 | import flanagan.complex.Complex; |
30 | import flanagan.math.FourierTransform; |
31 | |
32 | /** |
33 | * @author Ihssane |
34 | * |
35 | */ |
36 | public class SamplePDFImpl extends ProbabilityDensityFunctionImpl |
37 | implements |
38 | ISamplePDF { |
39 | |
40 | private enum Operation { |
41 | ADD, SUB, MULT, DIV |
42 | } |
43 | |
44 | private static final Complex DEFAULT_FILL_VALUE = new Complex(0, 0); |
45 | |
46 | private static final int FOURIER_TRANSFORM = 0; |
47 | |
48 | private static final int INVERSE_FOURIER_TRANSFORM = 1; |
49 | |
50 | private double distance; |
51 | |
52 | private List<Complex> values; |
53 | |
54 | private Complex fillValue; |
55 | |
56 | private FourierTransform fft = new FourierTransform(); |
57 | |
58 | protected SamplePDFImpl(double distance, IUnit unit, |
59 | IRandomGenerator generator) { |
60 | this(distance, unit, false, generator); |
61 | } |
62 | |
63 | protected SamplePDFImpl(double distance, IUnit unit, |
64 | boolean isInFrequencyDomain, IRandomGenerator generator) { |
65 | super(unit, isInFrequencyDomain); |
66 | this.distance = distance; |
67 | values = new ArrayList<Complex>(); |
68 | fillValue = DEFAULT_FILL_VALUE; |
69 | randomGenerator = generator; |
70 | } |
71 | |
72 | public IProbabilityDensityFunction add(IProbabilityDensityFunction pdf) |
73 | throws UnknownPDFTypeException, |
74 | FunctionsInDifferenDomainsException, IncompatibleUnitsException { |
75 | return performOperation(Operation.ADD, this, pdf); |
76 | } |
77 | |
78 | public IProbabilityDensityFunction mult(IProbabilityDensityFunction pdf) |
79 | throws UnknownPDFTypeException, |
80 | FunctionsInDifferenDomainsException, IncompatibleUnitsException { |
81 | return performOperation(Operation.MULT, this, pdf); |
82 | } |
83 | |
84 | public IProbabilityDensityFunction div(IProbabilityDensityFunction pdf) |
85 | throws FunctionsInDifferenDomainsException, |
86 | UnknownPDFTypeException, IncompatibleUnitsException { |
87 | return performOperation(Operation.DIV, this, pdf); |
88 | } |
89 | |
90 | public IProbabilityDensityFunction sub(IProbabilityDensityFunction pdf) |
91 | throws FunctionsInDifferenDomainsException, |
92 | UnknownPDFTypeException, IncompatibleUnitsException { |
93 | return performOperation(Operation.SUB, this, pdf); |
94 | } |
95 | |
96 | public IProbabilityDensityFunction scale(double scalar) { |
97 | ArrayList<Complex> resultList = new ArrayList<Complex>(); |
98 | |
99 | for (Complex z : values) { |
100 | resultList.add(z.times(scalar)); |
101 | } |
102 | |
103 | return pfFactory.createSamplePDFFromComplex(distance, resultList, this |
104 | .isInFrequencyDomain(), pfFactory.createDefaultUnit()); |
105 | } |
106 | |
107 | public IProbabilityDensityFunction getFourierTransform() { |
108 | return transformFunction(FOURIER_TRANSFORM); |
109 | } |
110 | |
111 | public IProbabilityDensityFunction getInverseFourierTransform() { |
112 | return transformFunction(INVERSE_FOURIER_TRANSFORM); |
113 | } |
114 | |
115 | public void expand(int newSize) throws SizeTooSmallException { |
116 | int diff = newSize - values.size(); |
117 | |
118 | if (diff < 0) |
119 | throw new SizeTooSmallException(); |
120 | |
121 | for (int i = 0; i < diff; i++) { |
122 | values.add(new Complex(fillValue)); |
123 | } |
124 | } |
125 | |
126 | public double getDistance() { |
127 | return distance; |
128 | } |
129 | |
130 | public List<Double> getValuesAsDouble() { |
131 | return MathTools.transformComplexToDouble(values); |
132 | } |
133 | |
134 | public void setValuesAsDouble(List<Double> values) { |
135 | this.values = new ArrayList<Complex>(MathTools |
136 | .transformDoubleToComplex(values)); |
137 | } |
138 | |
139 | /** |
140 | * @return the fillValue |
141 | */ |
142 | public double getFillValueAsDouble() { |
143 | return fillValue.getReal(); |
144 | } |
145 | |
146 | /** |
147 | * @param fillValue |
148 | * the fillValue to set |
149 | */ |
150 | public void setFillValue(double fillValue) { |
151 | this.fillValue = new Complex(fillValue); |
152 | } |
153 | |
154 | public Complex getFillValue() { |
155 | return fillValue; |
156 | } |
157 | |
158 | public ISamplePDF getFunctionWithNewDistance(double distance) |
159 | throws NegativeDistanceException, FunctionNotInTimeDomainException { |
160 | List<Double> newList = getValuesForDistance(distance); |
161 | return pfFactory.createSamplePDFFromDouble(distance, newList, this |
162 | .getUnit()); |
163 | } |
164 | |
165 | public List<Complex> getValues() { |
166 | return new ArrayList<Complex>(values); |
167 | } |
168 | |
169 | public void setFillValue(Complex fillValue) { |
170 | this.fillValue = fillValue; |
171 | |
172 | } |
173 | |
174 | public void setValues(List<Complex> values, boolean isInFrequencyDomain) { |
175 | this.values = new ArrayList<Complex>(values); |
176 | this.setInFrequencyDomain(isInFrequencyDomain); |
177 | } |
178 | |
179 | public double getLowerDomainBorder() { |
180 | return 0; |
181 | } |
182 | |
183 | public double drawSample() { |
184 | double result = 0.0; |
185 | List<Double> intervals = MathTools |
186 | .computeCumulativeProbabilities(getValuesAsDouble()); |
187 | |
188 | double probability = randomGenerator.random(); |
189 | double lowerBoundProbability; |
190 | double upperBoundProbability; |
191 | double probabilityDistance; |
192 | double middleValue; |
193 | double scalingFactor; |
194 | for (int currentInterval = 0; currentInterval < intervals.size(); currentInterval++) { |
195 | upperBoundProbability = intervals.get(currentInterval); |
196 | if (probability < upperBoundProbability) { |
197 | middleValue = distance * currentInterval; |
198 | double lowerBoundValue = middleValue - (distance / 2); |
199 | // special case first interval (no negative values allowed) |
200 | if (currentInterval == 0) |
201 | lowerBoundProbability = 0.0; |
202 | else |
203 | lowerBoundProbability = intervals.get(currentInterval - 1); |
204 | probabilityDistance = upperBoundProbability |
205 | - lowerBoundProbability; |
206 | // sepcial case no values in interval. |
207 | if (probabilityDistance > 0) |
208 | scalingFactor = (probability - lowerBoundProbability) |
209 | / (probabilityDistance); |
210 | else |
211 | scalingFactor = 0.0; |
212 | result = lowerBoundValue + distance * scalingFactor; |
213 | break; |
214 | } |
215 | } |
216 | return result; |
217 | } |
218 | |
219 | public double getArithmeticMeanValue() throws DomainNotNumbersException, |
220 | FunctionNotInTimeDomainException { |
221 | if (!isInTimeDomain()) |
222 | throw new FunctionNotInTimeDomainException(); |
223 | double pos = 0; |
224 | double mean = 0; |
225 | for (Complex val : values) { |
226 | mean += pos * val.getReal(); |
227 | pos += distance; |
228 | } |
229 | return mean; |
230 | } |
231 | |
232 | public Object getMedian() throws UnorderedDomainException { |
233 | return getPercentile(50); |
234 | } |
235 | |
236 | public Object getPercentile(int p) throws IndexOutOfBoundsException, |
237 | UnorderedDomainException { |
238 | if (!hasOrderedDomain()) |
239 | throw new UnorderedDomainException(); |
240 | if (p < 0 || p > 100) |
241 | throw new IndexOutOfBoundsException(); |
242 | double prob = ((double)p) / 100.0; |
243 | double currProb = 0; |
244 | int i; |
245 | for(i=0; i < values.size() && currProb < prob; i++){ |
246 | currProb += values.get(i).getReal(); |
247 | } |
248 | return i*distance; |
249 | } |
250 | |
251 | public int numberOfSamples() { |
252 | return values.size(); |
253 | } |
254 | |
255 | @Override |
256 | public boolean equals(Object obj) { |
257 | boolean result = false; |
258 | if (obj instanceof ISamplePDF) { |
259 | ISamplePDF pdf = (ISamplePDF) obj; |
260 | if ((pdf.getDistance() == this.getDistance())) { |
261 | List<Complex> v1 = values; |
262 | List<Complex> v2 = pdf.getValues(); |
263 | if (v1.size() > v2.size()) { |
264 | List<Complex> tmp = v2; |
265 | v2 = v1; |
266 | v1 = tmp; |
267 | } |
268 | Iterator<Complex> iter = v2.iterator(); |
269 | result = true; |
270 | for (Complex z : v1) { |
271 | if (!MathTools.equalsComplex(iter.next(), z)) { |
272 | result = false; |
273 | break; |
274 | } |
275 | } |
276 | while (iter.hasNext() && result) { |
277 | if (!(MathTools.equalsComplex(iter.next(), |
278 | new Complex(0, 0)))) { |
279 | result = false; |
280 | } |
281 | } |
282 | } |
283 | } |
284 | return result; |
285 | } |
286 | |
287 | @Override |
288 | public int hashCode() { |
289 | // TODO Auto-generated method stub |
290 | return super.hashCode(); |
291 | } |
292 | |
293 | @Override |
294 | public String toString() { |
295 | String result = "unit = " + getUnit().getUnitName() + "; "; |
296 | result += "distance = " + getDistance() + "; "; |
297 | result += "samples: "; |
298 | boolean isFirst = true; |
299 | for (Complex z : values) { |
300 | if (isFirst) { |
301 | isFirst = false; |
302 | } else { |
303 | result += ", "; |
304 | } |
305 | result += "(" + MathTools.asString(z.getReal()) + ", " |
306 | + MathTools.asString(z.getImag()) + ")"; |
307 | } |
308 | return result; |
309 | } |
310 | |
311 | private List<Double> getValuesForDistance(double newDistance) |
312 | throws NegativeDistanceException, FunctionNotInTimeDomainException { |
313 | // same distance |
314 | if (MathTools.equalsDouble(distance, newDistance)) |
315 | return getValuesAsDouble(); |
316 | |
317 | // check preconditions |
318 | if ((distance < 0) || (newDistance < 0)) |
319 | throw new NegativeDistanceException(); |
320 | |
321 | if (!isInTimeDomain()) |
322 | throw new FunctionNotInTimeDomainException(); |
323 | |
324 | // begin implementation |
325 | double oldPoint = distance / 2; |
326 | double newPoint = newDistance / 2; |
327 | int currentIndex = 0; |
328 | double buffer = 0.0; |
329 | |
330 | List<Double> newValues = new ArrayList<Double>(); |
331 | |
332 | if (MathTools.equalsDouble(newDistance, distance)) { |
333 | newValues = getValuesAsDouble(); |
334 | } else if (newDistance < distance) { |
335 | while (currentIndex < values.size()) { |
336 | if (newPoint < oldPoint) { |
337 | if (newPoint == newDistance / 2) |
338 | newValues |
339 | .add(getProb(currentIndex, newPoint, oldPoint)); |
340 | else |
341 | newValues.add(getProb(currentIndex, newDistance, |
342 | distance)); |
343 | |
344 | } else { |
345 | if (oldPoint == distance / 2) { |
346 | newValues.add(getLeftProb(oldPoint, currentIndex, |
347 | newPoint, newDistance, oldPoint) |
348 | + getRightProb(oldPoint, currentIndex + 1, |
349 | newPoint)); |
350 | } else |
351 | newValues.add(getLeftProb(oldPoint, currentIndex, |
352 | newPoint, newDistance, distance) |
353 | + getRightProb(oldPoint, currentIndex + 1, |
354 | newPoint)); |
355 | oldPoint += distance; |
356 | currentIndex++; |
357 | } |
358 | newPoint += newDistance; |
359 | } |
360 | } else if (newDistance > distance) { |
361 | while (currentIndex < values.size()) { |
362 | if (oldPoint < newPoint) { |
363 | buffer += values.get(currentIndex).getReal(); |
364 | |
365 | } else { |
366 | newValues.add(buffer |
367 | + getLeftProb(newPoint, currentIndex, oldPoint, |
368 | distance, distance)); |
369 | buffer = getRightProb(newPoint, currentIndex, oldPoint); |
370 | newPoint += newDistance; |
371 | } |
372 | oldPoint += distance; |
373 | currentIndex++; |
374 | } |
375 | if (buffer != 0) |
376 | newValues.add(buffer); |
377 | } |
378 | return newValues; |
379 | } |
380 | |
381 | private double getProb(int index, double newDistance, double distance) { |
382 | return (newDistance / distance) * values.get(index).getReal(); |
383 | } |
384 | |
385 | private double getLeftProb(double oldP, int index, double newP, double diff, double distance) { |
386 | double fractal = (diff - (newP - oldP)) / distance; |
387 | return values.get(index).getReal() * fractal; |
388 | } |
389 | |
390 | private double getRightProb(double oldP, int index, double newP) { |
391 | double fractal = (newP - oldP) / distance; |
392 | if (index < values.size()) |
393 | return values.get(index).getReal() * fractal; |
394 | else |
395 | return 0; |
396 | } |
397 | |
398 | private static IProbabilityDensityFunction performOperation(Operation op, |
399 | IProbabilityDensityFunction pdf1, IProbabilityDensityFunction pdf2) |
400 | throws FunctionsInDifferenDomainsException, |
401 | UnknownPDFTypeException, IncompatibleUnitsException { |
402 | |
403 | List<ISamplePDF> operands = prepareForComputation(pdf1, pdf2); |
404 | |
405 | ISamplePDF sPDF1 = operands.get(0); |
406 | ISamplePDF sPDF2 = operands.get(1); |
407 | ArrayList<Complex> resultList = new ArrayList<Complex>(); |
408 | double distance = sPDF1.getDistance(); |
409 | boolean inFrequencyDomain = sPDF1.isInFrequencyDomain(); |
410 | |
411 | Iterator<Complex> iterator = sPDF2.getValues().iterator(); |
412 | for (Complex z1 : sPDF1.getValues()) { |
413 | Complex z2 = iterator.next(); |
414 | Complex result; |
415 | switch (op) { |
416 | case ADD : |
417 | result = z1.plus(z2); |
418 | break; |
419 | case SUB : |
420 | result = z1.minus(z2); |
421 | break; |
422 | case MULT : |
423 | result = z1.times(z2); |
424 | break; |
425 | case DIV : |
426 | result = z1.over(z2); |
427 | break; |
428 | default : |
429 | result = null; |
430 | break; |
431 | } |
432 | resultList.add(result); |
433 | } |
434 | IProbabilityDensityFunction p = pfFactory.createSamplePDFFromComplex( |
435 | distance, resultList, inFrequencyDomain, sPDF1.getUnit()); |
436 | return p; |
437 | } |
438 | |
439 | private static List<ISamplePDF> prepareForComputation( |
440 | IProbabilityDensityFunction pdf1, IProbabilityDensityFunction pdf2) |
441 | throws FunctionsInDifferenDomainsException, |
442 | UnknownPDFTypeException, IncompatibleUnitsException { |
443 | // check preconditions |
444 | if (pdf1.isInTimeDomain() != pdf2.isInTimeDomain()) |
445 | throw new FunctionsInDifferenDomainsException(); |
446 | |
447 | if (pdf1.getUnit() != null && !pdf1.getUnit().equals(pdf2.getUnit())) |
448 | throw new IncompatibleUnitsException(); |
449 | |
450 | // ensure that we only have SamplePDFs with equal distances and the same |
451 | // number of samples |
452 | ISamplePDF sPDF1 = pfFactory.transformToSamplePDF(pdf1); |
453 | ISamplePDF sPDF2 = pfFactory.transformToSamplePDF(pdf2); |
454 | |
455 | List<ISamplePDF> operands; |
456 | operands = createFunctionsWithEqualDistance(sPDF1, sPDF2); |
457 | sPDF1 = operands.get(0); |
458 | sPDF2 = operands.get(1); |
459 | |
460 | try { |
461 | int maxSize = Math.max(sPDF1.numberOfSamples(), sPDF2 |
462 | .numberOfSamples()); |
463 | sPDF1.expand(maxSize); |
464 | sPDF2.expand(maxSize); |
465 | } catch (SizeTooSmallException e) { |
466 | // should never happen... |
467 | e.printStackTrace(); |
468 | throw new RuntimeException(e); |
469 | } |
470 | return operands; |
471 | } |
472 | |
473 | private IProbabilityDensityFunction transformFunction(int flag) { |
474 | Complex[] cValues = new Complex[values.size()]; |
475 | values.toArray(cValues); |
476 | fft.setData(cValues); |
477 | |
478 | if (flag == FOURIER_TRANSFORM) |
479 | fft.transform(); |
480 | else |
481 | fft.inverse(); |
482 | |
483 | List<Complex> resultList = Arrays.asList(fft |
484 | .getTransformedDataAsComplex()); |
485 | |
486 | ISamplePDF spdf = pfFactory.createSamplePDFFromComplex(distance, |
487 | resultList, !this.isInFrequencyDomain(), pfFactory |
488 | .createDefaultUnit()); |
489 | return spdf; |
490 | } |
491 | |
492 | /** |
493 | * Creates two functions with an equal distance, if both functions are in |
494 | * the time domain. Precondition: Functions are in the same domain. |
495 | * |
496 | * @param pdf1 |
497 | * @param pdf2 |
498 | * @return |
499 | * @throws FunctionNotInTimeDomainException |
500 | * @throws NegativeDistanceException |
501 | * @throws FunctionNotInTimeDomainException |
502 | * Thrown if one of the input pdfs is not in the time domain. |
503 | */ |
504 | protected static List<ISamplePDF> createFunctionsWithEqualDistance( |
505 | ISamplePDF pdf1, ISamplePDF pdf2) { |
506 | |
507 | ArrayList<ISamplePDF> resultList = new ArrayList<ISamplePDF>(); |
508 | |
509 | try { |
510 | if (!MathTools.equalsDouble(pdf1.getDistance(), pdf2.getDistance())) { |
511 | boolean inTimeDomain = pdf1.isInTimeDomain(); |
512 | |
513 | if (!inTimeDomain) { |
514 | pdf1 = (ISamplePDF) pdf1.getInverseFourierTransform(); |
515 | pdf2 = (ISamplePDF) pdf2.getInverseFourierTransform(); |
516 | } |
517 | |
518 | double distance = MathTools.gcd(pdf1.getDistance(), pdf2 |
519 | .getDistance()); |
520 | |
521 | pdf1 = pdf1.getFunctionWithNewDistance(distance); |
522 | pdf2 = pdf2.getFunctionWithNewDistance(distance); |
523 | |
524 | if (!inTimeDomain) { |
525 | pdf1 = (ISamplePDF) pdf1.getFourierTransform(); |
526 | pdf2 = (ISamplePDF) pdf2.getFourierTransform(); |
527 | } |
528 | |
529 | } |
530 | |
531 | resultList.add(pdf1); |
532 | resultList.add(pdf2); |
533 | } catch (ProbabilityFunctionException e) { |
534 | // should never happen |
535 | e.printStackTrace(); |
536 | throw new RuntimeException(e); |
537 | } |
538 | return resultList; |
539 | } |
540 | |
541 | public double getProbabilitySum() throws FunctionNotInTimeDomainException { |
542 | if (!isInTimeDomain()) |
543 | throw new FunctionNotInTimeDomainException(); |
544 | double sum = 0; |
545 | for (Complex value : values) { |
546 | sum += value.getReal(); |
547 | } |
548 | return sum; |
549 | } |
550 | |
551 | public void checkConstrains() throws NegativeDistanceException, |
552 | ProbabilitySumNotOneException, FunctionNotInTimeDomainException, |
553 | UnitNotSetException, UnitNameNotSetException, |
554 | InvalidSampleValueException { |
555 | if (distance <= 0.0) |
556 | throw new NegativeDistanceException(); |
557 | if (getUnit() == null) |
558 | throw new UnitNotSetException(); |
559 | if (getUnit().getUnitName() == null) |
560 | throw new UnitNameNotSetException(); |
561 | try { |
562 | if (!MathTools.equalsDouble(getProbabilitySum(), 1.0)) |
563 | throw new ProbabilitySumNotOneException(); |
564 | for (double p : getValuesAsDouble()) |
565 | if (!(p >= 0.0 - MathTools.EPSILON_ERROR && p <= 1.0 + MathTools.EPSILON_ERROR)) |
566 | throw new InvalidSampleValueException(); |
567 | } catch (FunctionNotInTimeDomainException e) { |
568 | throw e; |
569 | } |
570 | |
571 | } |
572 | |
573 | public IProbabilityDensityFunction getCumulativeFunction() |
574 | throws FunctionNotInTimeDomainException { |
575 | |
576 | if (!isInTimeDomain()) |
577 | throw new FunctionNotInTimeDomainException(); |
578 | |
579 | List<Double> cumulativeProbabilities = MathTools |
580 | .computeCumulativeProbabilities(getValuesAsDouble()); |
581 | ISamplePDF spdf = pfFactory.createSamplePDFFromDouble(distance, |
582 | cumulativeProbabilities, isInFrequencyDomain(), this.getUnit(), |
583 | this.getRandomGenerator()); |
584 | spdf.setFillValue(new Complex(1.0, 0.0)); |
585 | return spdf; |
586 | } |
587 | |
588 | public double probabilisticEquals(IProbabilityDensityFunction pdf) |
589 | throws ProbabilityFunctionException { |
590 | return compareTo(pdf, CompareOperation.EQUALS); |
591 | } |
592 | |
593 | public double greaterThan(IProbabilityDensityFunction pdf) |
594 | throws ProbabilityFunctionException { |
595 | return compareTo(pdf, CompareOperation.GREATER); |
596 | } |
597 | |
598 | public double lessThan(IProbabilityDensityFunction pdf) |
599 | throws ProbabilityFunctionException { |
600 | return compareTo(pdf, CompareOperation.LESS); |
601 | } |
602 | |
603 | private double compareTo(IProbabilityDensityFunction pdf, |
604 | CompareOperation op) throws ProbabilityFunctionException { |
605 | ISamplePDF sPDF = pfFactory.transformToSamplePDF(pdf); |
606 | sPDF = sPDF.getFunctionWithNewDistance(this.distance); |
607 | int maxSize = Math |
608 | .max(sPDF.getValues().size(), this.getValues().size()); |
609 | sPDF.expand(maxSize); |
610 | this.expand(maxSize); |
611 | List<Double> pdfValues = sPDF.getValuesAsDouble(); |
612 | List<Double> thisValues = this.getValuesAsDouble(); |
613 | |
614 | switch (op) { |
615 | case EQUALS : |
616 | return equals(thisValues, pdfValues); |
617 | case GREATER : |
618 | return greaterThan(thisValues, pdfValues); |
619 | case LESS : |
620 | return greaterThan(pdfValues, thisValues); |
621 | default : |
622 | return 0; |
623 | } |
624 | } |
625 | |
626 | private double greaterThan(List<Double> firstValues, |
627 | List<Double> secondValues) { |
628 | assert (firstValues.size() == secondValues.size()); |
629 | double prob = 0; |
630 | for (int i = 0; i < secondValues.size(); i++) { |
631 | double tempProb = greaterThan(secondValues, i); |
632 | prob += tempProb * secondValues.get(i); |
633 | } |
634 | return prob; |
635 | } |
636 | |
637 | private double greaterThan(List<Double> secondValues, int i) { |
638 | double prob = 0; |
639 | for (int j = i + 1; j < secondValues.size(); j++) { |
640 | prob += secondValues.get(j); |
641 | } |
642 | return prob; |
643 | } |
644 | |
645 | private double equals(List<Double> firstValues, List<Double> secondValues) { |
646 | double prob = 0; |
647 | for (int i = 0; i < firstValues.size(); i++) { |
648 | prob += firstValues.get(i) * secondValues.get(i); |
649 | } |
650 | return prob; |
651 | } |
652 | |
653 | public IProbabilityDensityFunction stretchDomain(double scalar) { |
654 | SamplePDFImpl sPDF = new SamplePDFImpl(this.getDistance() * scalar, |
655 | this.getUnit(), this.randomGenerator); |
656 | sPDF.setValues(this.getValues(), this.isInFrequencyDomain()); |
657 | sPDF.setFillValue(this.getFillValue()); |
658 | return sPDF; |
659 | } |
660 | |
661 | public IProbabilityDensityFunction shiftDomain(double scalar) |
662 | throws DomainNotNumbersException { |
663 | throw new UnsupportedOperationException(); |
664 | // SamplePDFImpl sPDF = new SamplePDFImpl(this.getDistance(), |
665 | // this.getUnit(), this.randomGenerator); |
666 | // List<Complex> sampleList = this.getValues(); |
667 | // sampleList.add(0, new Complex(0,0)); |
668 | } |
669 | |
670 | public Complex getValue(int pos) { |
671 | return pos < values.size() ? values.get(pos) : fillValue; |
672 | } |
673 | |
674 | public Double getValueAsDouble(int pos) { |
675 | return getValue(pos).getReal(); |
676 | } |
677 | } |