1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.complex;
19
20 import java.text.FieldPosition;
21 import java.text.NumberFormat;
22 import java.text.ParseException;
23 import java.text.ParsePosition;
24 import java.util.Locale;
25
26 import org.apache.commons.math.MathRuntimeException;
27 import org.apache.commons.math.util.CompositeFormat;
28
29
30
31
32
33
34
35
36
37 public class ComplexFormat extends CompositeFormat {
38
39
40 private static final long serialVersionUID = -3343698360149467646L;
41
42
43 private static final String DEFAULT_IMAGINARY_CHARACTER = "i";
44
45
46 private String imaginaryCharacter;
47
48
49 private NumberFormat imaginaryFormat;
50
51
52 private NumberFormat realFormat;
53
54
55
56
57
58 public ComplexFormat() {
59 this(DEFAULT_IMAGINARY_CHARACTER, getDefaultNumberFormat());
60 }
61
62
63
64
65
66
67 public ComplexFormat(NumberFormat format) {
68 this(DEFAULT_IMAGINARY_CHARACTER, format);
69 }
70
71
72
73
74
75
76
77 public ComplexFormat(NumberFormat realFormat, NumberFormat imaginaryFormat) {
78 this(DEFAULT_IMAGINARY_CHARACTER, realFormat, imaginaryFormat);
79 }
80
81
82
83
84
85
86 public ComplexFormat(String imaginaryCharacter) {
87 this(imaginaryCharacter, getDefaultNumberFormat());
88 }
89
90
91
92
93
94
95
96 public ComplexFormat(String imaginaryCharacter, NumberFormat format) {
97 this(imaginaryCharacter, format, (NumberFormat)format.clone());
98 }
99
100
101
102
103
104
105
106
107
108 public ComplexFormat(String imaginaryCharacter, NumberFormat realFormat,
109 NumberFormat imaginaryFormat) {
110 super();
111 setImaginaryCharacter(imaginaryCharacter);
112 setImaginaryFormat(imaginaryFormat);
113 setRealFormat(realFormat);
114 }
115
116
117
118
119
120
121 public static Locale[] getAvailableLocales() {
122 return NumberFormat.getAvailableLocales();
123 }
124
125
126
127
128
129
130
131
132 public static String formatComplex(Complex c) {
133 return getInstance().format(c);
134 }
135
136
137
138
139
140
141
142
143
144
145 public StringBuffer format(Complex complex, StringBuffer toAppendTo,
146 FieldPosition pos) {
147
148 pos.setBeginIndex(0);
149 pos.setEndIndex(0);
150
151
152 double re = complex.getReal();
153 formatDouble(re, getRealFormat(), toAppendTo, pos);
154
155
156 double im = complex.getImaginary();
157 if (im < 0.0) {
158 toAppendTo.append(" - ");
159 formatDouble(-im, getImaginaryFormat(), toAppendTo, pos);
160 toAppendTo.append(getImaginaryCharacter());
161 } else if (im > 0.0 || Double.isNaN(im)) {
162 toAppendTo.append(" + ");
163 formatDouble(im, getImaginaryFormat(), toAppendTo, pos);
164 toAppendTo.append(getImaginaryCharacter());
165 }
166
167 return toAppendTo;
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 @Override
184 public StringBuffer format(Object obj, StringBuffer toAppendTo,
185 FieldPosition pos) {
186
187 StringBuffer ret = null;
188
189 if (obj instanceof Complex) {
190 ret = format( (Complex)obj, toAppendTo, pos);
191 } else if (obj instanceof Number) {
192 ret = format( new Complex(((Number)obj).doubleValue(), 0.0),
193 toAppendTo, pos);
194 } else {
195 throw MathRuntimeException.createIllegalArgumentException(
196 "cannot format a {0} instance as a complex number",
197 obj.getClass().getName());
198 }
199
200 return ret;
201 }
202
203
204
205
206
207 public String getImaginaryCharacter() {
208 return imaginaryCharacter;
209 }
210
211
212
213
214
215 public NumberFormat getImaginaryFormat() {
216 return imaginaryFormat;
217 }
218
219
220
221
222
223 public static ComplexFormat getInstance() {
224 return getInstance(Locale.getDefault());
225 }
226
227
228
229
230
231
232 public static ComplexFormat getInstance(Locale locale) {
233 NumberFormat f = getDefaultNumberFormat(locale);
234 return new ComplexFormat(f);
235 }
236
237
238
239
240
241 public NumberFormat getRealFormat() {
242 return realFormat;
243 }
244
245
246
247
248
249
250
251
252
253 public Complex parse(String source) throws ParseException {
254 ParsePosition parsePosition = new ParsePosition(0);
255 Complex result = parse(source, parsePosition);
256 if (parsePosition.getIndex() == 0) {
257 throw MathRuntimeException.createParseException(
258 parsePosition.getErrorIndex(),
259 "unparseable complex number: \"{0}\"", source);
260 }
261 return result;
262 }
263
264
265
266
267
268
269
270
271 public Complex parse(String source, ParsePosition pos) {
272 int initialIndex = pos.getIndex();
273
274
275 parseAndIgnoreWhitespace(source, pos);
276
277
278 Number re = parseNumber(source, getRealFormat(), pos);
279 if (re == null) {
280
281
282 pos.setIndex(initialIndex);
283 return null;
284 }
285
286
287 int startIndex = pos.getIndex();
288 char c = parseNextCharacter(source, pos);
289 int sign = 0;
290 switch (c) {
291 case 0 :
292
293
294 return new Complex(re.doubleValue(), 0.0);
295 case '-' :
296 sign = -1;
297 break;
298 case '+' :
299 sign = 1;
300 break;
301 default :
302
303
304
305 pos.setIndex(initialIndex);
306 pos.setErrorIndex(startIndex);
307 return null;
308 }
309
310
311 parseAndIgnoreWhitespace(source, pos);
312
313
314 Number im = parseNumber(source, getRealFormat(), pos);
315 if (im == null) {
316
317
318 pos.setIndex(initialIndex);
319 return null;
320 }
321
322
323 if (!parseFixedstring(source, getImaginaryCharacter(), pos)) {
324 return null;
325 }
326
327 return new Complex(re.doubleValue(), im.doubleValue() * sign);
328
329 }
330
331
332
333
334
335
336
337
338
339 @Override
340 public Object parseObject(String source, ParsePosition pos) {
341 return parse(source, pos);
342 }
343
344
345
346
347
348
349
350 public void setImaginaryCharacter(String imaginaryCharacter) {
351 if (imaginaryCharacter == null || imaginaryCharacter.length() == 0) {
352 throw MathRuntimeException.createIllegalArgumentException(
353 "empty string for imaginary character");
354 }
355 this.imaginaryCharacter = imaginaryCharacter;
356 }
357
358
359
360
361
362
363
364 public void setImaginaryFormat(NumberFormat imaginaryFormat) {
365 if (imaginaryFormat == null) {
366 throw MathRuntimeException.createIllegalArgumentException(
367 "null imaginary format");
368 }
369 this.imaginaryFormat = imaginaryFormat;
370 }
371
372
373
374
375
376
377
378 public void setRealFormat(NumberFormat realFormat) {
379 if (realFormat == null) {
380 throw MathRuntimeException.createIllegalArgumentException(
381 "null real format");
382 }
383 this.realFormat = realFormat;
384 }
385
386 }