EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.probfunction.math.impl]

COVERAGE SUMMARY FOR SOURCE FILE [ProbabilityMassFunctionImpl.java]

nameclass, %method, %block, %line, %
ProbabilityMassFunctionImpl.java100% (2/2)59%  (17/29)52%  (485/935)45%  (79,2/175)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ProbabilityMassFunctionImpl100% (1/1)56%  (14/25)47%  (400/845)44%  (76,4/172)
div (IProbabilityMassFunction): IProbabilityMassFunction 0%   (0/1)0%   (0/14)0%   (0/3)
drawSample (): Object 0%   (0/1)0%   (0/37)0%   (0/9)
getArithmeticMeanValue (): double 0%   (0/1)0%   (0/86)0%   (0/17)
getCumulativeFunction (): IProbabilityMassFunction 0%   (0/1)0%   (0/47)0%   (0/12)
getFourierTramsform (): IProbabilityMassFunction 0%   (0/1)0%   (0/2)0%   (0/1)
getInverseFourierTransform (): IProbabilityMassFunction 0%   (0/1)0%   (0/2)0%   (0/1)
getProbabilities (): List 0%   (0/1)0%   (0/24)0%   (0/4)
shiftDomain (double): IProbabilityMassFunction 0%   (0/1)0%   (0/5)0%   (0/1)
stretchDomain (double): IProbabilityMassFunction 0%   (0/1)0%   (0/5)0%   (0/1)
sub (IProbabilityMassFunction): IProbabilityMassFunction 0%   (0/1)0%   (0/14)0%   (0/3)
transformDomainValues (double, ProbabilityMassFunctionImpl$Operation): IProba... 0%   (0/1)0%   (0/168)0%   (0/33)
mult (IProbabilityMassFunction): IProbabilityMassFunction 100% (1/1)71%  (10/14)67%  (2/3)
performOperation (ProbabilityMassFunctionImpl$Operation, IProbabilityMassFunc... 100% (1/1)79%  (59/75)71%  (12/17)
haveSameDomain (IProbabilityMassFunction): boolean 100% (1/1)89%  (57/64)83%  (12,5/15)
$SWITCH_TABLE$de$uka$ipd$sdq$probfunction$math$impl$ProbabilityMassFunctionIm... 100% (1/1)89%  (49/55)89%  (0,9/1)
getPercentile (int): Object 100% (1/1)89%  (33/37)83%  (5/6)
checkConstrains (): void 100% (1/1)91%  (41/45)89%  (8/9)
ProbabilityMassFunctionImpl (List, IUnit, boolean, boolean, IRandomGenerator)... 100% (1/1)100% (15/15)100% (5/5)
add (IProbabilityMassFunction): IProbabilityMassFunction 100% (1/1)100% (14/14)100% (3/3)
equals (Object): boolean 100% (1/1)100% (38/38)100% (10/10)
getMedian (): Object 100% (1/1)100% (4/4)100% (1/1)
getProbabilitySum (): double 100% (1/1)100% (21/21)100% (4/4)
getSamples (): List 100% (1/1)100% (6/6)100% (1/1)
scale (double): IProbabilityMassFunction 100% (1/1)100% (35/35)100% (7/7)
setSamples (List): void 100% (1/1)100% (18/18)100% (5/5)
     
class ProbabilityMassFunctionImpl$Operation100% (1/1)75%  (3/4)94%  (85/90)92%  (2,8/3)
valueOf (String): ProbabilityMassFunctionImpl$Operation 0%   (0/1)0%   (0/5)0%   (0/1)
<static initializer> 100% (1/1)100% (64/64)100% (2/2)
ProbabilityMassFunctionImpl$Operation (String, int): void 100% (1/1)100% (5/5)100% (1/1)
values (): ProbabilityMassFunctionImpl$Operation [] 100% (1/1)100% (16/16)100% (1/1)

1/**
2 * 
3 */
4package de.uka.ipd.sdq.probfunction.math.impl;
5 
6import java.util.ArrayList;
7import java.util.Collections;
8import java.util.Iterator;
9import java.util.List;
10 
11import de.uka.ipd.sdq.probfunction.math.IProbabilityMassFunction;
12import de.uka.ipd.sdq.probfunction.math.IRandomGenerator;
13import de.uka.ipd.sdq.probfunction.math.ISample;
14import de.uka.ipd.sdq.probfunction.math.IUnit;
15import de.uka.ipd.sdq.probfunction.math.exception.DifferentDomainsException;
16import de.uka.ipd.sdq.probfunction.math.exception.DomainNotNumbersException;
17import de.uka.ipd.sdq.probfunction.math.exception.InvalidSampleValueException;
18import de.uka.ipd.sdq.probfunction.math.exception.ProbabilitySumNotOneException;
19import de.uka.ipd.sdq.probfunction.math.exception.UnitNameNotSetException;
20import de.uka.ipd.sdq.probfunction.math.exception.UnitNotSetException;
21import de.uka.ipd.sdq.probfunction.math.exception.UnorderedDomainException;
22import de.uka.ipd.sdq.probfunction.math.util.MathTools;
23 
24/**
25 * @author Ihssane
26 * 
27 */
28public class ProbabilityMassFunctionImpl extends ProbabilityFunctionImpl
29                implements
30                        IProbabilityMassFunction {
31 
32        private List<ISample> samples;
33 
34        private enum Operation {
35                ADD, SUB, MULT, DIV, SHIFT, STRETCH
36        }
37 
38        protected ProbabilityMassFunctionImpl(List<ISample> samples, IUnit unit,
39                        boolean hasOrderedDomain, boolean isInFrequencyDomain,
40                        IRandomGenerator generator) {
41                super(unit, hasOrderedDomain, isInFrequencyDomain);
42                Collections.sort(samples, MathTools.getSampleComparator());
43                this.samples = samples;
44 
45                randomGenerator = generator;
46        }
47 
48        private IProbabilityMassFunction performOperation(Operation op,
49                        IProbabilityMassFunction pmf1, IProbabilityMassFunction pmf2) {
50                List<ISample> resultList = new ArrayList<ISample>();
51 
52                Iterator<ISample> iterator = pmf2.getSamples().iterator();
53                for (ISample s1 : pmf1.getSamples()) {
54                        ISample s2 = iterator.next();
55                        double result;
56                        switch (op) {
57                                case ADD :
58                                        result = s1.getProbability() + s2.getProbability();
59                                        break;
60                                case SUB :
61                                        result = s1.getProbability() - s2.getProbability();
62                                        break;
63                                case MULT :
64                                        result = s1.getProbability() * s2.getProbability();
65                                        break;
66                                case DIV :
67                                        result = s1.getProbability() / s2.getProbability();
68                                        break;
69                                default :
70                                        result = 0.0;
71                                        break;
72                        }
73                        resultList.add(pfFactory.createSample(s1.getValue(), result));
74                }
75                return pfFactory.createProbabilityMassFunction(resultList, this
76                                .getUnit(), hasOrderedDomain());
77        }
78 
79        public IProbabilityMassFunction add(IProbabilityMassFunction pmf)
80                        throws DifferentDomainsException {
81                if (!this.haveSameDomain(pmf))
82                        throw new DifferentDomainsException();
83 
84                return performOperation(Operation.ADD, this, pmf);
85        }
86 
87        public IProbabilityMassFunction mult(IProbabilityMassFunction pmf)
88                        throws DifferentDomainsException {
89                if (!this.haveSameDomain(pmf))
90                        throw new DifferentDomainsException();
91 
92                return performOperation(Operation.MULT, this, pmf);
93        }
94 
95        public IProbabilityMassFunction scale(double scalar) {
96 
97                List<ISample> newList = new ArrayList<ISample>();
98                for (ISample sample : samples)
99                        newList.add(pfFactory.createSample(sample.getValue(), sample
100                                        .getProbability()
101                                        * scalar));
102 
103                return pfFactory.createProbabilityMassFunction(newList, this.getUnit(),
104                                this.hasOrderedDomain());
105        }
106 
107        public IProbabilityMassFunction div(IProbabilityMassFunction pmf)
108                        throws DifferentDomainsException {
109                if (!this.haveSameDomain(pmf))
110                        throw new DifferentDomainsException();
111 
112                return performOperation(Operation.DIV, this, pmf);
113        }
114 
115        public IProbabilityMassFunction sub(IProbabilityMassFunction pmf)
116                        throws DifferentDomainsException {
117                if (!this.haveSameDomain(pmf))
118                        throw new DifferentDomainsException();
119 
120                return performOperation(Operation.SUB, this, pmf);
121        }
122        
123        /**
124         * Adjust this PMF and the passed PMF so that both have the same domain (probabilities 
125         * for the same values).
126         * 
127         * Assumes that the samples are sorted.
128     * 
129     * FIXME: The implementation is yet incomplete and needs to be revised. 
130         * 
131         * @param otherPMF 
132         * @return the adjusted other PMF otherPMF
133         */
134/*        private IProbabilityMassFunction makeSameDomain (IProbabilityMassFunction otherPMF){
135                
136                List<ISample> valuesThis = this.samples;
137                List<ISample> valuesOther = otherPMF.getSamples();
138                
139                if (valuesThis.size() == 0 && valuesOther.size() == 0)
140                        return otherPMF;
141                
142                if (valuesThis.size() == 0 && valuesOther.size() ==0){
143                        throw new RuntimeException("Cannot adjust the domains of an empty PMF.");
144                }
145                
146                // test for integer and double?
147                // can also be Strings.. need to be the same type. 
148                // If different, we need to be able to cast one number into another.  
149                boolean isIntegerThis = true;
150                boolean isIntegerOther = true;
151                
152                //store values to add, the add after iterating, then sort.
153                List<ISample> valuesToAddToThis = new ArrayList<ISample>(valuesOther.size());
154                List<ISample> valuesToAddToOther = new ArrayList<ISample>(valuesThis.size());
155                
156                Comparator<ISample> comparator = new ValueBasedComparator();
157                
158                //the following assumes a sorted list, I am not sure whether that is already guaranteed
159                Collections.sort(valuesThis, comparator);
160                Collections.sort(valuesOther, comparator);
161                
162                valuesToAddToThis = getAllMissingSamples(valuesThis, valuesOther);
163                valuesToAddToOther = getAllMissingSamples(valuesOther, valuesThis);
164                
165                
166                valuesThis.addAll(valuesToAddToThis);
167                valuesOther.addAll(valuesToAddToOther);
168                Collections.sort(valuesThis, comparator);
169                Collections.sort(valuesOther, comparator);
170                
171                //TODO: align sample types if possible. 
172                                
173                otherPMF.setSamples(valuesOther);
174                return otherPMF;
175                
176        }*/
177 
178 
179        /**
180         * Add all values from valuesOther to valuesThis that have not been there before. 
181         * Afterwards, valuesThis should contain all values of valuesOther (and possibly more)
182         * @param valuesThis
183         * @param valuesOther
184         * @return
185         */
186        /*private List<ISample> getAllMissingSamples(List<ISample> valuesThis,
187                        List<ISample> valuesOther) {
188        
189                List<ISample> result = new ArrayList<ISample>();
190                
191                Comparator<ISample> comparator = new ValueBasedComparator();
192                int indexOther = 0;
193                ISample sampleOther = valuesOther.get(0);
194                
195                for (int indexThis = 0; indexThis < valuesThis.size(); indexThis++) {
196                
197                        ISample sampleThis = valuesThis.get(indexThis);
198                        
199                        int compareResult = comparator.compare(sampleThis, sampleOther);
200                        if (compareResult < 0){
201                                //sampleThis is smaller -> continue
202                        } else if (compareResult > 0){
203                                //sampleThis is larger -> add the other sample to results
204                                result.add(new SampleImpl(sampleOther.getValue(), 0));
205                                sampleOther = valuesOther.get(indexOther);
206                                indexOther++;
207                                //sampleThis needs to be compared again in the next iteration of the for loop. 
208                                indexThis--;
209                        } else {
210                                //Both have a sample for the same values, nothing to be done
211                                sampleOther = valuesOther.get(indexOther);
212                                indexOther++;                        
213                        }
214                        
215                        if (indexOther < valuesOther.size()){
216                                sampleOther = valuesOther.get(indexOther);
217                        } else {
218                                break;
219                        }
220                                        
221                }
222                
223                //maybe there are still values not addressed in list valuesOther
224                for (int i = indexOther; i < valuesOther.size(); i++) {
225                        result.add(new SampleImpl(valuesOther.get(i).getValue(),0));
226                }
227                
228                return result;
229        }*/
230 
231        public boolean haveSameDomain(IProbabilityMassFunction pmf) {
232                List<ISample> values1 = this.samples;
233                List<ISample> values2 = pmf.getSamples();
234 
235                if (values1.size() != values2.size())
236                        return false;
237                if (values1.size() == 0 && values2.size() == 0)
238                        return true;
239                if (!(values1.get(0).getValue().getClass().isInstance(values2.get(0)
240                                .getValue())))
241                // if (new ValueBasedComparator().compare(values1.get(0),values2.get(0))!=0)
242                        return false;
243 
244                boolean result = true;
245                Iterator<ISample> iterator = values2.iterator();
246                for (ISample o : values1) {
247                        //use comparator here to really compare the value, not just the object. 
248                        if (!o.getValue().equals((iterator.next().getValue())))
249                                result = false;
250                }
251 
252                return result;
253        }
254 
255        public IProbabilityMassFunction getFourierTramsform() {
256                // TODO Auto-generated method stub
257                return null;
258        }
259 
260        public IProbabilityMassFunction getInverseFourierTransform() {
261                // TODO Auto-generated method stub
262                return null;
263        }
264 
265        /**
266         * @return the samples
267         */
268        public List<ISample> getSamples() {
269                return new ArrayList<ISample>(samples);
270        }
271 
272        /**
273         * @param samples
274         *            the samples to set
275         * @throws ProbabilitySumNotOneException
276         */
277        public void setSamples(List<ISample> samples) {
278                // if (!MathTools.equalsDouble(MathTools.sumOfSamples(samples), 1.0))
279                // throw new ProbabilitySumNotOneException();
280                if (samples.size() > 1
281                                && samples.get(0).getValue() instanceof Comparable)
282                        Collections.sort(samples, MathTools.getSampleComparator());
283                this.samples = samples;
284        }
285 
286        public double getArithmeticMeanValue() throws DomainNotNumbersException {
287                double mean = 0;
288                for (ISample sample : this.samples) {
289                        Object value = sample.getValue();
290                        if (value instanceof Double) {
291                                Double d = (Double) value;
292                                mean += d * sample.getProbability();
293                        } else if (value instanceof Integer) {
294                                Integer i = (Integer) value;
295                                mean += i * sample.getProbability();
296                        } else if (value instanceof Long) {
297                                Long i = (Long) value;
298                                mean += i * sample.getProbability();
299                        } else if (value instanceof Float) {
300                                Float i = (Float) value;
301                                mean += i * sample.getProbability();
302                        } else {
303                                throw new DomainNotNumbersException();
304                        }
305                }
306                return mean;
307        }
308 
309        public Object getMedian() throws UnorderedDomainException {
310                return getPercentile(50);
311        }
312 
313        public Object getPercentile(int p) throws IndexOutOfBoundsException,
314                        UnorderedDomainException {
315                if (!hasOrderedDomain())
316                        throw new UnorderedDomainException();
317                if (p < 0 || p > 100)
318                        throw new IndexOutOfBoundsException();
319 
320                int rank = (int) Math.floor((p * (samples.size() + 1.0)) / 100.0);
321                return samples.get(rank).getValue();
322        }
323 
324        public Object drawSample() {
325                Object result = 0.0;
326                List<Double> intervals = MathTools
327                                .computeCumulativeProbabilities(getProbabilities());
328 
329                double random = randomGenerator.random();
330                for (int j = 0; j < intervals.size(); j++)
331                        if (random < intervals.get(j)) {
332                                result = samples.get(j).getValue();
333                                break;
334                        }
335                return result;
336        }
337 
338        private List<Double> getProbabilities() {
339                List<Double> prob = new ArrayList<Double>();
340                for (ISample s : samples)
341                        prob.add(s.getProbability());
342                return prob;
343        }
344 
345        /**
346         * @see java.lang.Object#equals(java.lang.Object)
347         */
348        @Override
349        public boolean equals(Object obj) {
350                if (((IProbabilityMassFunction) obj).getSamples().size() != this.samples
351                                .size())
352                        return false;
353 
354                boolean result = true;
355                Iterator<ISample> iterator = ((IProbabilityMassFunction) obj)
356                                .getSamples().iterator();
357                for (ISample o : this.getSamples()) {
358                        if (!o.equals(iterator.next()))
359                                result = false;
360                }
361 
362                return result;
363        }
364 
365        public double getProbabilitySum() {
366                double sum = 0;
367                for (ISample sample : samples) {
368                        sum += sample.getProbability();
369                }
370                return sum;
371        }
372 
373        public void checkConstrains() throws ProbabilitySumNotOneException,
374                        InvalidSampleValueException, UnitNotSetException,
375                        UnitNameNotSetException {
376                if (!MathTools.equalsDouble(getProbabilitySum(), 1.0))
377                        throw new ProbabilitySumNotOneException();
378 
379                //TODO: Fix this when units work again
380                //if (getUnit() == null)
381                //        throw new UnitNotSetException();
382                //if (getUnit().getUnitName() == null)
383                //        throw new UnitNameNotSetException();
384 
385                for (ISample sample : this.samples) {
386                        Object value = sample.getValue();
387                        if (value == null)
388                                throw new InvalidSampleValueException();
389                        if (sample.getProbability() < 0.0 || sample.getProbability() > 1.0)
390                                throw new InvalidSampleValueException();
391                }
392        }
393 
394        public IProbabilityMassFunction getCumulativeFunction() {
395                List<Double> newProb = MathTools
396                                .computeCumulativeProbabilities(getProbabilities());
397                List<ISample> newSamples = new ArrayList<ISample>();
398                int index = 0;
399                for (Double d : newProb) {
400                        newSamples.add(pfFactory.createSample(
401                                        samples.get(index).getValue(), d));
402                        index++;
403                }
404 
405                IProbabilityMassFunction pmf = null;
406                pmf = pfFactory.createProbabilityMassFunction(newSamples, this
407                                .getUnit(), this.hasOrderedDomain());
408 
409                return pmf;
410        }
411 
412        public IProbabilityMassFunction shiftDomain(double scalar)
413                        throws DomainNotNumbersException {
414                return transformDomainValues(scalar, Operation.SHIFT);
415        }
416 
417        public IProbabilityMassFunction stretchDomain(double scalar)
418                        throws DomainNotNumbersException {
419                return transformDomainValues(scalar, Operation.STRETCH);
420        }
421 
422        /**
423         * Shifts or stretches the domain of the PMF according to the scalar factor
424         * given as a parameter. Only works if the sample values are numbers.
425         * 
426         * Tries to preserve the value types. For example, if the factor scalar is
427         * an Integer and all sample values are Integer, then the resulting PMF will
428         * also contain Integer-samples.
429         * 
430         * Scalar must not be equal to 0 if Operation is stretch. 
431         * 
432         * @author Koziolek (kill me)
433         * @param scalar
434         *            the factor to shift or stretch the domain
435         * @return
436         */
437        private IProbabilityMassFunction transformDomainValues(double scalar,
438                        Operation op) throws DomainNotNumbersException {
439                List<ISample> resultList = new ArrayList<ISample>();
440 
441                // determine whether scalar is an int
442                // (i.e., zero behind the point; example: 2.0)
443                Double factorDouble = scalar;
444                Integer factorInteger = factorDouble.intValue();
445                boolean factorIsInteger = (factorDouble == factorInteger.doubleValue());
446 
447                for (ISample sample : samples) {
448                        Object value = sample.getValue();
449                        Number resultValue = null;
450                        // Ok, there are several cases, as we would like to
451                        // preserve the type of the value. Please beautify
452                        // this if possible. :)
453                        switch (op) {
454                                case SHIFT :
455                                        if (value instanceof Integer && factorIsInteger) {
456                                                resultValue = new Integer((Integer) value
457                                                                + factorInteger);
458                                        } else if (value instanceof Long && factorIsInteger) {
459                                                resultValue = new Long((Long) value + factorInteger);
460                                        } else if (value instanceof Number) {
461                                                Number valueNumber = (Number) value;
462                                                resultValue = new Double(valueNumber.doubleValue()
463                                                                + factorDouble);
464                                        } else
465                                                throw new DomainNotNumbersException();
466                                        break;
467                                case STRETCH :
468                                        if (value instanceof Integer && factorIsInteger) {
469                                                resultValue = new Integer((Integer) value
470                                                                * factorInteger);
471                                        } else if (value instanceof Long && factorIsInteger) {
472                                                resultValue = new Long((Long) value * factorInteger);
473                                        } else if (value instanceof Number) {
474                                                Number valueNumber = (Number) value;
475                                                resultValue = new Double(valueNumber.doubleValue()
476                                                                * factorDouble);
477                                        } else
478                                                throw new DomainNotNumbersException();
479                                        break;
480                                default :
481                                        resultValue = 0.0;
482                        }
483 
484                        resultList.add(pfFactory.createSample(resultValue, sample
485                                        .getProbability()));
486                }
487 
488                return pfFactory.createProbabilityMassFunction(resultList, this
489                                .getUnit(), hasOrderedDomain());
490        }
491}
492 
493//class ValueBasedComparator implements Comparator<ISample>{
494//        
495//        
496//        @Override
497//        public int compare(ISample arg0, ISample arg1) {
498//                Object value0 = arg0.getValue();
499//                Object value1 = arg1.getValue();
500//                                
501//                if (value0.getClass().isInstance(value1)){
502//                        return ((Comparable) value0).compareTo(value1);
503//                } else         if (value1.getClass().isInstance(value0)){
504//                        int result = ((Comparable) value1).compareTo(value0);
505//                        return result * -1;
506//                } else if (value1 instanceof Number && value0 instanceof Number){
507//                        Number number0 = (Number)value0;
508//                        Number number1 = (Number)value1;
509//                        
510//                        return new Double(number0.doubleValue()).compareTo(new Double(number1.doubleValue()));
511//                } else {
512//                        throw new DifferentDomainsException();
513//                }
514//        }
515//                
516//}
517 

[all classes][de.uka.ipd.sdq.probfunction.math.impl]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov