Flattener.java
- /* Copyright 2002-2025 CS GROUP
- * Licensed to CS GROUP (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.forces.gravity.potential;
- import org.hipparchus.util.FastMath;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitMessages;
- /** Utility for converting between (degree, order) indices and one-dimensional flatten index.
- * <p>
- * The outer loop in {@link org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel}
- * if in decreasing order and the inner loop is in increasing degree (starting
- * from the diagonal). This utility converts (degree, order) indices into a flatten index
- * in a one-dimensional array that increases as these loops are performed.
- * This means the first element of the one-dimensional array corresponds to diagonal
- * element at maximum order and the last element corresponds to order 0 and maximum degree.
- * </p>
- * @author Luc Maisonobe
- * @since 11.1
- */
- class Flattener {
- /** Degree of the spherical harmonics. */
- private final int degree;
- /** Order of the spherical harmonics. */
- private final int order;
- /** Number of high order cells dropped in the triangular array. */
- private final int dropped;
- /** Simple constructor.
- * @param degree degree of the spherical harmonics
- * @param order order of the spherical harmonics
- */
- Flattener(final int degree, final int order) {
- this.degree = degree;
- this.order = order;
- this.dropped = (degree - order + 1) * (degree - order) / 2;
- }
- /** Get the degree of the spherical harmonics.
- * @return degree of the spherical harmonics
- */
- public int getDegree() {
- return degree;
- }
- /** Get the order of the spherical harmonics.
- * @return order of the spherical harmonics
- */
- public int getOrder() {
- return order;
- }
- /** Convert (degree, order) indices to one-dimensional flatten index.
- * <p>
- * As the outer loop in {@link org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel}
- * if on decreasing order and the inner loop is in increasing degree (starting
- * from the diagonal), the flatten index increases as these loops are performed.
- * </p>
- * @param n degree index (must be within range, otherwise an exception is thrown)
- * @param m order index (must be within range, otherwise an exception is thrown)
- * @return one-dimensional flatten index
- * @see #withinRange(int, int)
- */
- public int index(final int n, final int m) {
- if (!withinRange(n, m)) {
- throw new OrekitException(OrekitMessages.WRONG_DEGREE_OR_ORDER, n, m, degree, order);
- }
- final int dm = degree - m;
- return dm * (dm + 1) / 2 + (n - m) - dropped;
- }
- /** Get the size of a flatten array sufficient to hold all coefficients.
- * @return size of a flatten array sufficient to hold all coefficients
- */
- public int arraySize() {
- return index(degree, 0) + 1;
- }
- /** Check if indices are within range.
- * @param n degree
- * @param m order
- * @return true if indices are within limits, false otherwise
- */
- public boolean withinRange(final int n, final int m) {
- return n >= 0 && n <= degree && m >= 0 && m <= FastMath.min(n, order);
- }
- /** Flatten a triangular array.
- * @param triangular triangular array to flatten
- * @return flatten array
- */
- public double[] flatten(final double[][] triangular) {
- final double[] flat = new double[arraySize()];
- for (int n = 0; n <= getDegree(); ++n) {
- for (int m = 0; m <= FastMath.min(n, getOrder()); ++m) {
- flat[index(n, m)] = triangular[n][m];
- }
- }
- return flat;
- }
- }