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.time;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.analysis.interpolation.FieldHermiteInterpolator;
22  import org.hipparchus.util.MathArrays;
23  
24  import java.util.List;
25  
26  /**
27   * Hermite interpolator of time stamped field value.
28   * <p>
29   * As this implementation of interpolation is polynomial, it should be used only with small number of interpolation points
30   * (about 10-20 points) in order to avoid <a href="http://en.wikipedia.org/wiki/Runge%27s_phenomenon">Runge's phenomenon</a>
31   * and numerical problems (including NaN appearing).
32   *
33   * @author Vincent Cucchietti
34   * @see FieldHermiteInterpolator
35   * @see FieldTimeInterpolator
36   * @param <KK> type of the field elements
37   */
38  public class TimeStampedFieldHermiteInterpolator<KK extends CalculusFieldElement<KK>>
39          extends AbstractFieldTimeInterpolator<TimeStampedField<KK>, KK> {
40  
41      /**
42       * Constructor with :
43       * <ul>
44       *     <li>Default number of interpolation points of {@code DEFAULT_INTERPOLATION_POINTS}</li>
45       *     <li>Default extrapolation threshold value ({@code DEFAULT_EXTRAPOLATION_THRESHOLD_SEC} s)</li>
46       * </ul>
47       * As this implementation of interpolation is polynomial, it should be used only with small number of interpolation
48       * points (about 10-20 points) in order to avoid <a href="http://en.wikipedia.org/wiki/Runge%27s_phenomenon">Runge's
49       * phenomenon</a> and numerical problems (including NaN appearing).
50       */
51      public TimeStampedFieldHermiteInterpolator() {
52          this(DEFAULT_INTERPOLATION_POINTS);
53      }
54  
55      /**
56       * Constructor with :
57       * <ul>
58       *     <li>Default extrapolation threshold value ({@code DEFAULT_EXTRAPOLATION_THRESHOLD_SEC} s)</li>
59       * </ul>
60       * As this implementation of interpolation is polynomial, it should be used only with small number of interpolation
61       * points (about 10-20 points) in order to avoid <a href="http://en.wikipedia.org/wiki/Runge%27s_phenomenon">Runge's
62       * phenomenon</a> and numerical problems (including NaN appearing).
63       *
64       * @param interpolationPoints number of interpolation points
65       */
66      public TimeStampedFieldHermiteInterpolator(final int interpolationPoints) {
67          this(interpolationPoints, DEFAULT_EXTRAPOLATION_THRESHOLD_SEC);
68      }
69  
70      /**
71       * Constructor.
72       * <p>
73       * As this implementation of interpolation is polynomial, it should be used only with small number of interpolation
74       * points (about 10-20 points) in order to avoid <a href="http://en.wikipedia.org/wiki/Runge%27s_phenomenon">Runge's
75       * phenomenon</a> and numerical problems (including NaN appearing).
76       *
77       * @param interpolationPoints number of interpolation points
78       * @param extrapolationThreshold extrapolation threshold beyond which the propagation will fail
79       */
80      public TimeStampedFieldHermiteInterpolator(final int interpolationPoints, final double extrapolationThreshold) {
81          super(interpolationPoints, extrapolationThreshold);
82      }
83  
84      /**
85       * {@inheritDoc}
86       * <p>
87       * As this implementation of interpolation is polynomial, it should be used only with small samples (about 10-20 points)
88       * in order to avoid <a href="http://en.wikipedia.org/wiki/Runge%27s_phenomenon">Runge's phenomenon</a> and numerical
89       * problems (including NaN appearing).
90       */
91      @Override
92      protected TimeStampedField<KK> interpolate(final InterpolationData interpolationData) {
93          final FieldHermiteInterpolator<KK> interpolator = new FieldHermiteInterpolator<>();
94  
95          // Fill interpolator with sample
96          final Field<KK>                  field             = interpolationData.getField();
97          final KK                         zero              = interpolationData.getZero();
98          final FieldAbsoluteDate<KK>      interpolationDate = interpolationData.getInterpolationDate();
99          final List<TimeStampedField<KK>> neighborList      = interpolationData.getNeighborList();
100         for (TimeStampedField<KK> value : neighborList) {
101             final KK   deltaT    = value.getDate().durationFrom(interpolationDate);
102             final KK[] tempArray = MathArrays.buildArray(field, 1);
103             tempArray[0] = value.getValue();
104             interpolator.addSamplePoint(deltaT, tempArray);
105         }
106 
107         return new TimeStampedField<>(interpolator.value(zero)[0], interpolationDate);
108     }
109 }