1   /* Copyright 2013-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.rugged.utils;
18  
19  import org.hipparchus.exception.LocalizedCoreFormats;
20  import org.orekit.errors.OrekitException;
21  import org.orekit.time.AbsoluteDate;
22  
23  /** AbsoluteDateArrayHandling consist of additions to AbsoluteDate to handle arrays.
24   * @author Melina Vanel
25   */
26  public class AbsoluteDateArrayHandling {
27  
28      /** Dates array on which we want to apply time shift or compute duration. */
29      private final AbsoluteDate[] dates;
30  
31      /** Simple constructor.
32       * @param dates is an array of absolute dates on which we want to apply time shift or
33       * compute duration
34       */
35      public AbsoluteDateArrayHandling(final AbsoluteDate[] dates) {
36          this.dates = dates.clone();
37      }
38  
39      /** Get instance dates array.
40       * @return dates array
41       */
42      public AbsoluteDate[] getDates() {
43          return this.dates.clone();
44      }
45  
46      /** Get time-shifted dates for several dates or several time shifts.
47       * If instance dates = [date1, date2, ..., daten] and argument
48       * dts = [dts1, dts2, ..., dtsn] then this function will return a matrix
49       * [[date1 shiftedby dts1, date1 shiftedBy dts2, ..., date1 shiftedBy dtsn],
50       * [date2 shiftedby dts1, date2 shiftedBy dts2, ..., date2 shiftedBy dtsn],
51       * [...]
52       * [daten shiftedby dts1, daten shiftedBy dts2, ..., date1 shiftedBy dtsn]].
53       * If ones want to apply only 1 time shift corresponding to 1 date see
54       * {@link #shiftedBy(double[])}.
55       * @param dts time shifts array in seconds we want to apply to dates
56       * @return a matrix of new dates, shifted with respect to wanted time
57       * shifts. If instance dates = [date1, date2, ..., daten] each line
58       * correspond to one date (for example date1 shiftedBy all timeshifts
59       * (building the different columns))
60       */
61      public AbsoluteDate[][] multipleShiftedBy(final double[] dts) {
62  
63          final AbsoluteDate[][] datesShifted = new AbsoluteDate[dates.length][dts.length];
64          int index_dates = 0;
65  
66          for (AbsoluteDate date: this.dates) {
67              final AbsoluteDate[] dateShifted = new AbsoluteDate[dts.length];
68              int index_dts = 0;
69              for (double dt: dts) {
70                  dateShifted[index_dts] = date.shiftedBy(dt);
71                  index_dts += 1;
72              }
73              datesShifted[index_dates] = dateShifted;
74              index_dates += 1;
75  
76          }
77          return (AbsoluteDate[][]) datesShifted;
78      }
79  
80      /** Get time-shifted dates for several dates and corresponding time shifts.
81       * If instance dates = [date1, date2, ..., daten] and argument
82       * dts = [dts1, dts2, ..., dtsn] then this function will return
83       * [date1 shiftedby dts1, date2 shiftedBy dts2, ..., daten shiftedBy dtsn]. If
84       * several time shift want to be applied on each date see
85       * {@link #multipleShiftedBy(double[])}.
86       * @param dts time shifts array in seconds we want to apply to corresponding dates.
87       * Warning, must be same length as dates.
88       * @return an 1D array of new dates, shifted with respect to wanted corresponding time
89       * shifts.
90       */
91      public AbsoluteDate[] shiftedBy(final double[] dts) {
92  
93          // Check same dimensions
94          if (dates.length != dts.length) {
95              throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
96                                        dates.length, dts.length);
97          }
98  
99          final AbsoluteDate[] datesShifted = new AbsoluteDate[dates.length];
100         int index_dates = 0;
101 
102         for (AbsoluteDate date: this.dates) {
103             datesShifted[index_dates] = date.shiftedBy(dts[index_dates]);
104             index_dates += 1;
105 
106         }
107         return datesShifted;
108     }
109 
110     /** Get array with durations between instances dates and given dates
111      * If instance dates = [date1, date2, ..., daten] and argument
112      * datesForDuration = [d1, d2, ..., dn] then this function will return a matrix
113      * [[date1 durationFrom d1, date1 durationFrom d2, ..., date1 durationFrom dn],
114      * [date2 durationFrom d1, date2 durationFrom d2, ..., date2 durationFrom dn],
115      * [...]
116      * [daten durationFrom d1, daten durationFrom d2, ..., date1 durationFrom dn]].
117      * If ones want to compute duration from only 1 date corresponding to 1 instance date see
118      * {@link #durationFrom(AbsoluteDate[])}.
119      * @param datesForDuration dates for which we want to compute the duration form instances dates
120      * @return a matrix of double representing durations from instance dates
121      * If instance dates = [date1, date2, ..., daten] each line
122      * correspond to one date (for example date1 duration from all given dates in arguments
123      * (building the different columns))
124      */
125     public double[][] multipleDurationFrom(final AbsoluteDate[] datesForDuration) {
126 
127         final double[][] durationsFromDates = new double[dates.length][datesForDuration.length];
128         int index_dates = 0;
129 
130         for (AbsoluteDate date: this.dates) {
131             final double[] durationFromDate = new double[datesForDuration.length];
132             int index_datesForDuration = 0;
133             for (AbsoluteDate dateForDuration: datesForDuration) {
134                 durationFromDate[index_datesForDuration] = date.durationFrom(dateForDuration);
135                 index_datesForDuration += 1;
136             }
137             durationsFromDates[index_dates] = durationFromDate;
138             index_dates += 1;
139 
140         }
141         return (double[][]) durationsFromDates;
142     }
143 
144     /** Get array with durations between instances dates and corresponding given dates
145      * If instance dates = [date1, date2, ..., daten] and argument
146      * datesForDuration = [d1, d2, ..., dn] then this function will return
147      * [date1 durationFrom d1, date2 durationFrom d2, ..., daten durationFrom dn]. If
148      * duration from from all arguments dates wants to be compute on each date see
149      * {@link #multipleDurationFrom(AbsoluteDate[])}.
150      * @param datesForDuration dates for which we want to compute the duration form instances dates.
151      * Warning must have same length as instance dates.
152      * @return a array of double representing durations between instance dates and corresponding
153      * argument dates
154      */
155     public double[] durationFrom(final AbsoluteDate[] datesForDuration) {
156 
157         // Check same dimensions
158         if (dates.length != datesForDuration.length) {
159             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
160                                       dates.length, datesForDuration.length);
161         }
162 
163         final double[] durationsFromDates = new double[dates.length];
164         int index_dates = 0;
165 
166         for (AbsoluteDate date: this.dates) {
167             durationsFromDates[index_dates] = date.durationFrom(datesForDuration[index_dates]);
168             index_dates += 1;
169 
170         }
171         return durationsFromDates;
172     }
173 
174 }