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