1 | package de.uka.ipd.sdq.simucomframework.variables.functions; |
2 | |
3 | import java.util.List; |
4 | |
5 | import org.apache.log4j.Logger; |
6 | |
7 | /**Calculates the maximal of a value and given absolute and relative deviations. |
8 | * This function has three parameters. The first parameter is the value, the second on the absolute deviation, and the third one the relative deviation. |
9 | * @author groenda |
10 | */ |
11 | public class MaxDeviationFunction implements IFunction { |
12 | /** Logger for this class. */ |
13 | private static final Logger logger = Logger.getLogger(MaxDeviationFunction.class); |
14 | |
15 | /** Name used in the stochastic expression for this function. */ |
16 | public static final String MAX_DEVIATION_FUNCTION_NAME = "MaxDeviation"; |
17 | |
18 | /* (non-Javadoc) |
19 | * @see de.uka.ipd.sdq.simucomframework.variables.functions.IFunction#checkParameters(java.util.List) |
20 | */ |
21 | public boolean checkParameters(List<Object> parameters) { |
22 | if (parameters.size() != 3) |
23 | return false; |
24 | if (!(parameterIsNumber(parameters.get(0)) || parameters.get(0) instanceof String)) { |
25 | return false; |
26 | } |
27 | if (!(parameters.get(1) instanceof Double)) { |
28 | return false; |
29 | } |
30 | if (!(parameters.get(2) instanceof Double)) { |
31 | return false; |
32 | } |
33 | return true; |
34 | } |
35 | |
36 | /**Checks if the given parameter is a number. |
37 | * Valid numbers are of the types {@link Integer}, {@link Long}, {@link Float}, and {@link Double}. |
38 | * @param obj Parameter. |
39 | * @return {@code true} if, and only if, the parameter is a number. |
40 | */ |
41 | private boolean parameterIsNumber(Object obj) { |
42 | boolean valid = false; |
43 | if (obj instanceof Integer |
44 | || obj instanceof Byte |
45 | || obj instanceof Character |
46 | || obj instanceof Long |
47 | || obj instanceof Float |
48 | || obj instanceof Double) { |
49 | valid = true; |
50 | } |
51 | return valid; |
52 | } |
53 | |
54 | /* (non-Javadoc) |
55 | * @see de.uka.ipd.sdq.simucomframework.variables.functions.IFunction#evaluate(java.util.List) |
56 | */ |
57 | public Object evaluate(List<Object> parameters) { |
58 | Object value = parameters.get(0); |
59 | Double abs = (Double) parameters.get(1); |
60 | Double rel = (Double) parameters.get(2); |
61 | if (value instanceof Integer) { |
62 | Integer val = (Integer) value; |
63 | if (abs > val*rel) { |
64 | return Double.valueOf(Math.ceil(val + abs)).intValue(); |
65 | } else { |
66 | return Double.valueOf(Math.ceil(val + val * rel)).intValue(); |
67 | } |
68 | } else if (value instanceof Long) { |
69 | Long val = (Long) value; |
70 | if (abs > val*rel) { |
71 | return Double.valueOf(Math.ceil(val + abs)).longValue(); |
72 | } else { |
73 | return Double.valueOf(Math.ceil(val + val * rel)).longValue(); |
74 | } |
75 | } else if (value instanceof Byte) { |
76 | Byte val = (Byte) value; |
77 | if (abs > val*rel) { |
78 | return Double.valueOf(Math.ceil(val + abs)).byteValue(); |
79 | } else { |
80 | return Double.valueOf(Math.ceil(val + val * rel)).byteValue(); |
81 | } |
82 | } else if (value instanceof Character) { |
83 | Character val = (Character) value; |
84 | if (abs > val*rel) { |
85 | return Double.valueOf(Math.ceil(val + abs)).byteValue(); |
86 | } else { |
87 | return Double.valueOf(Math.ceil(val + val * rel)).byteValue(); |
88 | } |
89 | } else if (value instanceof Float) { |
90 | Float val = (Float) value; |
91 | if (abs > val*rel) { |
92 | return Double.valueOf(Math.ceil(val + abs)).floatValue(); |
93 | } else { |
94 | return Double.valueOf(Math.ceil(val + val * rel)).floatValue(); |
95 | } |
96 | } else if (value instanceof Double) { |
97 | Double val = (Double) value; |
98 | if (abs > val*rel) { |
99 | return Double.valueOf(Math.ceil(val + abs)); |
100 | } else { |
101 | return Double.valueOf(Math.ceil(val + val * rel)); |
102 | } |
103 | } else if (value instanceof String) { |
104 | logger.debug("String/Enum-based parameter was provided to MaxDeviation function. The parameter will be returned directly."); |
105 | return value; |
106 | } else { |
107 | throw new IllegalArgumentException("Unsupported type of value argument experienced."); |
108 | } |
109 | } |
110 | |
111 | } |