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