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 minimum 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 MinDeviationFunction implements IFunction { |
12 | /** Logger for this class. */ |
13 | private static final Logger logger = Logger.getLogger(MinDeviationFunction.class); |
14 | |
15 | /** Name used in the stochastic expression for this function. */ |
16 | public static final String MIN_DEVIATION_FUNCTION_NAME = "MinDeviation"; |
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 | if (value instanceof String) { |
60 | logger.debug("String/Enum-based parameter was provided to MinDeviation Function. The parameter will be directly returned."); |
61 | return value; |
62 | } |
63 | Double abs = (Double) parameters.get(1); |
64 | Double rel = (Double) parameters.get(2); |
65 | if (value instanceof Integer) { |
66 | Integer val = (Integer) value; |
67 | if (abs > val*rel) { |
68 | return Double.valueOf(Math.floor(val - abs)).intValue(); |
69 | } else { |
70 | return Double.valueOf(Math.floor(val - val * rel)).intValue(); |
71 | } |
72 | } else if (value instanceof Long) { |
73 | Long val = (Long) value; |
74 | if (abs > val*rel) { |
75 | return Double.valueOf(Math.floor(val - abs)).longValue(); |
76 | } else { |
77 | return Double.valueOf(Math.floor(val - val * rel)).longValue(); |
78 | } |
79 | } else if (value instanceof Byte) { |
80 | Byte val = (Byte) value; |
81 | if (abs > val*rel) { |
82 | return Double.valueOf(Math.floor(val - abs)).byteValue(); |
83 | } else { |
84 | return Double.valueOf(Math.floor(val - val * rel)).byteValue(); |
85 | } |
86 | } else if (value instanceof Character) { |
87 | Character val = (Character) value; |
88 | if (abs > val*rel) { |
89 | return Double.valueOf(Math.floor(val - abs)).byteValue(); |
90 | } else { |
91 | return Double.valueOf(Math.floor(val - val * rel)).byteValue(); |
92 | } |
93 | } else if (value instanceof Float) { |
94 | Float val = (Float) value; |
95 | if (abs > val*rel) { |
96 | return Double.valueOf(Math.floor(val - abs)).floatValue(); |
97 | } else { |
98 | return Double.valueOf(Math.floor(val - val * rel)).floatValue(); |
99 | } |
100 | } else if (value instanceof Double) { |
101 | Double val = (Double) value; |
102 | if (abs > val*rel) { |
103 | return Double.valueOf(Math.floor(val - abs)); |
104 | } else { |
105 | return Double.valueOf(Math.floor(val - val * rel)); |
106 | } |
107 | } else { |
108 | throw new IllegalArgumentException("Unsupported type of value argument experienced."); |
109 | } |
110 | } |
111 | |
112 | } |