1   /* Copyright 2002-2026 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.propagation;
18  
19  import org.hipparchus.linear.MatrixUtils;
20  import org.hipparchus.linear.RealMatrix;
21  import org.orekit.orbits.PositionAngleType;
22  import org.orekit.utils.DoubleArrayDictionary;
23  
24  /** Base harvester between two-dimensional Jacobian matrices and one-dimensional {@link
25   * SpacecraftState#getAdditionalState(String) additional state arrays}.
26   * @author Luc Maisonobe
27   * @since 11.1
28   */
29  public abstract class AbstractMatricesHarvester implements MatricesHarvester {
30  
31      /** Default state dimension, equivalent to position and velocity vectors. */
32      public static final int DEFAULT_STATE_DIMENSION = 6;
33  
34      /** State Transition Matrix state name. */
35      private String stmName;
36  
37      /** Initial State Transition Matrix. */
38      private RealMatrix initialStm;
39  
40      /** Initial columns of the Jacobians matrix with respect to parameters. */
41      private DoubleArrayDictionary initialJacobianColumns;
42  
43      /** Empty constructor.
44       * <p>
45       * This constructor is not strictly necessary, but it prevents spurious
46       * javadoc warnings with JDK 18 and later.
47       * </p>
48       * @since 14.0
49       */
50      public AbstractMatricesHarvester() {
51          // nothing to do
52      }
53  
54      /** Set the initial State Transition Matrix.
55       * <p>
56       * The arguments for initial matrices <em>must</em> be compatible with the
57       * {@link org.orekit.orbits.OrbitType orbit type} and
58       * {@link PositionAngleType position angle} that will be used by propagator,
59       * which may be different from input and output
60       * </p>
61       * @param name State Transition Matrix state name
62       * @param stm  initial State Transition Matrix āˆ‚Y/āˆ‚Iā‚€
63       *             if null (which is the most frequent case), input and output
64       *             orbit types are assumed to be identical and the matrix is
65       *             assumed to be the 6x6 identity
66       */
67      protected void setInitialStm(final String name, final RealMatrix stm) {
68          this.stmName    = name;
69          this.initialStm = stm == null ?
70                            MatrixUtils.createRealIdentityMatrix(DEFAULT_STATE_DIMENSION) :
71                            stm;
72      }
73  
74      /** Set the initial columns of the Jacobians matrix with respect to parameters.
75       * <p>
76       * The arguments for initial matrices <em>must</em> be compatible with the
77       * {@link org.orekit.orbits.OrbitType orbit type} and
78       * {@link PositionAngleType position angle} that will be used by propagator
79       * </p>
80       * @param initialJacobianColumns initial columns of the Jacobians matrix with respect to parameters,
81       * if null or if some selected parameters are missing from the dictionary, the corresponding
82       * initial column is assumed to be 0
83       */
84      protected void setInitialJacobianColumns(final DoubleArrayDictionary initialJacobianColumns) {
85          this.initialJacobianColumns = initialJacobianColumns == null ?
86                                        new DoubleArrayDictionary() :
87                                        initialJacobianColumns;
88      }
89  
90      /**
91       * Getter for the state dimension.
92       * @return state dimension
93       * @since 13.1
94       */
95      public int getStateDimension() {
96          return initialStm.getColumnDimension();
97      }
98  
99      /** Get the State Transition Matrix state name.
100      * @return State Transition Matrix state name
101      */
102     public String getStmName() {
103         return stmName;
104     }
105 
106     /** Get the initial State Transition Matrix.
107      * @return initial State Transition Matrix
108      */
109     public RealMatrix getInitialStateTransitionMatrix() {
110         return initialStm;
111     }
112 
113     /** Get the initial column of Jacobian matrix with respect to named parameter.
114      * @param columnName name of the column
115      * @return initial column of the Jacobian matrix
116      */
117     public double[] getInitialJacobianColumn(final String columnName) {
118         final DoubleArrayDictionary.Entry entry = initialJacobianColumns.getEntry(columnName);
119         return entry == null ? new double[getStateDimension()] : entry.getValue();
120     }
121 
122     /** Convert a flattened array to a square matrix.
123      * @param array input array
124      * @return the corresponding matrix
125      * @since 13.1
126      */
127     public RealMatrix toSquareMatrix(final double[] array) {
128         final int stateDimension = getStateDimension();
129         final RealMatrix matrix = MatrixUtils.createRealMatrix(stateDimension, stateDimension);
130         int index = 0;
131         for (int i = 0; i < stateDimension; ++i) {
132             for (int j = 0; j < stateDimension; ++j) {
133                 matrix.setEntry(i, j, array[index++]);
134             }
135         }
136         return matrix;
137     }
138 
139     /** Set the STM data into an array.
140      * @param matrix STM matrix
141      * @return an array containing the STM data
142      * @since 13.1
143      */
144     public double[] toArray(final double[][] matrix) {
145         final int stateDimension = matrix.length;
146         final double[] array = new double[stateDimension * stateDimension];
147         int index = 0;
148         for (final double[] row : matrix) {
149             for (int j = 0; j < stateDimension; ++j) {
150                 array[index++] = row[j];
151             }
152         }
153         return array;
154     }
155 
156     /** {@inheritDoc} */
157     @Override
158     public void setReferenceState(final SpacecraftState reference) {
159         // nothing to do
160     }
161 
162     /** Freeze the names of the Jacobian columns.
163      * <p>
164      * This method is called when propagation starts, i.e. when configuration is completed
165      * </p>
166      */
167     public abstract void freezeColumnsNames();
168 
169 }