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