1 /* Copyright 2002-2019 CS Systèmes d'Information
2 * Licensed to CS Systèmes d'Information (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.data;
18
19 import java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.io.Serializable;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31
32 import org.hipparchus.RealFieldElement;
33 import org.hipparchus.exception.DummyLocalizable;
34 import org.hipparchus.util.FastMath;
35 import org.orekit.errors.OrekitException;
36 import org.orekit.errors.OrekitInternalError;
37 import org.orekit.errors.OrekitMessages;
38 import org.orekit.time.AbsoluteDate;
39 import org.orekit.time.FieldAbsoluteDate;
40 import org.orekit.time.TimeScalarFunction;
41 import org.orekit.time.TimeScale;
42 import org.orekit.utils.Constants;
43 import org.orekit.utils.IERSConventions;
44
45 /**
46 * Class computing the fundamental arguments for nutation and tides.
47 * <p>
48 * The fundamental arguments are split in two sets:
49 * </p>
50 * <ul>
51 * <li>the Delaunay arguments for Moon and Sun effects</li>
52 * <li>the planetary arguments for other planets</li>
53 * </ul>
54 *
55 * @author Luc Maisonobe
56 * @see SeriesTerm
57 * @see PoissonSeries
58 * @see BodiesElements
59 */
60 public class FundamentalNutationArguments implements Serializable {
61
62 /** Serializable UID. */
63 private static final long serialVersionUID = 20131209L;
64
65 /** IERS conventions to use. */
66 private final IERSConventions conventions;
67
68 /** Time scale for GMST computation. */
69 private final TimeScale timeScale;
70
71 /** Function computing Greenwich Mean Sidereal Time. */
72 private final transient TimeScalarFunction gmstFunction;
73
74 /** Function computing Greenwich Mean Sidereal Time rate. */
75 private final transient TimeScalarFunction gmstRateFunction;
76
77 // luni-solar Delaunay arguments
78
79 /** Coefficients for mean anomaly of the Moon. */
80 private final double[] lCoefficients;
81
82 /** Coefficients for mean anomaly of the Sun. */
83 private final double[] lPrimeCoefficients;
84
85 /** Coefficients for L - Ω where L is the mean longitude of the Moon. */
86 private final double[] fCoefficients;
87
88 /** Coefficients for mean elongation of the Moon from the Sun. */
89 private final double[] dCoefficients;
90
91 /** Coefficients for mean longitude of the ascending node of the Moon. */
92 private final double[] omegaCoefficients;
93
94 // planetary nutation arguments
95
96 /** Coefficients for mean Mercury longitude. */
97 private final double[] lMeCoefficients;
98
99 /** Coefficients for mean Venus longitude. */
100 private final double[] lVeCoefficients;
101
102 /** Coefficients for mean Earth longitude. */
103 private final double[] lECoefficients;
104
105 /** Coefficients for mean Mars longitude. */
106 private final double[] lMaCoefficients;
107
108 /** Coefficients for mean Jupiter longitude. */
109 private final double[] lJCoefficients;
110
111 /** Coefficients for mean Saturn longitude. */
112 private final double[] lSaCoefficients;
113
114 /** Coefficients for mean Uranus longitude. */
115 private final double[] lUCoefficients;
116
117 /** Coefficients for mean Neptune longitude. */
118 private final double[] lNeCoefficients;
119
120 /** Coefficients for general accumulated precession. */
121 private final double[] paCoefficients;
122
123 /** Build a model of fundamental arguments from an IERS table file.
124 * @param conventions IERS conventions to use
125 * @param timeScale time scale for GMST computation
126 * (may be null if tide parameter γ = GMST + π is not needed)
127 * @param stream stream containing the IERS table
128 * @param name name of the resource file (for error messages only)
129 */
130 public FundamentalNutationArguments(final IERSConventions conventions,
131 final TimeScale timeScale,
132 final InputStream stream, final String name) {
133 this(conventions, timeScale, parseCoefficients(stream, name));
134 }
135
136 /** Build a model of fundamental arguments from an IERS table file.
137 * @param conventions IERS conventions to use
138 * @param timeScale time scale for GMST computation
139 * (may be null if tide parameter γ = GMST + π is not needed)
140 * @param coefficients list of coefficients arrays (all 14 arrays must be provided,
141 * the 5 Delaunay first and the 9 planetary afterwards)
142 * @since 6.1
143 */
144 public FundamentalNutationArguments(final IERSConventions conventions, final TimeScale timeScale,
145 final List<double[]> coefficients) {
146 this.conventions = conventions;
147 this.timeScale = timeScale;
148 this.gmstFunction = (timeScale == null) ? null : conventions.getGMSTFunction(timeScale);
149 this.gmstRateFunction = (timeScale == null) ? null : conventions.getGMSTRateFunction(timeScale);
150 this.lCoefficients = coefficients.get( 0);
151 this.lPrimeCoefficients = coefficients.get( 1);
152 this.fCoefficients = coefficients.get( 2);
153 this.dCoefficients = coefficients.get( 3);
154 this.omegaCoefficients = coefficients.get( 4);
155 this.lMeCoefficients = coefficients.get( 5);
156 this.lVeCoefficients = coefficients.get( 6);
157 this.lECoefficients = coefficients.get( 7);
158 this.lMaCoefficients = coefficients.get( 8);
159 this.lJCoefficients = coefficients.get( 9);
160 this.lSaCoefficients = coefficients.get(10);
161 this.lUCoefficients = coefficients.get(11);
162 this.lNeCoefficients = coefficients.get(12);
163 this.paCoefficients = coefficients.get(13);
164 }
165
166 /** Parse coefficients.
167 * @param stream stream containing the IERS table
168 * @param name name of the resource file (for error messages only)
169 * @return list of coefficients arrays
170 */
171 private static List<double[]> parseCoefficients(final InputStream stream, final String name) {
172
173 if (stream == null) {
174 throw new OrekitException(OrekitMessages.UNABLE_TO_FIND_FILE, name);
175 }
176
177 try {
178
179 final DefinitionParser definitionParser = new DefinitionParser();
180
181 // setup the reader
182 final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
183 int lineNumber = 0;
184
185 // look for the reference date and the 14 polynomials
186 final int n = FundamentalName.values().length;
187 final Map<FundamentalName, double[]> polynomials = new HashMap<FundamentalName, double[]>(n);
188 for (String line = reader.readLine(); line != null; line = reader.readLine()) {
189 lineNumber++;
190 if (definitionParser.parseDefinition(line, lineNumber, name)) {
191 polynomials.put(definitionParser.getParsedName(),
192 definitionParser.getParsedPolynomial());
193 }
194 }
195
196 final List<double[]> coefficients = new ArrayList<double[]>(n);
197 coefficients.add(getCoefficients(FundamentalName.L, polynomials, name));
198 coefficients.add(getCoefficients(FundamentalName.L_PRIME, polynomials, name));
199 coefficients.add(getCoefficients(FundamentalName.F, polynomials, name));
200 coefficients.add(getCoefficients(FundamentalName.D, polynomials, name));
201 coefficients.add(getCoefficients(FundamentalName.OMEGA, polynomials, name));
202 if (polynomials.containsKey(FundamentalName.L_ME)) {
203 // IERS conventions 2003 and later provide planetary nutation arguments
204 coefficients.add(getCoefficients(FundamentalName.L_ME, polynomials, name));
205 coefficients.add(getCoefficients(FundamentalName.L_VE, polynomials, name));
206 coefficients.add(getCoefficients(FundamentalName.L_E, polynomials, name));
207 coefficients.add(getCoefficients(FundamentalName.L_MA, polynomials, name));
208 coefficients.add(getCoefficients(FundamentalName.L_J, polynomials, name));
209 coefficients.add(getCoefficients(FundamentalName.L_SA, polynomials, name));
210 coefficients.add(getCoefficients(FundamentalName.L_U, polynomials, name));
211 coefficients.add(getCoefficients(FundamentalName.L_NE, polynomials, name));
212 coefficients.add(getCoefficients(FundamentalName.PA, polynomials, name));
213 } else {
214 // IERS conventions 1996 and earlier don't provide planetary nutation arguments
215 final double[] zero = new double[] {
216 0.0
217 };
218 while (coefficients.size() < n) {
219 coefficients.add(zero);
220 }
221 }
222
223 return coefficients;
224
225 } catch (IOException ioe) {
226 throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
227 }
228
229 }
230
231 /** Get the coefficients for a fundamental argument.
232 * @param argument fundamental argument
233 * @param polynomials map of the polynomials
234 * @param fileName name of the file from which the coefficients have been read
235 * @return polynomials coefficients (ordered from high degrees to low degrees)
236 */
237 private static double[] getCoefficients(final FundamentalName argument,
238 final Map<FundamentalName, double[]> polynomials,
239 final String fileName) {
240 if (!polynomials.containsKey(argument)) {
241 throw new OrekitException(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, fileName);
242 }
243 return polynomials.get(argument);
244 }
245
246 /** Evaluate a polynomial.
247 * @param tc offset in Julian centuries
248 * @param coefficients polynomial coefficients (ordered from low degrees to high degrees)
249 * @return value of the polynomial
250 */
251 private double value(final double tc, final double[] coefficients) {
252 double value = 0;
253 for (int i = coefficients.length - 1; i >= 0; --i) {
254 value = coefficients[i] + tc * value;
255 }
256 return value;
257 }
258
259 /** Evaluate a polynomial time derivative.
260 * @param tc offset in Julian centuries
261 * @param coefficients polynomial coefficients (ordered from low degrees to high degrees)
262 * @return time derivative of the polynomial
263 */
264 private double derivative(final double tc, final double[] coefficients) {
265 double derivative = 0;
266 for (int i = coefficients.length - 1; i > 0; --i) {
267 derivative = i * coefficients[i] + tc * derivative;
268 }
269 return derivative / Constants.JULIAN_CENTURY;
270 }
271
272 /** Evaluate a polynomial.
273 * @param tc offset in Julian centuries
274 * @param <T> type of the field elements
275 * @param coefficients polynomial coefficients (ordered from low degrees to high degrees)
276 * @return value of the polynomial
277 */
278 private <T extends RealFieldElement<T>> T value(final T tc, final double[] coefficients) {
279 T value = tc.getField().getZero();
280 for (int i = coefficients.length - 1; i >= 0; --i) {
281 value = tc.multiply(value).add(coefficients[i]);
282 }
283 return value;
284 }
285
286 /** Evaluate a polynomial time derivative.
287 * @param tc offset in Julian centuries
288 * @param <T> type of the field elements
289 * @param coefficients polynomial coefficients (ordered from low degrees to high degrees)
290 * @return time derivative of the polynomial
291 */
292 private <T extends RealFieldElement<T>> T derivative(final T tc, final double[] coefficients) {
293 T derivative = tc.getField().getZero();
294 for (int i = coefficients.length - 1; i > 0; --i) {
295 derivative = tc.multiply(derivative).add(i * coefficients[i]);
296 }
297 return derivative.divide(Constants.JULIAN_CENTURY);
298 }
299
300 /** Evaluate all fundamental arguments for the current date (Delaunay plus planetary).
301 * @param date current date
302 * @return all fundamental arguments for the current date (Delaunay plus planetary)
303 */
304 public BodiesElements evaluateAll(final AbsoluteDate date) {
305
306 final double tc = conventions.evaluateTC(date);
307 final double gamma = gmstFunction == null ?
308 Double.NaN : gmstFunction.value(date) + FastMath.PI;
309 final double gammaDot = gmstRateFunction == null ?
310 Double.NaN : gmstRateFunction.value(date);
311
312 return new BodiesElements(date, tc, gamma, gammaDot,
313 value(tc, lCoefficients), // mean anomaly of the Moon
314 derivative(tc, lCoefficients), // mean anomaly of the Moon time derivative
315 value(tc, lPrimeCoefficients), // mean anomaly of the Sun
316 derivative(tc, lPrimeCoefficients), // mean anomaly of the Sun time derivative
317 value(tc, fCoefficients), // L - Ω where L is the mean longitude of the Moon
318 derivative(tc, fCoefficients), // L - Ω where L is the mean longitude of the Moon time derivative
319 value(tc, dCoefficients), // mean elongation of the Moon from the Sun
320 derivative(tc, dCoefficients), // mean elongation of the Moon from the Sun time derivative
321 value(tc, omegaCoefficients), // mean longitude of the ascending node of the Moon
322 derivative(tc, omegaCoefficients), // mean longitude of the ascending node of the Moon time derivative
323 value(tc, lMeCoefficients), // mean Mercury longitude
324 derivative(tc, lMeCoefficients), // mean Mercury longitude time derivative
325 value(tc, lVeCoefficients), // mean Venus longitude
326 derivative(tc, lVeCoefficients), // mean Venus longitude time derivative
327 value(tc, lECoefficients), // mean Earth longitude
328 derivative(tc, lECoefficients), // mean Earth longitude time derivative
329 value(tc, lMaCoefficients), // mean Mars longitude
330 derivative(tc, lMaCoefficients), // mean Mars longitude time derivative
331 value(tc, lJCoefficients), // mean Jupiter longitude
332 derivative(tc, lJCoefficients), // mean Jupiter longitude time derivative
333 value(tc, lSaCoefficients), // mean Saturn longitude
334 derivative(tc, lSaCoefficients), // mean Saturn longitude time derivative
335 value(tc, lUCoefficients), // mean Uranus longitude
336 derivative(tc, lUCoefficients), // mean Uranus longitude time derivative
337 value(tc, lNeCoefficients), // mean Neptune longitude
338 derivative(tc, lNeCoefficients), // mean Neptune longitude time derivative
339 value(tc, paCoefficients), // general accumulated precession in longitude
340 derivative(tc, paCoefficients)); // general accumulated precession in longitude time derivative
341
342 }
343
344 /** Evaluate all fundamental arguments for the current date (Delaunay plus planetary).
345 * @param date current date
346 * @param <T> type of the field elements
347 * @return all fundamental arguments for the current date (Delaunay plus planetary)
348 */
349 public <T extends RealFieldElement<T>> FieldBodiesElements<T> evaluateAll(final FieldAbsoluteDate<T> date) {
350
351 final T tc = conventions.evaluateTC(date);
352 final T gamma = gmstFunction == null ?
353 tc.getField().getZero().add(Double.NaN) : gmstFunction.value(date).add(FastMath.PI);
354 final T gammaDot = gmstRateFunction == null ?
355 tc.getField().getZero().add(Double.NaN) : gmstRateFunction.value(date);
356
357 return new FieldBodiesElements<>(date, tc, gamma, gammaDot,
358 value(tc, lCoefficients), // mean anomaly of the Moon
359 derivative(tc, lCoefficients), // mean anomaly of the Moon time derivative
360 value(tc, lPrimeCoefficients), // mean anomaly of the Sun
361 derivative(tc, lPrimeCoefficients), // mean anomaly of the Sun time derivative
362 value(tc, fCoefficients), // L - Ω where L is the mean longitude of the Moon
363 derivative(tc, fCoefficients), // L - Ω where L is the mean longitude of the Moon time derivative
364 value(tc, dCoefficients), // mean elongation of the Moon from the Sun
365 derivative(tc, dCoefficients), // mean elongation of the Moon from the Sun time derivative
366 value(tc, omegaCoefficients), // mean longitude of the ascending node of the Moon
367 derivative(tc, omegaCoefficients), // mean longitude of the ascending node of the Moon time derivative
368 value(tc, lMeCoefficients), // mean Mercury longitude
369 derivative(tc, lMeCoefficients), // mean Mercury longitude time derivative
370 value(tc, lVeCoefficients), // mean Venus longitude
371 derivative(tc, lVeCoefficients), // mean Venus longitude time derivative
372 value(tc, lECoefficients), // mean Earth longitude
373 derivative(tc, lECoefficients), // mean Earth longitude time derivative
374 value(tc, lMaCoefficients), // mean Mars longitude
375 derivative(tc, lMaCoefficients), // mean Mars longitude time derivative
376 value(tc, lJCoefficients), // mean Jupiter longitude
377 derivative(tc, lJCoefficients), // mean Jupiter longitude time derivative
378 value(tc, lSaCoefficients), // mean Saturn longitude
379 derivative(tc, lSaCoefficients), // mean Saturn longitude time derivative
380 value(tc, lUCoefficients), // mean Uranus longitude
381 derivative(tc, lUCoefficients), // mean Uranus longitude time derivative
382 value(tc, lNeCoefficients), // mean Neptune longitude
383 derivative(tc, lNeCoefficients), // mean Neptune longitude time derivative
384 value(tc, paCoefficients), // general accumulated precession in longitude
385 derivative(tc, paCoefficients)); // general accumulated precession in longitude time derivative
386
387 }
388
389 /** Replace the instance with a data transfer object for serialization.
390 * <p>
391 * This intermediate class serializes only the frame key.
392 * </p>
393 * @return data transfer object that will be serialized
394 */
395 private Object writeReplace() {
396 return new DataTransferObject(conventions, timeScale,
397 Arrays.asList(lCoefficients, lPrimeCoefficients, fCoefficients,
398 dCoefficients, omegaCoefficients,
399 lMeCoefficients, lVeCoefficients, lECoefficients,
400 lMaCoefficients, lJCoefficients, lSaCoefficients,
401 lUCoefficients, lNeCoefficients, paCoefficients));
402 }
403
404 /** Internal class used only for serialization. */
405 private static class DataTransferObject implements Serializable {
406
407 /** Serializable UID. */
408 private static final long serialVersionUID = 20131209L;
409
410 /** IERS conventions to use. */
411 private final IERSConventions conventions;
412
413 /** Time scale for GMST computation. */
414 private final TimeScale timeScale;
415
416 /** All coefficients. */
417 private final List<double[]> coefficients;
418
419 /** Simple constructor.
420 * @param conventions IERS conventions to use
421 * @param timeScale time scale for GMST computation
422 * @param coefficients all coefficients
423 */
424 DataTransferObject(final IERSConventions conventions, final TimeScale timeScale,
425 final List<double[]> coefficients) {
426 this.conventions = conventions;
427 this.timeScale = timeScale;
428 this.coefficients = coefficients;
429 }
430
431 /** Replace the deserialized data transfer object with a {@link TIRFProvider}.
432 * @return replacement {@link TIRFProvider}
433 */
434 private Object readResolve() {
435 try {
436 // retrieve a managed frame
437 return new FundamentalNutationArguments(conventions, timeScale, coefficients);
438 } catch (OrekitException oe) {
439 throw new OrekitInternalError(oe);
440 }
441 }
442
443 }
444
445 /** Enumerate for the fundamental names. */
446 private enum FundamentalName {
447
448 /** Constant for Mean anomaly of the Moon. */
449 L() {
450 /** {@inheritDoc} */
451 public String getArgumentName() {
452 return "l";
453 }
454 },
455
456 /** Constant for Mean anomaly of the Sun. */
457 L_PRIME() {
458 /** {@inheritDoc} */
459 public String getArgumentName() {
460 return "l'";
461 }
462 },
463
464 /** Constant for L - Ω where L is the mean longitude of the Moon. */
465 F() {
466 /** {@inheritDoc} */
467 public String getArgumentName() {
468 return "F";
469 }
470 },
471
472 /** Constant for mean elongation of the Moon from the Sun. */
473 D() {
474 /** {@inheritDoc} */
475 public String getArgumentName() {
476 return "D";
477 }
478 },
479
480 /** Constant for longitude of the ascending node of the Moon. */
481 OMEGA() {
482 /** {@inheritDoc} */
483 public String getArgumentName() {
484 return "\u03a9";
485 }
486 },
487
488 /** Constant for mean Mercury longitude. */
489 L_ME() {
490 /** {@inheritDoc} */
491 public String getArgumentName() {
492 return "LMe";
493 }
494 },
495
496 /** Constant for mean Venus longitude. */
497 L_VE() {
498 /** {@inheritDoc} */
499 public String getArgumentName() {
500 return "LVe";
501 }
502 },
503
504 /** Constant for mean Earth longitude. */
505 L_E() {
506 /** {@inheritDoc} */
507 public String getArgumentName() {
508 return "LE";
509 }
510 },
511
512 /** Constant for mean Mars longitude. */
513 L_MA() {
514 /** {@inheritDoc} */
515 public String getArgumentName() {
516 return "LMa";
517 }
518 },
519
520 /** Constant for mean Jupiter longitude. */
521 L_J() {
522 /** {@inheritDoc} */
523 public String getArgumentName() {
524 return "LJ";
525 }
526 },
527
528 /** Constant for mean Saturn longitude. */
529 L_SA() {
530 /** {@inheritDoc} */
531 public String getArgumentName() {
532 return "LSa";
533 }
534 },
535
536 /** Constant for mean Uranus longitude. */
537 L_U() {
538 /** {@inheritDoc} */
539 public String getArgumentName() {
540 return "LU";
541 }
542 },
543
544 /** Constant for mean Neptune longitude. */
545 L_NE() {
546 /** {@inheritDoc} */
547 public String getArgumentName() {
548 return "LNe";
549 }
550 },
551
552 /** Constant for general accumulated precession in longitude. */
553 PA() {
554 /** {@inheritDoc} */
555 public String getArgumentName() {
556 return "pA";
557 }
558 };
559
560 /** Get the fundamental name.
561 * @return fundamental name
562 */
563 public abstract String getArgumentName();
564
565 }
566
567 /** Local parser for argument definition lines. */
568 private static class DefinitionParser {
569
570 /** Regular expression pattern for definitions. */
571 private final Pattern pattern;
572
573 /** Parser for polynomials. */
574 private PolynomialParser polynomialParser;
575
576 /** Last parsed fundamental name. */
577 private FundamentalName parsedName;
578
579 /** Last parsed polynomial. */
580 private double[] parsedPolynomial;
581
582 /** Simple constructor. */
583 DefinitionParser() {
584
585 // the luni-solar Delaunay arguments polynomial parts should read something like:
586 // F5 ≡ Ω = 125.04455501° − 6962890.5431″t + 7.4722″t² + 0.007702″t³ − 0.00005939″t⁴
587 // whereas the planetary arguments polynomial parts should read something like:
588 // F14 ≡ pA = 0.02438175 × t + 0.00000538691 × t²
589 final String unicodeIdenticalTo = "\u2261";
590
591 // pattern for the global line
592 final StringBuilder builder = new StringBuilder();
593 for (final FundamentalName fn : FundamentalName.values()) {
594 if (builder.length() > 0) {
595 builder.append('|');
596 }
597 builder.append(fn.getArgumentName());
598 }
599 final String fundamentalName = "\\p{Space}*((?:" + builder.toString() + ")+)";
600 pattern = Pattern.compile("\\p{Space}*F\\p{Digit}+\\p{Space}*" + unicodeIdenticalTo +
601 fundamentalName + "\\p{Space}*=\\p{Space}*(.*)");
602
603 polynomialParser = new PolynomialParser('t', PolynomialParser.Unit.NO_UNITS);
604
605 }
606
607 /** Parse a definition line.
608 * @param line line to parse
609 * @param lineNumber line number
610 * @param fileName name of the file
611 * @return true if a definition has been parsed
612 */
613 public boolean parseDefinition(final String line, final int lineNumber, final String fileName) {
614
615 parsedName = null;
616 parsedPolynomial = null;
617
618 final Matcher matcher = pattern.matcher(line);
619 if (matcher.matches()) {
620 for (FundamentalName fn : FundamentalName.values()) {
621 if (fn.getArgumentName().equals(matcher.group(1))) {
622 parsedName = fn;
623 }
624 }
625
626 // parse the polynomial
627 parsedPolynomial = polynomialParser.parse(matcher.group(2));
628
629 return true;
630
631 } else {
632 return false;
633 }
634
635 }
636
637 /** Get the last parsed fundamental name.
638 * @return last parsed fundamental name
639 */
640 public FundamentalName getParsedName() {
641 return parsedName;
642 }
643
644 /** Get the last parsed polynomial.
645 * @return last parsed polynomial
646 */
647 public double[] getParsedPolynomial() {
648 return parsedPolynomial.clone();
649 }
650
651 }
652
653 }