1 package org.djunits.unit;
2
3 import java.io.Serializable;
4 import java.util.EnumMap;
5
6
7
8
9
10
11
12
13
14
15 public class SICoefficients implements Serializable
16 {
17
18 private static final long serialVersionUID = 1L;
19
20
21 private final EnumMap<SI, Integer> coefficientsMap;
22
23
24
25
26
27 protected SICoefficients(final EnumMap<SI, Integer> coefficients)
28 {
29 this.coefficientsMap = coefficients;
30 }
31
32
33 @Override
34 public final String toString()
35 {
36 return enumMapToString(this.coefficientsMap);
37 }
38
39
40
41
42
43
44 protected static String enumMapToString(final EnumMap<SI, Integer> map)
45 {
46 StringBuffer result = new StringBuffer();
47 for (SI si : map.keySet())
48 {
49 if (map.get(si) > 0)
50 {
51 result.append(si.name());
52 if (map.get(si) != 1)
53 {
54 result.append(map.get(si));
55 }
56 }
57 }
58
59 if (result.length() == 0)
60 {
61 result.append("1");
62 }
63
64 boolean first = true;
65 for (SI si : map.keySet())
66 {
67 if (map.get(si) < 0)
68 {
69 if (first)
70 {
71 result.append("/");
72 first = false;
73 }
74 result.append(si.name());
75 if (map.get(si) != -1)
76 {
77 result.append(-map.get(si));
78 }
79 }
80 }
81 return result.toString();
82 }
83
84
85
86
87 public final EnumMap<SI, Integer> getCoefficientsMap()
88 {
89 return this.coefficientsMap;
90 }
91
92
93
94
95
96
97
98 public static String normalize(final String coefficientString) throws UnitException
99 {
100 return enumMapToString(parse(coefficientString));
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 public static EnumMap<SI, Integer> parse(final String coefficientString) throws UnitException
135 {
136
137 EnumMap<SI, Integer> coefficients = new EnumMap<SI, Integer>(SI.class);
138 String cs = coefficientString;
139 cs = cs.replace(".", "").replace(" ", "");
140 if (cs.equals("1"))
141 {
142 return coefficients;
143 }
144 if (cs.startsWith("1/"))
145 {
146 cs = cs.substring(1);
147 }
148 int factor = 1;
149 while (cs.length() > 0)
150 {
151 if (cs.startsWith("/"))
152 {
153 cs = cs.substring(1);
154 if (cs.length() < 1)
155 {
156 throw new UnitException("No SI name after slash in " + coefficientString);
157 }
158 factor = -1;
159 }
160 boolean parsedPowerString = false;
161 int factor2 = 1;
162 for (SI si : SI.values())
163 {
164 factor2 = 1;
165 String name = si.name();
166 if (!cs.startsWith(name))
167 {
168 continue;
169 }
170 int endPos = name.length();
171 if (cs.substring(endPos).startsWith("ol"))
172 {
173 continue;
174 }
175
176 if (cs.substring(endPos).startsWith("^"))
177 {
178 endPos++;
179 }
180 int value = 1;
181 int digitsSeen = 0;
182 if (cs.substring(endPos).startsWith("-"))
183 {
184 factor2 = -1;
185 endPos++;
186 }
187 while (cs.length() > endPos)
188 {
189 char digit = cs.charAt(endPos);
190 if (digit >= '0' && digit <= '9')
191 {
192 if (0 == digitsSeen)
193 {
194 value = 0;
195 }
196 value = value * 10 + digit - '0';
197 endPos++;
198 digitsSeen++;
199 }
200 else
201 {
202 break;
203 }
204 }
205 Integer oldValue = coefficients.get(si);
206 if (null == oldValue)
207 {
208 oldValue = 0;
209 }
210 coefficients.put(si, oldValue + value * factor * factor2);
211 parsedPowerString = true;
212 cs = cs.substring(endPos);
213 break;
214 }
215 if (!parsedPowerString)
216 {
217 throw new UnitException("Not an SI unit name in \"" + coefficientString + "\" at \"" + cs + "\"");
218 }
219 }
220 return coefficients;
221 }
222
223
224
225
226
227
228 public static SICoefficients multiply(final SICoefficients a, final SICoefficients b)
229 {
230 EnumMap<SI, Integer> coefficients = new EnumMap<SI, Integer>(SI.class);
231 for (SI si : a.getCoefficientsMap().keySet())
232 {
233 coefficients.put(si, a.getCoefficientsMap().get(si));
234 }
235
236 for (SI si : b.getCoefficientsMap().keySet())
237 {
238 if (coefficients.containsKey(si))
239 {
240 coefficients.put(si, coefficients.get(si) + b.getCoefficientsMap().get(si));
241 }
242 else
243 {
244 coefficients.put(si, b.getCoefficientsMap().get(si));
245 }
246 }
247
248 for (SI si : coefficients.keySet())
249 {
250 if (coefficients.get(si) == 0)
251 {
252 coefficients.remove(si);
253 }
254 }
255 return new SICoefficients(coefficients);
256 }
257
258
259
260
261
262
263 public static SICoefficients divide(final SICoefficients a, final SICoefficients b)
264 {
265 EnumMap<SI, Integer> coefficients = new EnumMap<SI, Integer>(SI.class);
266 for (SI si : a.getCoefficientsMap().keySet())
267 {
268 coefficients.put(si, a.getCoefficientsMap().get(si));
269 }
270
271 for (SI si : b.getCoefficientsMap().keySet())
272 {
273 if (coefficients.containsKey(si))
274 {
275 coefficients.put(si, coefficients.get(si) - b.getCoefficientsMap().get(si));
276 }
277 else
278 {
279 coefficients.put(si, -b.getCoefficientsMap().get(si));
280 }
281 }
282
283 for (SI si : coefficients.keySet())
284 {
285 if (coefficients.get(si) == 0)
286 {
287 coefficients.remove(si);
288 }
289 }
290 return new SICoefficients(coefficients);
291 }
292
293 }