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.utils;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.analysis.differentiation.DSFactory;
22  import org.hipparchus.analysis.differentiation.DerivativeStructure;
23  import org.hipparchus.analysis.differentiation.FieldDerivativeStructure;
24  import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative1;
25  import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
26  import org.hipparchus.complex.Complex;
27  import org.hipparchus.complex.ComplexField;
28  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
29  import org.hipparchus.geometry.euclidean.threed.Vector3D;
30  import org.hipparchus.util.Binary64;
31  import org.hipparchus.util.Binary64Field;
32  import org.junit.jupiter.api.Assertions;
33  import org.junit.jupiter.api.BeforeEach;
34  import org.junit.jupiter.api.Test;
35  import org.orekit.Utils;
36  import org.orekit.time.AbsoluteDate;
37  import org.orekit.time.FieldAbsoluteDate;
38  import org.orekit.time.FieldTimeStamped;
39  
40  
41  public class TimeStampedFieldPVCoordinatesTest {
42  
43      @Test
44      public void testLinearConstructors() {
45          DSFactory factory = new DSFactory(6, 1);
46          TimeStampedFieldPVCoordinates<DerivativeStructure> pv1 =
47                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.CCSDS_EPOCH,
48                                                      createVector( 1,  0.1, 10, 6),
49                                                      createVector(-1, -0.1, -10, 6),
50                                                      createVector(10,  1.0, 100, 6));
51          TimeStampedFieldPVCoordinates<DerivativeStructure> pv2 =
52                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.FIFTIES_EPOCH,
53                                                      createVector( 2,  0.2,  20, 6),
54                                                      createVector(-2, -0.2, -20, 6),
55                                                      createVector(20,  2.0, 200, 6));
56          TimeStampedFieldPVCoordinates<DerivativeStructure> pv3 =
57                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.GALILEO_EPOCH,
58                                                      createVector( 3,  0.3,  30, 6),
59                                                      createVector(-3, -0.3, -30, 6),
60                                                      createVector(30,  3.0, 300, 6));
61          TimeStampedFieldPVCoordinates<DerivativeStructure> pv4 =
62                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.JULIAN_EPOCH,
63                                                      createVector( 4,  0.4,  40, 6),
64                                                      createVector(-4, -0.4, -40, 6),
65                                                      createVector(40,  4.0, 400, 6));
66          checkPV(pv4, new TimeStampedFieldPVCoordinates<>(AbsoluteDate.JULIAN_EPOCH, 4, pv1), 1.0e-15);
67          checkPV(pv4, new TimeStampedFieldPVCoordinates<>(AbsoluteDate.JULIAN_EPOCH, factory.constant(4), pv1), 1.0e-15);
68          checkPV(pv4, new TimeStampedFieldPVCoordinates<>(AbsoluteDate.JULIAN_EPOCH, factory.constant(4), pv1.toPVCoordinates()), 1.0e-15);
69          checkPV(pv2, new TimeStampedFieldPVCoordinates<>(AbsoluteDate.FIFTIES_EPOCH, pv1, pv3), 1.0e-15);
70          checkPV(pv3, new TimeStampedFieldPVCoordinates<>(AbsoluteDate.GALILEO_EPOCH, 1, pv1, 1, pv2), 1.0e-15);
71          checkPV(pv3,
72                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.GALILEO_EPOCH,
73                                                      factory.constant(1), pv1,
74                                                      factory.constant(1), pv2),
75                  1.0e-15);
76          checkPV(pv3,
77                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.GALILEO_EPOCH,
78                                                      factory.constant(1), pv1.toPVCoordinates(),
79                                                      factory.constant(1), pv2.toPVCoordinates()),
80                  1.0e-15);
81          checkPV(new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 2, pv4),
82                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 3, pv1, 1, pv2, 1, pv3),
83                  1.0e-15);
84          checkPV(new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 3, pv3),
85                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 3, pv1, 1, pv2, 1, pv4),
86                  1.0e-15);
87          checkPV(new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 3, pv3),
88                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH,
89                                                      factory.constant(3), pv1,
90                                                      factory.constant(1), pv2,
91                                                      factory.constant(1), pv4),
92                  1.0e-15);
93          checkPV(new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 3, pv3),
94                  new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH,
95                                                      factory.constant(3), pv1.toPVCoordinates(),
96                                                      factory.constant(1), pv2.toPVCoordinates(),
97                                                      factory.constant(1), pv4.toPVCoordinates()),
98                  1.0e-15);
99          checkPV(new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 5, pv4),
100                 new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 4, pv1, 3, pv2, 2, pv3, 1, pv4), 1.0e-15);
101         checkPV(new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 5, pv4),
102                 new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH,
103                                                     factory.constant(4), pv1,
104                                                     factory.constant(3), pv2,
105                                                     factory.constant(2), pv3,
106                                                     factory.constant(1), pv4),
107                 1.0e-15);
108         checkPV(new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, 5, pv4),
109                 new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH,
110                                                     factory.constant(4), pv1.toPVCoordinates(),
111                                                     factory.constant(3), pv2.toPVCoordinates(),
112                                                     factory.constant(2), pv3.toPVCoordinates(),
113                                                     factory.constant(1), pv4.toPVCoordinates()),
114                 1.0e-15);
115     }
116 
117     @Test
118     public void testToDerivativeStructureVector1() {
119         FieldVector3D<FieldDerivativeStructure<Binary64>> fv =
120                 new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
121                                                     new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
122                                                     new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
123                                                     new FieldVector3D<>(new Binary64(10), new Binary64(-1.0), new Binary64(-100))).
124                 toDerivativeStructureVector(1);
125         Assertions.assertEquals(1, fv.getX().getFreeParameters());
126         Assertions.assertEquals(1, fv.getX().getOrder());
127         Assertions.assertEquals(   1.0, fv.getX().getReal(), 1.0e-10);
128         Assertions.assertEquals(   0.1, fv.getY().getReal(), 1.0e-10);
129         Assertions.assertEquals(  10.0, fv.getZ().getReal(), 1.0e-10);
130         Assertions.assertEquals(  -1.0, fv.getX().getPartialDerivative(1).doubleValue(), 1.0e-15);
131         Assertions.assertEquals(  -0.1, fv.getY().getPartialDerivative(1).doubleValue(), 1.0e-15);
132         Assertions.assertEquals( -10.0, fv.getZ().getPartialDerivative(1).doubleValue(), 1.0e-15);
133         checkPV(new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
134                                                     new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
135                                                     new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
136                                                     FieldVector3D.getZero(Binary64Field.getInstance())),
137                 new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()), fv), 1.0e-15);
138 
139         for (double dt = 0; dt < 10; dt += 0.125) {
140             FieldVector3D<Binary64> p = new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
141                                                                   new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10))).
142                             shiftedBy(dt).getPosition();
143             Assertions.assertEquals(p.getX().doubleValue(), fv.getX().taylor(dt).doubleValue(), 1.0e-14);
144             Assertions.assertEquals(p.getY().doubleValue(), fv.getY().taylor(dt).doubleValue(), 1.0e-14);
145             Assertions.assertEquals(p.getZ().doubleValue(), fv.getZ().taylor(dt).doubleValue(), 1.0e-14);
146         }
147 
148         TimeStampedFieldPVCoordinates<Binary64> fpv =
149                         new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
150                                                             fv);
151         Assertions.assertEquals(   1.0, fpv.getPosition().getX().getReal(), 1.0e-10);
152         Assertions.assertEquals(   0.1, fpv.getPosition().getY().getReal(), 1.0e-10);
153         Assertions.assertEquals(  10.0, fpv.getPosition().getZ().getReal(), 1.0e-10);
154         Assertions.assertEquals(  -1.0, fpv.getVelocity().getX().getReal(), 1.0e-15);
155         Assertions.assertEquals(  -0.1, fpv.getVelocity().getY().getReal(), 1.0e-15);
156         Assertions.assertEquals( -10.0, fpv.getVelocity().getZ().getReal(), 1.0e-15);
157 
158     }
159 
160     @Test
161     public void testToDerivativeStructureVector2() {
162         FieldVector3D<FieldDerivativeStructure<Binary64>> fv =
163                 new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
164                                                     new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
165                                                     new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
166                                                     new FieldVector3D<>(new Binary64(10), new Binary64(-1.0), new Binary64(-100))).
167                 toDerivativeStructureVector(2);
168         Assertions.assertEquals(1, fv.getX().getFreeParameters());
169         Assertions.assertEquals(2, fv.getX().getOrder());
170         Assertions.assertEquals(   1.0, fv.getX().getReal(), 1.0e-10);
171         Assertions.assertEquals(   0.1, fv.getY().getReal(), 1.0e-10);
172         Assertions.assertEquals(  10.0, fv.getZ().getReal(), 1.0e-10);
173         Assertions.assertEquals(  -1.0, fv.getX().getPartialDerivative(1).doubleValue(), 1.0e-15);
174         Assertions.assertEquals(  -0.1, fv.getY().getPartialDerivative(1).doubleValue(), 1.0e-15);
175         Assertions.assertEquals( -10.0, fv.getZ().getPartialDerivative(1).doubleValue(), 1.0e-15);
176         Assertions.assertEquals(  10.0, fv.getX().getPartialDerivative(2).doubleValue(), 1.0e-15);
177         Assertions.assertEquals(  -1.0, fv.getY().getPartialDerivative(2).doubleValue(), 1.0e-15);
178         Assertions.assertEquals(-100.0, fv.getZ().getPartialDerivative(2).doubleValue(), 1.0e-15);
179         checkPV(new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
180                                                     new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
181                                                     new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
182                                                     new FieldVector3D<>(new Binary64(10), new Binary64(-1.0), new Binary64(-100))),
183                 new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()), fv), 1.0e-15);
184 
185         for (double dt = 0; dt < 10; dt += 0.125) {
186             FieldVector3D<Binary64> p = new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
187                                                                   new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
188                                                                   new FieldVector3D<>(new Binary64(10), new Binary64(-1.0), new Binary64(-100))).
189                             shiftedBy(dt).getPosition();
190             Assertions.assertEquals(p.getX().doubleValue(), fv.getX().taylor(dt).doubleValue(), 1.0e-14);
191             Assertions.assertEquals(p.getY().doubleValue(), fv.getY().taylor(dt).doubleValue(), 1.0e-14);
192             Assertions.assertEquals(p.getZ().doubleValue(), fv.getZ().taylor(dt).doubleValue(), 1.0e-14);
193         }
194 
195         TimeStampedFieldPVCoordinates<Binary64> fpv =
196                         new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
197                                                             fv);
198         Assertions.assertEquals(   1.0, fpv.getPosition().getX().getReal(), 1.0e-10);
199         Assertions.assertEquals(   0.1, fpv.getPosition().getY().getReal(), 1.0e-10);
200         Assertions.assertEquals(  10.0, fpv.getPosition().getZ().getReal(), 1.0e-10);
201         Assertions.assertEquals(  -1.0, fpv.getVelocity().getX().getReal(), 1.0e-15);
202         Assertions.assertEquals(  -0.1, fpv.getVelocity().getY().getReal(), 1.0e-15);
203         Assertions.assertEquals( -10.0, fpv.getVelocity().getZ().getReal(), 1.0e-15);
204         Assertions.assertEquals(  10.0, fpv.getAcceleration().getX().getReal(), 1.0e-15);
205         Assertions.assertEquals(  -1.0, fpv.getAcceleration().getY().getReal(), 1.0e-15);
206         Assertions.assertEquals(-100.0, fpv.getAcceleration().getZ().getReal(), 1.0e-15);
207 
208     }
209 
210     @Test
211     public void testToUnivariateDerivative1Vector() {
212         FieldVector3D<FieldUnivariateDerivative1<Binary64>> fv =
213                 new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
214                                                     new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
215                                                     new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
216                                                     new FieldVector3D<>(new Binary64(10), new Binary64(-1.0), new Binary64(-100))).
217                 toUnivariateDerivative1Vector();
218         Assertions.assertEquals(1, fv.getX().getFreeParameters());
219         Assertions.assertEquals(1, fv.getX().getOrder());
220         Assertions.assertEquals(   1.0, fv.getX().getReal(), 1.0e-10);
221         Assertions.assertEquals(   0.1, fv.getY().getReal(), 1.0e-10);
222         Assertions.assertEquals(  10.0, fv.getZ().getReal(), 1.0e-10);
223         Assertions.assertEquals(  -1.0, fv.getX().getPartialDerivative(1).doubleValue(), 1.0e-15);
224         Assertions.assertEquals(  -0.1, fv.getY().getPartialDerivative(1).doubleValue(), 1.0e-15);
225         Assertions.assertEquals( -10.0, fv.getZ().getPartialDerivative(1).doubleValue(), 1.0e-15);
226         checkPV(new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
227                                                     new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
228                                                     new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
229                                                     FieldVector3D.getZero(Binary64Field.getInstance())),
230                 new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()), fv), 1.0e-15);
231 
232         for (double dt = 0; dt < 10; dt += 0.125) {
233             FieldVector3D<Binary64> p = new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
234                                                                   new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10))).
235                             shiftedBy(dt).getPosition();
236             Assertions.assertEquals(p.getX().doubleValue(), fv.getX().taylor(dt).doubleValue(), 1.0e-14);
237             Assertions.assertEquals(p.getY().doubleValue(), fv.getY().taylor(dt).doubleValue(), 1.0e-14);
238             Assertions.assertEquals(p.getZ().doubleValue(), fv.getZ().taylor(dt).doubleValue(), 1.0e-14);
239         }
240 
241         TimeStampedFieldPVCoordinates<Binary64> fpv =
242                         new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
243                                                             fv);
244         Assertions.assertEquals(   1.0, fpv.getPosition().getX().getReal(), 1.0e-10);
245         Assertions.assertEquals(   0.1, fpv.getPosition().getY().getReal(), 1.0e-10);
246         Assertions.assertEquals(  10.0, fpv.getPosition().getZ().getReal(), 1.0e-10);
247         Assertions.assertEquals(  -1.0, fpv.getVelocity().getX().getReal(), 1.0e-15);
248         Assertions.assertEquals(  -0.1, fpv.getVelocity().getY().getReal(), 1.0e-15);
249         Assertions.assertEquals( -10.0, fpv.getVelocity().getZ().getReal(), 1.0e-15);
250 
251     }
252 
253     @Test
254     public void testToUnivariateDerivative2Vector() {
255         FieldVector3D<FieldUnivariateDerivative2<Binary64>> fv =
256                 new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
257                                                     new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
258                                                     new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
259                                                     new FieldVector3D<>(new Binary64(10), new Binary64(-1.0), new Binary64(-100))).
260                 toUnivariateDerivative2Vector();
261         Assertions.assertEquals(1, fv.getX().getFreeParameters());
262         Assertions.assertEquals(2, fv.getX().getOrder());
263         Assertions.assertEquals(   1.0, fv.getX().getReal(), 1.0e-10);
264         Assertions.assertEquals(   0.1, fv.getY().getReal(), 1.0e-10);
265         Assertions.assertEquals(  10.0, fv.getZ().getReal(), 1.0e-10);
266         Assertions.assertEquals(  -1.0, fv.getX().getPartialDerivative(1).doubleValue(), 1.0e-15);
267         Assertions.assertEquals(  -0.1, fv.getY().getPartialDerivative(1).doubleValue(), 1.0e-15);
268         Assertions.assertEquals( -10.0, fv.getZ().getPartialDerivative(1).doubleValue(), 1.0e-15);
269         Assertions.assertEquals(  10.0, fv.getX().getPartialDerivative(2).doubleValue(), 1.0e-15);
270         Assertions.assertEquals(  -1.0, fv.getY().getPartialDerivative(2).doubleValue(), 1.0e-15);
271         Assertions.assertEquals(-100.0, fv.getZ().getPartialDerivative(2).doubleValue(), 1.0e-15);
272         checkPV(new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
273                                                     new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
274                                                     new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
275                                                     new FieldVector3D<>(new Binary64(10), new Binary64(-1.0), new Binary64(-100))),
276                 new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()), fv), 1.0e-15);
277 
278         for (double dt = 0; dt < 10; dt += 0.125) {
279             FieldVector3D<Binary64> p = new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64( 1), new Binary64( 0.1), new Binary64( 10)),
280                                                                   new FieldVector3D<>(new Binary64(-1), new Binary64(-0.1), new Binary64(-10)),
281                                                                   new FieldVector3D<>(new Binary64(10), new Binary64(-1.0), new Binary64(-100))).
282                             shiftedBy(dt).getPosition();
283             Assertions.assertEquals(p.getX().doubleValue(), fv.getX().taylor(dt).doubleValue(), 1.0e-14);
284             Assertions.assertEquals(p.getY().doubleValue(), fv.getY().taylor(dt).doubleValue(), 1.0e-14);
285             Assertions.assertEquals(p.getZ().doubleValue(), fv.getZ().taylor(dt).doubleValue(), 1.0e-14);
286         }
287 
288         TimeStampedFieldPVCoordinates<Binary64> fpv =
289                         new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getGalileoEpoch(Binary64Field.getInstance()),
290                                                             fv);
291         Assertions.assertEquals(   1.0, fpv.getPosition().getX().getReal(), 1.0e-10);
292         Assertions.assertEquals(   0.1, fpv.getPosition().getY().getReal(), 1.0e-10);
293         Assertions.assertEquals(  10.0, fpv.getPosition().getZ().getReal(), 1.0e-10);
294         Assertions.assertEquals(  -1.0, fpv.getVelocity().getX().getReal(), 1.0e-15);
295         Assertions.assertEquals(  -0.1, fpv.getVelocity().getY().getReal(), 1.0e-15);
296         Assertions.assertEquals( -10.0, fpv.getVelocity().getZ().getReal(), 1.0e-15);
297         Assertions.assertEquals(  10.0, fpv.getAcceleration().getX().getReal(), 1.0e-15);
298         Assertions.assertEquals(  -1.0, fpv.getAcceleration().getY().getReal(), 1.0e-15);
299         Assertions.assertEquals(-100.0, fpv.getAcceleration().getZ().getReal(), 1.0e-15);
300 
301     }
302 
303     @Test
304     public void testShift() {
305         FieldVector3D<DerivativeStructure> p1 = createVector(  1,  0.1,   10, 4);
306         FieldVector3D<DerivativeStructure> v1 = createVector( -1, -0.1,  -10, 4);
307         FieldVector3D<DerivativeStructure> a1 = createVector( 10,  1.0,  100, 4);
308         FieldVector3D<DerivativeStructure> p2 = createVector(  7,  0.7,   70, 4);
309         FieldVector3D<DerivativeStructure> v2 = createVector(-11, -1.1, -110, 4);
310         FieldVector3D<DerivativeStructure> a2 = createVector( 10,  1.0,  100, 4);
311         checkPV(new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH, p2, v2, a2),
312                 new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH.shiftedBy(1.0), p1, v1, a1).shiftedBy(-1.0), 1.0e-15);
313         Assertions.assertEquals(0.0,
314                             TimeStampedFieldPVCoordinates.estimateVelocity(p1, p2, -1.0).subtract(createVector(-6, -0.6, -60, 4)).getNorm().getReal(),
315                             1.0e-15);
316     }
317 
318     @Test
319     public void testToString() {
320         Utils.setDataRoot("regular-data");
321         TimeStampedFieldPVCoordinates<DerivativeStructure> pv =
322             new TimeStampedFieldPVCoordinates<>(AbsoluteDate.J2000_EPOCH,
323                                                 createVector( 1,  0.1,  10, 4),
324                                                 createVector(-1, -0.1, -10, 4),
325                                                 createVector(10,  1.0, 100, 4));
326         Assertions.assertEquals("{2000-01-01T11:58:55.816, P(1.0, 0.1, 10.0), V(-1.0, -0.1, -10.0), A(10.0, 1.0, 100.0)}", pv.toString());
327     }
328 
329     @Test
330     public void testIssue510() {
331         DSFactory factory = new DSFactory(1, 1);
332         TimeStampedFieldPVCoordinates<DerivativeStructure> pv =
333                         new TimeStampedFieldPVCoordinates<>(FieldAbsoluteDate.getJ2000Epoch(factory.getDerivativeField()),
334                                                             new FieldVector3D<>(factory.constant(10.0),
335                                                                                 factory.constant(20.0),
336                                                                                 factory.constant(30.0)),
337                                                             new FieldVector3D<>(factory.constant(1.0),
338                                                                                 factory.constant(2.0),
339                                                                                 factory.constant(3.0)),
340                                                             FieldVector3D.getZero(factory.getDerivativeField()));
341         DerivativeStructure dt = factory.variable(0, 1.0);
342         TimeStampedFieldPVCoordinates<DerivativeStructure> shifted = pv.shiftedBy(dt);
343         Assertions.assertEquals(1.0, shifted.getDate().durationFrom(pv.getDate()).getPartialDerivative(1), 1.0e-15);
344         Assertions.assertEquals(pv.getVelocity().getX().getValue(), shifted.getPosition().getX().getPartialDerivative(1), 1.0e-15);
345         Assertions.assertEquals(pv.getVelocity().getY().getValue(), shifted.getPosition().getY().getPartialDerivative(1), 1.0e-15);
346         Assertions.assertEquals(pv.getVelocity().getZ().getValue(), shifted.getPosition().getZ().getPartialDerivative(1), 1.0e-15);
347 
348     }
349 
350     @Test
351     void testFromTimeStampedPVCoordinates() {
352         // GIVEN
353         final ComplexField field = ComplexField.getInstance();
354         final Vector3D position = Vector3D.MINUS_I;
355         final Vector3D velocity = Vector3D.PLUS_K;
356         final AbsoluteDate date = AbsoluteDate.ARBITRARY_EPOCH;
357         final TimeStampedPVCoordinates expectedPV = new TimeStampedPVCoordinates(date, position, velocity);
358         // WHEN
359         final TimeStampedFieldPVCoordinates<Complex> fieldPV = new TimeStampedFieldPVCoordinates<>(field, expectedPV);
360         // THEN
361         Assertions.assertEquals(expectedPV.getDate(), fieldPV.getDate().toAbsoluteDate());
362         Assertions.assertEquals(expectedPV.getPosition(), fieldPV.getPosition().toVector3D());
363         Assertions.assertEquals(expectedPV.getVelocity(), fieldPV.getVelocity().toVector3D());
364         Assertions.assertEquals(expectedPV.getAcceleration(), fieldPV.getAcceleration().toVector3D());
365     }
366 
367     @Test
368     public void testIssue774() {
369         doTestIssue774(Binary64Field.getInstance());
370     }
371 
372     private <T extends CalculusFieldElement<T>> void doTestIssue774(final Field<T> field) {
373 
374         final T zero = field.getZero();
375 
376         // Epoch
377         final FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field);
378 
379         // Coordinates
380         final FieldPVCoordinates<T> pv =
381                         new FieldPVCoordinates<T>(new FieldVector3D<T>(zero, zero, zero),
382                                                   new FieldVector3D<T>(zero, zero, zero));
383 
384         // Time stamped object
385         final FieldTimeStamped<T> timeStamped =
386                         new TimeStampedFieldPVCoordinates<>(date, pv);
387 
388         // Verify
389         Assertions.assertEquals(0.0, date.durationFrom(timeStamped.getDate()).getReal(), Double.MIN_VALUE);
390     }
391 
392     private <T extends CalculusFieldElement<T>> void checkPV(TimeStampedFieldPVCoordinates<T> expected,
393                                                          TimeStampedFieldPVCoordinates<T> real, double epsilon) {
394         Assertions.assertEquals(expected.getDate(), real.getDate());
395         Assertions.assertEquals(expected.getPosition().getX().getReal(),     real.getPosition().getX().getReal(), epsilon);
396         Assertions.assertEquals(expected.getPosition().getY().getReal(),     real.getPosition().getY().getReal(), epsilon);
397         Assertions.assertEquals(expected.getPosition().getZ().getReal(),     real.getPosition().getZ().getReal(), epsilon);
398         Assertions.assertEquals(expected.getVelocity().getX().getReal(),     real.getVelocity().getX().getReal(), epsilon);
399         Assertions.assertEquals(expected.getVelocity().getY().getReal(),     real.getVelocity().getY().getReal(), epsilon);
400         Assertions.assertEquals(expected.getVelocity().getZ().getReal(),     real.getVelocity().getZ().getReal(), epsilon);
401         Assertions.assertEquals(expected.getAcceleration().getX().getReal(), real.getAcceleration().getX().getReal(), epsilon);
402         Assertions.assertEquals(expected.getAcceleration().getY().getReal(), real.getAcceleration().getY().getReal(), epsilon);
403         Assertions.assertEquals(expected.getAcceleration().getZ().getReal(), real.getAcceleration().getZ().getReal(), epsilon);
404     }
405 
406     public static FieldVector3D<DerivativeStructure> createVector(double x, double y, double z, int params) {
407         DSFactory factory = new DSFactory(params, 1);
408         return new FieldVector3D<>(factory.variable(0, x),
409                                    factory.variable(1, y),
410                                    factory.variable(2, z));
411     }
412 
413     @BeforeEach
414     public void setUp() {
415         Utils.setDataRoot("regular-data");
416     }
417 
418 }