Source Code Cross Referenced for ComplexFormat.java in  » Science » Apache-commons-math-1.1 » org » apache » commons » math » complex » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » Apache commons math 1.1 » org.apache.commons.math.complex 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2004 The Apache Software Foundation.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.apache.commons.math.complex;
018:
019:        import java.io.Serializable;
020:        import java.text.FieldPosition;
021:        import java.text.Format;
022:        import java.text.NumberFormat;
023:        import java.text.ParseException;
024:        import java.text.ParsePosition;
025:        import java.util.Locale;
026:
027:        /**
028:         * Formats a Complex number in cartesian format "Re(c) + Im(c)i".  'i' can
029:         * be replaced with 'j', and the number format for both real and imaginary parts
030:         * can be configured.
031:         *
032:         * @author Apache Software Foundation
033:         * @version $Revision: 348519 $ $Date: 2005-11-23 12:12:18 -0700 (Wed, 23 Nov 2005) $
034:         */
035:        public class ComplexFormat extends Format implements  Serializable {
036:
037:            /** Serializable version identifier */
038:            private static final long serialVersionUID = -6337346779577272306L;
039:
040:            /** The default imaginary character. */
041:            private static final String DEFAULT_IMAGINARY_CHARACTER = "i";
042:
043:            /** The notation used to signify the imaginary part of the complex number. */
044:            private String imaginaryCharacter;
045:
046:            /** The format used for the imaginary part. */
047:            private NumberFormat imaginaryFormat;
048:
049:            /** The format used for the real part. */
050:            private NumberFormat realFormat;
051:
052:            /**
053:             * Create an instance with the default imaginary character, 'i', and the
054:             * default number format for both real and imaginary parts.
055:             */
056:            public ComplexFormat() {
057:                this (DEFAULT_IMAGINARY_CHARACTER, getDefaultNumberFormat());
058:            }
059:
060:            /**
061:             * Create an instance with a custom number format for both real and
062:             * imaginary parts.
063:             * @param format the custom format for both real and imaginary parts.
064:             */
065:            public ComplexFormat(NumberFormat format) {
066:                this (DEFAULT_IMAGINARY_CHARACTER, format);
067:            }
068:
069:            /**
070:             * Create an instance with a custom number format for the real part and a
071:             * custom number format for the imaginary part.
072:             * @param realFormat the custom format for the real part.
073:             * @param imaginaryFormat the custom format for the imaginary part.
074:             */
075:            public ComplexFormat(NumberFormat realFormat,
076:                    NumberFormat imaginaryFormat) {
077:                this (DEFAULT_IMAGINARY_CHARACTER, realFormat, imaginaryFormat);
078:            }
079:
080:            /**
081:             * Create an instance with a custom imaginary character, and the default
082:             * number format for both real and imaginary parts.
083:             * @param imaginaryCharacter The custom imaginary character.
084:             */
085:            public ComplexFormat(String imaginaryCharacter) {
086:                this (imaginaryCharacter, getDefaultNumberFormat());
087:            }
088:
089:            /**
090:             * Create an instance with a custom imaginary character, and a custom number
091:             * format for both real and imaginary parts.
092:             * @param imaginaryCharacter The custom imaginary character.
093:             * @param format the custom format for both real and imaginary parts.
094:             */
095:            public ComplexFormat(String imaginaryCharacter, NumberFormat format) {
096:                this (imaginaryCharacter, format, (NumberFormat) format.clone());
097:            }
098:
099:            /**
100:             * Create an instance with a custom imaginary character, a custom number
101:             * format for the real part, and a custom number format for the imaginary
102:             * part.
103:             * @param imaginaryCharacter The custom imaginary character.
104:             * @param realFormat the custom format for the real part.
105:             * @param imaginaryFormat the custom format for the imaginary part.
106:             */
107:            public ComplexFormat(String imaginaryCharacter,
108:                    NumberFormat realFormat, NumberFormat imaginaryFormat) {
109:                super ();
110:                setImaginaryCharacter(imaginaryCharacter);
111:                setImaginaryFormat(imaginaryFormat);
112:                setRealFormat(realFormat);
113:            }
114:
115:            /**
116:             * This static method calls formatComplex() on a default instance of
117:             * ComplexFormat.
118:             *
119:             * @param c Complex object to format
120:             * @return A formatted number in the form "Re(c) + Im(c)i"
121:             */
122:            public static String formatComplex(Complex c) {
123:                return getInstance().format(c);
124:            }
125:
126:            /**
127:             * Formats a {@link Complex} object to produce a string.
128:             *
129:             * @param complex the object to format.
130:             * @param toAppendTo where the text is to be appended
131:             * @param pos On input: an alignment field, if desired. On output: the
132:             *            offsets of the alignment field
133:             * @return the value passed in as toAppendTo.
134:             */
135:            public StringBuffer format(Complex complex,
136:                    StringBuffer toAppendTo, FieldPosition pos) {
137:
138:                pos.setBeginIndex(0);
139:                pos.setEndIndex(0);
140:
141:                // format real
142:                double re = complex.getReal();
143:                formatDouble(re, getRealFormat(), toAppendTo, pos);
144:
145:                // format sign and imaginary
146:                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:            /**
161:             * Formats a object to produce a string.  <code>obj</code> must be either a 
162:             * {@link Complex} object or a {@link Number} object.  Any other type of
163:             * object will result in an {@link IllegalArgumentException} being thrown.
164:             *
165:             * @param obj the object to format.
166:             * @param toAppendTo where the text is to be appended
167:             * @param pos On input: an alignment field, if desired. On output: the
168:             *            offsets of the alignment field
169:             * @return the value passed in as toAppendTo.
170:             * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition)
171:             * @throws IllegalArgumentException is <code>obj</code> is not a valid type.
172:             */
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(
182:                            new Complex(((Number) obj).doubleValue(), 0.0),
183:                            toAppendTo, pos);
184:                } else {
185:                    throw new IllegalArgumentException(
186:                            "Cannot format given Object as a Date");
187:                }
188:
189:                return ret;
190:            }
191:
192:            /**
193:             * Formats a double value to produce a string.  In general, the value is
194:             * formatted using the formatting rules of <code>format</code>.  There are
195:             * three exceptions to this:
196:             * <ol>
197:             * <li>NaN is formatted as '(NaN)'</li>
198:             * <li>Positive infinity is formatted as '(Infinity)'</li>
199:             * <li>Negative infinity is formatted as '(-Infinity)'</li>
200:             * </ol>
201:             *
202:             * @param value the double to format.
203:             * @param format the format used.
204:             * @param toAppendTo where the text is to be appended
205:             * @param pos On input: an alignment field, if desired. On output: the
206:             *            offsets of the alignment field
207:             * @return the value passed in as toAppendTo.
208:             */
209:            private StringBuffer formatDouble(double value,
210:                    NumberFormat format, StringBuffer toAppendTo,
211:                    FieldPosition pos) {
212:                if (Double.isNaN(value) || Double.isInfinite(value)) {
213:                    toAppendTo.append('(');
214:                    toAppendTo.append(value);
215:                    toAppendTo.append(')');
216:                } else {
217:                    getRealFormat().format(value, toAppendTo, pos);
218:                }
219:                return toAppendTo;
220:            }
221:
222:            /**
223:             * Get the set of locales for which complex formats are available.  This
224:             * is the same set as the {@link NumberFormat} set. 
225:             * @return available complex format locales.
226:             */
227:            public static Locale[] getAvailableLocales() {
228:                return NumberFormat.getAvailableLocales();
229:            }
230:
231:            /**
232:             * Create a default number format.  The default number format is based on
233:             * {@link NumberFormat#getInstance()} with the only customizing is the
234:             * maximum number of fraction digits, which is set to 2.  
235:             * @return the default number format.
236:             */
237:            private static NumberFormat getDefaultNumberFormat() {
238:                return getDefaultNumberFormat(Locale.getDefault());
239:            }
240:
241:            /**
242:             * Create a default number format.  The default number format is based on
243:             * {@link NumberFormat#getInstance(java.util.Locale)} with the only
244:             * customizing is the maximum number of fraction digits, which is set to 2.  
245:             * @param locale the specific locale used by the format.
246:             * @return the default number format specific to the given locale.
247:             */
248:            private static NumberFormat getDefaultNumberFormat(Locale locale) {
249:                NumberFormat nf = NumberFormat.getInstance(locale);
250:                nf.setMaximumFractionDigits(2);
251:                return nf;
252:            }
253:
254:            /**
255:             * Access the imaginaryCharacter.
256:             * @return the imaginaryCharacter.
257:             */
258:            public String getImaginaryCharacter() {
259:                return imaginaryCharacter;
260:            }
261:
262:            /**
263:             * Access the imaginaryFormat.
264:             * @return the imaginaryFormat.
265:             */
266:            public NumberFormat getImaginaryFormat() {
267:                return imaginaryFormat;
268:            }
269:
270:            /**
271:             * Returns the default complex format for the current locale.
272:             * @return the default complex format.
273:             */
274:            public static ComplexFormat getInstance() {
275:                return getInstance(Locale.getDefault());
276:            }
277:
278:            /**
279:             * Returns the default complex format for the given locale.
280:             * @param locale the specific locale used by the format.
281:             * @return the complex format specific to the given locale.
282:             */
283:            public static ComplexFormat getInstance(Locale locale) {
284:                NumberFormat f = getDefaultNumberFormat(locale);
285:                return new ComplexFormat(f);
286:            }
287:
288:            /**
289:             * Access the realFormat.
290:             * @return the realFormat.
291:             */
292:            public NumberFormat getRealFormat() {
293:                return realFormat;
294:            }
295:
296:            /**
297:             * Parses a string to produce a {@link Complex} object.
298:             *
299:             * @param source the string to parse
300:             * @return the parsed {@link Complex} object.
301:             * @exception ParseException if the beginning of the specified string
302:             *            cannot be parsed.
303:             */
304:            public Complex parse(String source) throws ParseException {
305:                ParsePosition parsePosition = new ParsePosition(0);
306:                Complex result = parse(source, parsePosition);
307:                if (parsePosition.getIndex() == 0) {
308:                    throw new ParseException("Unparseable complex number: \""
309:                            + source + "\"", parsePosition.getErrorIndex());
310:                }
311:                return result;
312:            }
313:
314:            /**
315:             * Parses a string to produce a {@link Complex} object.
316:             *
317:             * @param source the string to parse
318:             * @param pos input/ouput parsing parameter.
319:             * @return the parsed {@link Complex} object.
320:             */
321:            public Complex parse(String source, ParsePosition pos) {
322:                int initialIndex = pos.getIndex();
323:
324:                // parse whitespace
325:                parseAndIgnoreWhitespace(source, pos);
326:
327:                // parse real
328:                Number re = parseNumber(source, getRealFormat(), pos);
329:                if (re == null) {
330:                    // invalid real number
331:                    // set index back to initial, error index should already be set
332:                    // character examined.
333:                    pos.setIndex(initialIndex);
334:                    return null;
335:                }
336:
337:                // parse sign
338:                int startIndex = pos.getIndex();
339:                char c = parseNextCharacter(source, pos);
340:                int sign = 0;
341:                switch (c) {
342:                case 0:
343:                    // no sign
344:                    // return real only complex number
345:                    return new Complex(re.doubleValue(), 0.0);
346:                case '-':
347:                    sign = -1;
348:                    break;
349:                case '+':
350:                    sign = 1;
351:                    break;
352:                default:
353:                    // invalid sign
354:                    // set index back to initial, error index should be the last
355:                    // character examined.
356:                    pos.setIndex(initialIndex);
357:                    pos.setErrorIndex(startIndex);
358:                    return null;
359:                }
360:
361:                // parse whitespace
362:                parseAndIgnoreWhitespace(source, pos);
363:
364:                // parse imaginary
365:                Number im = parseNumber(source, getRealFormat(), pos);
366:                if (im == null) {
367:                    // invalid imaginary number
368:                    // set index back to initial, error index should already be set
369:                    // character examined.
370:                    pos.setIndex(initialIndex);
371:                    return null;
372:                }
373:
374:                // parse imaginary character
375:                int n = getImaginaryCharacter().length();
376:                startIndex = pos.getIndex();
377:                int endIndex = startIndex + n;
378:                if (source.substring(startIndex, endIndex).compareTo(
379:                        getImaginaryCharacter()) != 0) {
380:                    // set index back to initial, error index should be the start index
381:                    // character examined.
382:                    pos.setIndex(initialIndex);
383:                    pos.setErrorIndex(startIndex);
384:                    return null;
385:                }
386:                pos.setIndex(endIndex);
387:
388:                return new Complex(re.doubleValue(), im.doubleValue() * sign);
389:            }
390:
391:            /**
392:             * Parses <code>source</code> until a non-whitespace character is found.
393:             *
394:             * @param source the string to parse
395:             * @param pos input/ouput parsing parameter.  On output, <code>pos</code>
396:             *        holds the index of the next non-whitespace character.
397:             */
398:            private void parseAndIgnoreWhitespace(String source,
399:                    ParsePosition pos) {
400:                parseNextCharacter(source, pos);
401:                pos.setIndex(pos.getIndex() - 1);
402:            }
403:
404:            /**
405:             * Parses <code>source</code> until a non-whitespace character is found.
406:             *
407:             * @param source the string to parse
408:             * @param pos input/ouput parsing parameter.
409:             * @return the first non-whitespace character.
410:             */
411:            private char parseNextCharacter(String source, ParsePosition pos) {
412:                int index = pos.getIndex();
413:                int n = source.length();
414:                char ret = 0;
415:
416:                if (index < n) {
417:                    char c;
418:                    do {
419:                        c = source.charAt(index++);
420:                    } while (Character.isWhitespace(c) && index < n);
421:                    pos.setIndex(index);
422:
423:                    if (index < n) {
424:                        ret = c;
425:                    }
426:                }
427:
428:                return ret;
429:            }
430:
431:            /**
432:             * Parses <code>source</code> for a special double values.  These values
433:             * include Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY.
434:             *
435:             * @param source the string to parse
436:             * @param value the special value to parse.
437:             * @param pos input/ouput parsing parameter.
438:             * @return the special number.
439:             */
440:            private Number parseNumber(String source, double value,
441:                    ParsePosition pos) {
442:                Number ret = null;
443:
444:                StringBuffer sb = new StringBuffer();
445:                sb.append('(');
446:                sb.append(value);
447:                sb.append(')');
448:
449:                int n = sb.length();
450:                int startIndex = pos.getIndex();
451:                int endIndex = startIndex + n;
452:                if (endIndex < source.length()) {
453:                    if (source.substring(startIndex, endIndex).compareTo(
454:                            sb.toString()) == 0) {
455:                        ret = new Double(value);
456:                        pos.setIndex(endIndex);
457:                    }
458:                }
459:
460:                return ret;
461:            }
462:
463:            /**
464:             * Parses <code>source</code> for a number.  This method can parse normal,
465:             * numeric values as well as special values.  These special values include
466:             * Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY.
467:             *
468:             * @param source the string to parse
469:             * @param format the number format used to parse normal, numeric values.
470:             * @param pos input/ouput parsing parameter.
471:             * @return the parsed number.
472:             */
473:            private Number parseNumber(String source, NumberFormat format,
474:                    ParsePosition pos) {
475:                int startIndex = pos.getIndex();
476:                Number number = getRealFormat().parse(source, pos);
477:                int endIndex = pos.getIndex();
478:
479:                // check for error parsing number
480:                if (startIndex == endIndex) {
481:                    // try parsing special numbers
482:                    double[] special = { Double.NaN, Double.POSITIVE_INFINITY,
483:                            Double.NEGATIVE_INFINITY };
484:                    for (int i = 0; i < special.length; ++i) {
485:                        number = parseNumber(source, special[i], pos);
486:                        if (number != null) {
487:                            break;
488:                        }
489:                    }
490:                }
491:
492:                return number;
493:            }
494:
495:            /**
496:             * Parses a string to produce a object.
497:             *
498:             * @param source the string to parse
499:             * @param pos input/ouput parsing parameter.
500:             * @return the parsed object.
501:             * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition)
502:             */
503:            public Object parseObject(String source, ParsePosition pos) {
504:                return parse(source, pos);
505:            }
506:
507:            /**
508:             * Modify the imaginaryCharacter.
509:             * @param imaginaryCharacter The new imaginaryCharacter value.
510:             * @throws IllegalArgumentException if <code>imaginaryCharacter</code> is
511:             *         <code>null</code> or an empty string.
512:             */
513:            public void setImaginaryCharacter(String imaginaryCharacter) {
514:                if (imaginaryCharacter == null
515:                        || imaginaryCharacter.length() == 0) {
516:                    throw new IllegalArgumentException(
517:                            "imaginaryCharacter must be a non-empty string.");
518:                }
519:                this .imaginaryCharacter = imaginaryCharacter;
520:            }
521:
522:            /**
523:             * Modify the imaginaryFormat.
524:             * @param imaginaryFormat The new imaginaryFormat value.
525:             * @throws IllegalArgumentException if <code>imaginaryFormat</code> is
526:             *         <code>null</code>.
527:             */
528:            public void setImaginaryFormat(NumberFormat imaginaryFormat) {
529:                if (imaginaryFormat == null) {
530:                    throw new IllegalArgumentException(
531:                            "imaginaryFormat can not be null.");
532:                }
533:                this .imaginaryFormat = imaginaryFormat;
534:            }
535:
536:            /**
537:             * Modify the realFormat.
538:             * @param realFormat The new realFormat value.
539:             * @throws IllegalArgumentException if <code>realFormat</code> is
540:             *         <code>null</code>.
541:             */
542:            public void setRealFormat(NumberFormat realFormat) {
543:                if (realFormat == null) {
544:                    throw new IllegalArgumentException(
545:                            "realFormat can not be null.");
546:                }
547:                this.realFormat = realFormat;
548:            }
549:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.