1 16 17 package org.apache.commons.math.complex; 18 19 import java.io.Serializable ; 20 import java.text.FieldPosition ; 21 import java.text.Format ; 22 import java.text.NumberFormat ; 23 import java.text.ParseException ; 24 import java.text.ParsePosition ; 25 import java.util.Locale ; 26 27 35 public class ComplexFormat extends Format implements Serializable { 36 37 38 static final long serialVersionUID = -6337346779577272306L; 39 40 41 private static final String DEFAULT_IMAGINARY_CHARACTER = "i"; 42 43 44 private String imaginaryCharacter; 45 46 47 private NumberFormat imaginaryFormat; 48 49 50 private NumberFormat realFormat; 51 52 56 public ComplexFormat() { 57 this(DEFAULT_IMAGINARY_CHARACTER, getDefaultNumberFormat()); 58 } 59 60 65 public ComplexFormat(NumberFormat format) { 66 this(DEFAULT_IMAGINARY_CHARACTER, format); 67 } 68 69 75 public ComplexFormat(NumberFormat realFormat, 76 NumberFormat imaginaryFormat) { 77 this(DEFAULT_IMAGINARY_CHARACTER, realFormat, imaginaryFormat); 78 } 79 80 85 public ComplexFormat(String imaginaryCharacter) { 86 this(imaginaryCharacter, getDefaultNumberFormat()); 87 } 88 89 95 public ComplexFormat(String imaginaryCharacter, NumberFormat format) { 96 this(imaginaryCharacter, format, (NumberFormat )format.clone()); 97 } 98 99 107 public ComplexFormat(String imaginaryCharacter, NumberFormat realFormat, 108 NumberFormat imaginaryFormat) { 109 super(); 110 setImaginaryCharacter(imaginaryCharacter); 111 setImaginaryFormat(imaginaryFormat); 112 setRealFormat(realFormat); 113 } 114 115 122 public static String formatComplex( Complex c ) { 123 return getInstance().format( c ); 124 } 125 126 135 public StringBuffer format(Complex complex, StringBuffer toAppendTo, 136 FieldPosition pos) { 137 138 pos.setBeginIndex(0); 139 pos.setEndIndex(0); 140 141 double re = complex.getReal(); 143 formatDouble(re, getRealFormat(), toAppendTo, pos); 144 145 double im = complex.getImaginary(); 147 if (im < 0.0) { 148 toAppendTo.append(" - "); 149 formatDouble(-im, getImaginaryFormat(), toAppendTo, pos); 150 toAppendTo.append(getImaginaryCharacter()); 151 } else if (im > 0.0 || Double.isNaN(im)) { 152 toAppendTo.append(" + "); 153 formatDouble(im, getImaginaryFormat(), toAppendTo, pos); 154 toAppendTo.append(getImaginaryCharacter()); 155 } 156 157 return toAppendTo; 158 } 159 160 173 public StringBuffer format(Object obj, StringBuffer toAppendTo, 174 FieldPosition pos) { 175 176 StringBuffer ret = null; 177 178 if (obj instanceof Complex) { 179 ret = format( (Complex)obj, toAppendTo, pos); 180 } else if (obj instanceof Number ) { 181 ret = format( new Complex(((Number )obj).doubleValue(), 0.0), 182 toAppendTo, pos); 183 } else { 184 throw new IllegalArgumentException ( 185 "Cannot format given Object as a Date"); 186 } 187 188 return ret; 189 } 190 191 208 private StringBuffer formatDouble(double value, NumberFormat format, 209 StringBuffer toAppendTo, FieldPosition pos) { 210 if( Double.isNaN(value) || Double.isInfinite(value) ) { 211 toAppendTo.append('('); 212 toAppendTo.append(value); 213 toAppendTo.append(')'); 214 } else { 215 getRealFormat().format(value, toAppendTo, pos); 216 } 217 return toAppendTo; 218 } 219 220 225 public static Locale [] getAvailableLocales() { 226 return NumberFormat.getAvailableLocales(); 227 } 228 229 235 private static NumberFormat getDefaultNumberFormat() { 236 return getDefaultNumberFormat(Locale.getDefault()); 237 } 238 239 246 private static NumberFormat getDefaultNumberFormat(Locale locale) { 247 NumberFormat nf = NumberFormat.getInstance(locale); 248 nf.setMaximumFractionDigits(2); 249 return nf; 250 } 251 252 256 public String getImaginaryCharacter() { 257 return imaginaryCharacter; 258 } 259 260 264 public NumberFormat getImaginaryFormat() { 265 return imaginaryFormat; 266 } 267 268 272 public static ComplexFormat getInstance() { 273 return getInstance(Locale.getDefault()); 274 } 275 276 281 public static ComplexFormat getInstance(Locale locale) { 282 NumberFormat f = getDefaultNumberFormat(locale); 283 return new ComplexFormat(f); 284 } 285 286 290 public NumberFormat getRealFormat() { 291 return realFormat; 292 } 293 294 302 public Complex parse(String source) throws ParseException { 303 ParsePosition parsePosition = new ParsePosition (0); 304 Complex result = parse(source, parsePosition); 305 if (parsePosition.getIndex() == 0) { 306 throw new ParseException ("Unparseable complex number: \"" + source + 307 "\"", parsePosition.getErrorIndex()); 308 } 309 return result; 310 } 311 312 319 public Complex parse(String source, ParsePosition pos) { 320 int initialIndex = pos.getIndex(); 321 322 parseAndIgnoreWhitespace(source, pos); 324 325 Number re = parseNumber(source, getRealFormat(), pos); 327 if (re == null) { 328 pos.setIndex(initialIndex); 332 return null; 333 } 334 335 int startIndex = pos.getIndex(); 337 char c = parseNextCharacter(source, pos); 338 int sign = 0; 339 switch (c) { 340 case 0 : 341 return new Complex(re.doubleValue(), 0.0); 344 case '-' : 345 sign = -1; 346 break; 347 case '+' : 348 sign = 1; 349 break; 350 default : 351 pos.setIndex(initialIndex); 355 pos.setErrorIndex(startIndex); 356 return null; 357 } 358 359 parseAndIgnoreWhitespace(source, pos); 361 362 Number im = parseNumber(source, getRealFormat(), pos); 364 if (im == null) { 365 pos.setIndex(initialIndex); 369 return null; 370 } 371 372 int n = getImaginaryCharacter().length(); 374 startIndex = pos.getIndex(); 375 int endIndex = startIndex + n; 376 if (source.substring(startIndex, endIndex).compareTo( 377 getImaginaryCharacter()) != 0) { 378 pos.setIndex(initialIndex); 381 pos.setErrorIndex(startIndex); 382 return null; 383 } 384 pos.setIndex(endIndex); 385 386 return new Complex(re.doubleValue(), im.doubleValue() * sign); 387 } 388 389 396 private void parseAndIgnoreWhitespace(String source, ParsePosition pos) { 397 parseNextCharacter(source, pos); 398 pos.setIndex(pos.getIndex() - 1); 399 } 400 401 408 private char parseNextCharacter(String source, ParsePosition pos) { 409 int index = pos.getIndex(); 410 int n = source.length(); 411 char ret = 0; 412 413 if (index < n) { 414 char c; 415 do { 416 c = source.charAt(index++); 417 } while (Character.isWhitespace(c) && index < n); 418 pos.setIndex(index); 419 420 if (index < n) { 421 ret = c; 422 } 423 } 424 425 return ret; 426 } 427 428 437 private Number parseNumber(String source, double value, ParsePosition pos) { 438 Number ret = null; 439 440 StringBuffer sb = new StringBuffer (); 441 sb.append('('); 442 sb.append(value); 443 sb.append(')'); 444 445 int n = sb.length(); 446 int startIndex = pos.getIndex(); 447 int endIndex = startIndex + n; 448 if (endIndex < source.length()) { 449 if (source.substring(startIndex, endIndex).compareTo(sb.toString()) == 0) { 450 ret = new Double (value); 451 pos.setIndex(endIndex); 452 } 453 } 454 455 return ret; 456 } 457 458 468 private Number parseNumber(String source, NumberFormat format, ParsePosition pos) { 469 int startIndex = pos.getIndex(); 470 Number number = getRealFormat().parse(source, pos); 471 int endIndex = pos.getIndex(); 472 473 if (startIndex == endIndex) { 475 double[] special = {Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY}; 477 for (int i = 0; i < special.length; ++i) { 478 number = parseNumber(source, special[i], pos); 479 if (number != null) { 480 break; 481 } 482 } 483 } 484 485 return number; 486 } 487 488 496 public Object parseObject(String source, ParsePosition pos) { 497 return parse(source, pos); 498 } 499 505 public void setImaginaryCharacter(String imaginaryCharacter) { 506 if (imaginaryCharacter == null || imaginaryCharacter.length() == 0) { 507 throw new IllegalArgumentException ( 508 "imaginaryCharacter must be a non-empty string."); 509 } 510 this.imaginaryCharacter = imaginaryCharacter; 511 } 512 513 519 public void setImaginaryFormat(NumberFormat imaginaryFormat) { 520 if (imaginaryFormat == null) { 521 throw new IllegalArgumentException ( 522 "imaginaryFormat can not be null."); 523 } 524 this.imaginaryFormat = imaginaryFormat; 525 } 526 527 533 public void setRealFormat(NumberFormat realFormat) { 534 if (realFormat == null) { 535 throw new IllegalArgumentException ( 536 "realFormat can not be null."); 537 } 538 this.realFormat = realFormat; 539 } 540 } 541 | Popular Tags |