diff --git a/src/main/java/org/orekit/rugged/adjustment/GroundOptimizationProblemBuilder.java b/src/main/java/org/orekit/rugged/adjustment/GroundOptimizationProblemBuilder.java index 23a7d40378c7b4aeed9bbc83e6fd770d1e6f0adb..ec9c758d51204f1173054fd1cdff99c07365274d 100644 --- a/src/main/java/org/orekit/rugged/adjustment/GroundOptimizationProblemBuilder.java +++ b/src/main/java/org/orekit/rugged/adjustment/GroundOptimizationProblemBuilder.java @@ -21,7 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Gradient; import org.hipparchus.linear.Array2DRowRealMatrix; import org.hipparchus.linear.ArrayRealVector; import org.hipparchus.linear.RealMatrix; @@ -162,7 +162,7 @@ public class GroundOptimizationProblemBuilder extends OptimizationProblemBuilder for (final SensorToGroundMapping reference : this.sensorToGroundMappings) { for (final Map.Entry<SensorPixel, GeodeticPoint> mapping : reference.getMapping()) { final GeodeticPoint gp = mapping.getValue(); - final DerivativeStructure[] ilResult = this.rugged.inverseLocationDerivatives(reference.getSensorName(), gp, minLine, maxLine, this.getGenerator()); + final Gradient[] ilResult = this.rugged.inverseLocationDerivatives(reference.getSensorName(), gp, minLine, maxLine, this.getGenerator()); if (ilResult == null) { value.setEntry(l, minLine - 100.0); // arbitrary diff --git a/src/main/java/org/orekit/rugged/adjustment/InterSensorsOptimizationProblemBuilder.java b/src/main/java/org/orekit/rugged/adjustment/InterSensorsOptimizationProblemBuilder.java index 13d69958ce7429762be4a0d0c654ae93b1b44487..4f6b98308a3df3297a4ce9fbac54a38af11df927 100644 --- a/src/main/java/org/orekit/rugged/adjustment/InterSensorsOptimizationProblemBuilder.java +++ b/src/main/java/org/orekit/rugged/adjustment/InterSensorsOptimizationProblemBuilder.java @@ -24,7 +24,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Gradient; import org.hipparchus.linear.Array2DRowRealMatrix; import org.hipparchus.linear.ArrayRealVector; import org.hipparchus.linear.RealMatrix; @@ -207,7 +207,7 @@ public class InterSensorsOptimizationProblemBuilder extends OptimizationProblemB final SpacecraftToObservedBody scToBodyA = ruggedA.getScToBody(); - final DerivativeStructure[] ilResult = + final Gradient[] ilResult = ruggedB.distanceBetweenLOSderivatives(lineSensorA, dateA, pixelA, scToBodyA, lineSensorB, dateB, pixelB, this.getGenerator()); diff --git a/src/main/java/org/orekit/rugged/adjustment/OptimizationProblemBuilder.java b/src/main/java/org/orekit/rugged/adjustment/OptimizationProblemBuilder.java index 421e23e39c7dd6d1e338ea8a2bfe842291afd2fc..1dd9945076f6ff4c88170f67045aec3fe29ee375 100644 --- a/src/main/java/org/orekit/rugged/adjustment/OptimizationProblemBuilder.java +++ b/src/main/java/org/orekit/rugged/adjustment/OptimizationProblemBuilder.java @@ -24,8 +24,9 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.hipparchus.analysis.differentiation.DSFactory; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.Field; +import org.hipparchus.analysis.differentiation.Gradient; +import org.hipparchus.analysis.differentiation.GradientField; import org.hipparchus.optim.ConvergenceChecker; import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresProblem; import org.hipparchus.optim.nonlinear.vector.leastsquares.MultivariateJacobianFunction; @@ -34,7 +35,7 @@ import org.orekit.rugged.adjustment.measurements.Observables; import org.orekit.rugged.errors.RuggedException; import org.orekit.rugged.errors.RuggedMessages; import org.orekit.rugged.linesensor.LineSensor; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.utils.ParameterDriver; /** @@ -51,8 +52,8 @@ abstract class OptimizationProblemBuilder { /** Margin used in parameters estimation for the inverse location lines range. */ protected static final int ESTIMATION_LINE_RANGE_MARGIN = 100; - /** Derivative structure generator.*/ - private final DSGenerator generator; + /** Gradient generator.*/ + private final DerivativeGenerator<Gradient> generator; /** Parameter drivers list. */ private final List<ParameterDriver> drivers; @@ -151,11 +152,11 @@ abstract class OptimizationProblemBuilder { return validator; } - /** Create the generator for {@link DerivativeStructure} instances. + /** Create the generator for {@link Gradient} instances. * @param selectedSensors list of sensors referencing the parameters drivers * @return a new generator */ - private DSGenerator createGenerator(final List<LineSensor> selectedSensors) { + private DerivativeGenerator<Gradient> createGenerator(final List<LineSensor> selectedSensors) { // Initialize set of drivers name final Set<String> names = new HashSet<>(); @@ -188,10 +189,9 @@ abstract class OptimizationProblemBuilder { }); } - final DSFactory factory = new DSFactory(map.size(), 1); - - // Derivative Structure Generator - return new DSGenerator() { + // gradient Generator + final GradientField field = GradientField.getField(map.size()); + return new DerivativeGenerator<Gradient>() { /** {@inheritDoc} */ @Override @@ -201,21 +201,27 @@ abstract class OptimizationProblemBuilder { /** {@inheritDoc} */ @Override - public DerivativeStructure constant(final double value) { - return factory.constant(value); + public Gradient constant(final double value) { + return Gradient.constant(map.size(), value); } /** {@inheritDoc} */ @Override - public DerivativeStructure variable(final ParameterDriver driver) { - + public Gradient variable(final ParameterDriver driver) { final Integer index = map.get(driver.getName()); if (index == null) { return constant(driver.getValue()); } else { - return factory.variable(index.intValue(), driver.getValue()); + return Gradient.variable(map.size(), index.intValue(), driver.getValue()); } } + + /** {@inheritDoc} */ + @Override + public Field<Gradient> getField() { + return field; + } + }; } @@ -245,7 +251,7 @@ abstract class OptimizationProblemBuilder { * Get the derivative structure generator. * @return the derivative structure generator. */ - protected final DSGenerator getGenerator() { + protected final DerivativeGenerator<Gradient> getGenerator() { return this.generator; } diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java index 57fd79bbeb701b67f91e483b65ac63d4074fe2ef..a7f3890a9d6304ed50be475e160bb91f0e7b3fe6 100644 --- a/src/main/java/org/orekit/rugged/api/Rugged.java +++ b/src/main/java/org/orekit/rugged/api/Rugged.java @@ -20,10 +20,12 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.analysis.differentiation.DerivativeStructure; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.FastMath; +import org.hipparchus.util.MathArrays; import org.orekit.bodies.GeodeticPoint; import org.orekit.frames.Transform; import org.orekit.rugged.errors.DumpManager; @@ -36,7 +38,7 @@ import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing; import org.orekit.rugged.linesensor.SensorPixel; import org.orekit.rugged.linesensor.SensorPixelCrossing; import org.orekit.rugged.refraction.AtmosphericRefraction; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.rugged.utils.ExtendedEllipsoid; import org.orekit.rugged.utils.NormalizedGeodeticPoint; import org.orekit.rugged.utils.SpacecraftToObservedBody; @@ -944,6 +946,7 @@ public class Rugged { } /** Compute distances between two line sensors with derivatives. + * @param <T> derivative type * @param sensorA line sensor A * @param dateA current date for sensor A * @param pixelA pixel index for sensor A @@ -955,11 +958,11 @@ public class Rugged { * @return distances computed, with derivatives, between LOS and to the ground * @see #distanceBetweenLOS(LineSensor, AbsoluteDate, double, SpacecraftToObservedBody, LineSensor, AbsoluteDate, double) */ - public DerivativeStructure[] distanceBetweenLOSderivatives( + public <T extends Derivative<T>> T[] distanceBetweenLOSderivatives( final LineSensor sensorA, final AbsoluteDate dateA, final double pixelA, final SpacecraftToObservedBody scToBodyA, final LineSensor sensorB, final AbsoluteDate dateB, final double pixelB, - final DSGenerator generator) { + final DerivativeGenerator<T> generator) { // Compute the approximate transforms between spacecraft and observed body // from Rugged instance A @@ -973,59 +976,63 @@ public class Rugged { final Transform transformScToBodyB = new Transform(dateB, scToInertB, inertToBodyB); // Get sensors LOS into local frame - final FieldVector3D<DerivativeStructure> vALocal = sensorA.getLOSDerivatives(dateA, pixelA, generator); - final FieldVector3D<DerivativeStructure> vBLocal = sensorB.getLOSDerivatives(dateB, pixelB, generator); + final FieldVector3D<T> vALocal = sensorA.getLOSDerivatives(dateA, pixelA, generator); + final FieldVector3D<T> vBLocal = sensorB.getLOSDerivatives(dateB, pixelB, generator); // Get sensors LOS into body frame - final FieldVector3D<DerivativeStructure> vA = transformScToBodyA.transformVector(vALocal); // V_a : line of sight's vectorA - final FieldVector3D<DerivativeStructure> vB = transformScToBodyB.transformVector(vBLocal); // V_b : line of sight's vectorB + final FieldVector3D<T> vA = transformScToBodyA.transformVector(vALocal); // V_a : line of sight's vectorA + final FieldVector3D<T> vB = transformScToBodyB.transformVector(vBLocal); // V_b : line of sight's vectorB // Position of sensors into local frame final Vector3D sAtmp = sensorA.getPosition(); final Vector3D sBtmp = sensorB.getPosition(); - final DerivativeStructure scaleFactor = FieldVector3D.dotProduct(vA.normalize(), vA.normalize()); // V_a.V_a=1 + final T scaleFactor = FieldVector3D.dotProduct(vA.normalize(), vA.normalize()); // V_a.V_a=1 // Build a vector from the position and a scale factor (equals to 1). // The vector built will be scaleFactor * sAtmp for example. - final FieldVector3D<DerivativeStructure> sALocal = new FieldVector3D<DerivativeStructure>(scaleFactor, sAtmp); - final FieldVector3D<DerivativeStructure> sBLocal = new FieldVector3D<DerivativeStructure>(scaleFactor, sBtmp); + final FieldVector3D<T> sALocal = new FieldVector3D<>(scaleFactor, sAtmp); + final FieldVector3D<T> sBLocal = new FieldVector3D<>(scaleFactor, sBtmp); // Get sensors position into body frame - final FieldVector3D<DerivativeStructure> sA = transformScToBodyA.transformPosition(sALocal); // S_a : sensorA 's position - final FieldVector3D<DerivativeStructure> sB = transformScToBodyB.transformPosition(sBLocal); // S_b : sensorB 's position + final FieldVector3D<T> sA = transformScToBodyA.transformPosition(sALocal); // S_a : sensorA 's position + final FieldVector3D<T> sB = transformScToBodyB.transformPosition(sBLocal); // S_b : sensorB 's position // Compute distance - final FieldVector3D<DerivativeStructure> vBase = sB.subtract(sA); // S_b - S_a - final DerivativeStructure svA = FieldVector3D.dotProduct(vBase, vA); // SV_a = (S_b - S_a).V_a - final DerivativeStructure svB = FieldVector3D.dotProduct(vBase, vB); // SV_b = (S_b - S_a).V_b + final FieldVector3D<T> vBase = sB.subtract(sA); // S_b - S_a + final T svA = FieldVector3D.dotProduct(vBase, vA); // SV_a = (S_b - S_a).V_a + final T svB = FieldVector3D.dotProduct(vBase, vB); // SV_b = (S_b - S_a).V_b - final DerivativeStructure vAvB = FieldVector3D.dotProduct(vA, vB); // V_a.V_b + final T vAvB = FieldVector3D.dotProduct(vA, vB); // V_a.V_b // Compute lambda_b = (SV_a * V_a.V_b - SV_b) / (1 - (V_a.V_b)²) - final DerivativeStructure lambdaB = (svA.multiply(vAvB).subtract(svB)).divide(vAvB.multiply(vAvB).subtract(1).negate()); + final T lambdaB = (svA.multiply(vAvB).subtract(svB)).divide(vAvB.multiply(vAvB).subtract(1).negate()); // Compute lambda_a = SV_a + lambdaB * V_a.V_b - final DerivativeStructure lambdaA = vAvB.multiply(lambdaB).add(svA); + final T lambdaA = vAvB.multiply(lambdaB).add(svA); // Compute vector M_a: - final FieldVector3D<DerivativeStructure> mA = sA.add(vA.scalarMultiply(lambdaA)); // M_a = S_a + lambda_a * V_a + final FieldVector3D<T> mA = sA.add(vA.scalarMultiply(lambdaA)); // M_a = S_a + lambda_a * V_a // Compute vector M_b - final FieldVector3D<DerivativeStructure> mB = sB.add(vB.scalarMultiply(lambdaB)); // M_b = S_b + lambda_b * V_b + final FieldVector3D<T> mB = sB.add(vB.scalarMultiply(lambdaB)); // M_b = S_b + lambda_b * V_b // Compute vector M_a -> M_B for which distance between LOS is minimum - final FieldVector3D<DerivativeStructure> vDistanceMin = mB.subtract(mA); // M_b - M_a + final FieldVector3D<T> vDistanceMin = mB.subtract(mA); // M_b - M_a // Compute vector from mid point of vector M_a -> M_B to the ground (corresponds to minimum elevation) - final FieldVector3D<DerivativeStructure> midPoint = (mB.add(mA)).scalarMultiply(0.5); + final FieldVector3D<T> midPoint = (mB.add(mA)).scalarMultiply(0.5); // Get the euclidean norms to compute the minimum distances: // between LOS - final DerivativeStructure dMin = vDistanceMin.getNorm(); + final T dMin = vDistanceMin.getNorm(); // to the ground - final DerivativeStructure dCentralBody = midPoint.getNorm(); + final T dCentralBody = midPoint.getNorm(); + + final T[] ret = MathArrays.buildArray(dMin.getField(), 2); + ret[0] = dMin; + ret[1] = dCentralBody; + return ret; - return new DerivativeStructure[] {dMin, dCentralBody}; } @@ -1066,22 +1073,22 @@ public class Rugged { } /** Inverse location of a point with derivatives. + * @param <T> derivative type * @param sensorName name of the line sensor * @param point point to localize * @param minLine minimum line number * @param maxLine maximum line number - * @param generator generator to use for building {@link DerivativeStructure} instances + * @param generator generator to use for building {@link Derivative} instances * @return sensor pixel seeing point with derivatives, or null if point cannot be seen between the * prescribed line numbers * @see #inverseLocation(String, GeodeticPoint, int, int) * @since 2.0 */ - - public DerivativeStructure[] inverseLocationDerivatives(final String sensorName, - final GeodeticPoint point, - final int minLine, - final int maxLine, - final DSGenerator generator) { + public <T extends Derivative<T>> T[] inverseLocationDerivatives(final String sensorName, + final GeodeticPoint point, + final int minLine, + final int maxLine, + final DerivativeGenerator<T> generator) { final LineSensor sensor = getLineSensor(sensorName); @@ -1109,37 +1116,39 @@ public class Rugged { // fix line by considering the closest pixel exact position and line-of-sight // (this pixel might point towards a direction slightly above or below the mean sensor plane) final int lowIndex = FastMath.max(0, FastMath.min(sensor.getNbPixels() - 2, (int) FastMath.floor(coarsePixel))); - final FieldVector3D<DerivativeStructure> lowLOS = + final FieldVector3D<T> lowLOS = sensor.getLOSDerivatives(crossingResult.getDate(), lowIndex, generator); - final FieldVector3D<DerivativeStructure> highLOS = sensor.getLOSDerivatives(crossingResult.getDate(), lowIndex + 1, generator); - final FieldVector3D<DerivativeStructure> localZ = FieldVector3D.crossProduct(lowLOS, highLOS).normalize(); - final DerivativeStructure beta = FieldVector3D.dotProduct(crossingResult.getTargetDirection(), localZ).acos(); - final DerivativeStructure s = FieldVector3D.dotProduct(crossingResult.getTargetDirectionDerivative(), localZ); - final DerivativeStructure minusBetaDer = s.divide(s.multiply(s).subtract(1).negate().sqrt()); - final DerivativeStructure deltaL = beta.subtract(0.5 * FastMath.PI) .divide(minusBetaDer); - final DerivativeStructure fixedLine = deltaL.add(crossingResult.getLine()); - final FieldVector3D<DerivativeStructure> fixedDirection = - new FieldVector3D<DerivativeStructure>(deltaL.getField().getOne(), crossingResult.getTargetDirection(), - deltaL, crossingResult.getTargetDirectionDerivative()).normalize(); + final FieldVector3D<T> highLOS = sensor.getLOSDerivatives(crossingResult.getDate(), lowIndex + 1, generator); + final FieldVector3D<T> localZ = FieldVector3D.crossProduct(lowLOS, highLOS).normalize(); + final T beta = FieldVector3D.dotProduct(crossingResult.getTargetDirection(), localZ).acos(); + final T s = FieldVector3D.dotProduct(crossingResult.getTargetDirectionDerivative(), localZ); + final T minusBetaDer = s.divide(s.multiply(s).subtract(1).negate().sqrt()); + final T deltaL = beta.subtract(0.5 * FastMath.PI) .divide(minusBetaDer); + final T fixedLine = deltaL.add(crossingResult.getLine()); + final FieldVector3D<T> fixedDirection = + new FieldVector3D<>(deltaL.getField().getOne(), crossingResult.getTargetDirection(), + deltaL, crossingResult.getTargetDirectionDerivative()).normalize(); // fix neighbouring pixels final AbsoluteDate fixedDate = sensor.getDate(fixedLine.getValue()); - final FieldVector3D<DerivativeStructure> fixedX = sensor.getLOSDerivatives(fixedDate, lowIndex, generator); - final FieldVector3D<DerivativeStructure> fixedZ = FieldVector3D.crossProduct(fixedX, sensor.getLOSDerivatives(fixedDate, lowIndex + 1, generator)); - final FieldVector3D<DerivativeStructure> fixedY = FieldVector3D.crossProduct(fixedZ, fixedX); + final FieldVector3D<T> fixedX = sensor.getLOSDerivatives(fixedDate, lowIndex, generator); + final FieldVector3D<T> fixedZ = FieldVector3D.crossProduct(fixedX, sensor.getLOSDerivatives(fixedDate, lowIndex + 1, generator)); + final FieldVector3D<T> fixedY = FieldVector3D.crossProduct(fixedZ, fixedX); // fix pixel - final DerivativeStructure hY = FieldVector3D.dotProduct(highLOS, fixedY); - final DerivativeStructure hX = FieldVector3D.dotProduct(highLOS, fixedX); - final DerivativeStructure pixelWidth = hY.atan2(hX); - final DerivativeStructure fY = FieldVector3D.dotProduct(fixedDirection, fixedY); - final DerivativeStructure fX = FieldVector3D.dotProduct(fixedDirection, fixedX); - final DerivativeStructure alpha = fY.atan2(fX); - final DerivativeStructure fixedPixel = alpha.divide(pixelWidth).add(lowIndex); - - return new DerivativeStructure[] { - fixedLine, fixedPixel - }; + final T hY = FieldVector3D.dotProduct(highLOS, fixedY); + final T hX = FieldVector3D.dotProduct(highLOS, fixedX); + final T pixelWidth = hY.atan2(hX); + final T fY = FieldVector3D.dotProduct(fixedDirection, fixedY); + final T fX = FieldVector3D.dotProduct(fixedDirection, fixedX); + final T alpha = fY.atan2(fX); + final T fixedPixel = alpha.divide(pixelWidth).add(lowIndex); + + final T[] ret = MathArrays.buildArray(fixedPixel.getField(), 2); + ret[0] = fixedLine; + ret[1] = fixedPixel; + return ret; + } /** Get transform from spacecraft to inertial frame. diff --git a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java index 59adb6528ecfe202015df6911b3ef8cd479ab8ad..fb22fd5d58c4322e0f935a74126c9842b4298328 100644 --- a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java +++ b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java @@ -36,7 +36,7 @@ import java.util.TreeMap; import java.util.regex.Pattern; import java.util.stream.Stream; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.exception.LocalizedCoreFormats; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Rotation; @@ -63,7 +63,7 @@ import org.orekit.rugged.raster.TileUpdater; import org.orekit.rugged.raster.UpdatableTile; import org.orekit.rugged.refraction.AtmosphericRefraction; import org.orekit.rugged.refraction.MultiLayerModel; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.rugged.utils.ExtendedEllipsoid; import org.orekit.rugged.utils.SpacecraftToObservedBody; import org.orekit.time.AbsoluteDate; @@ -1215,12 +1215,12 @@ public class DumpReplayer { /** {@inheritDoc} */ @Override - public FieldVector3D<DerivativeStructure> getLOSDerivatives(final int index, final AbsoluteDate date, - final DSGenerator generator) { + public <T extends Derivative<T>> FieldVector3D<T> getLOSDerivatives(final int index, final AbsoluteDate date, + final DerivativeGenerator<T> generator) { final Vector3D los = getLOS(index, date); - return new FieldVector3D<DerivativeStructure>(generator.constant(los.getX()), - generator.constant(los.getY()), - generator.constant(los.getZ())); + return new FieldVector3D<>(generator.constant(los.getX()), + generator.constant(los.getY()), + generator.constant(los.getZ())); } /** Set a datation pair. diff --git a/src/main/java/org/orekit/rugged/linesensor/LineSensor.java b/src/main/java/org/orekit/rugged/linesensor/LineSensor.java index c712c7344ad9447bdb406118a8583e435c5cd4fe..ca9fd053173413b20682e728b868f9fad85741c5 100644 --- a/src/main/java/org/orekit/rugged/linesensor/LineSensor.java +++ b/src/main/java/org/orekit/rugged/linesensor/LineSensor.java @@ -18,13 +18,13 @@ package org.orekit.rugged.linesensor; import java.util.stream.Stream; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.FastMath; import org.orekit.rugged.errors.DumpManager; import org.orekit.rugged.los.TimeDependentLOS; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.time.AbsoluteDate; import org.orekit.utils.ParameterDriver; @@ -113,37 +113,36 @@ public class LineSensor { /** Get the pixel normalized line-of-sight at some date, * and their derivatives with respect to estimated parameters. + * @param <T> derivative type * @param date current date * @param i pixel index (must be between 0 and {@link #getNbPixels()} - 1 - * @param generator generator to use for building {@link DerivativeStructure} instances + * @param generator generator to use for building {@link Derivative} instances * @return pixel normalized line-of-sight - * @since 2.0 */ - public FieldVector3D<DerivativeStructure> getLOSDerivatives(final AbsoluteDate date, final int i, - final DSGenerator generator) { + public <T extends Derivative<T>> FieldVector3D<T> getLOSDerivatives(final AbsoluteDate date, final int i, + final DerivativeGenerator<T> generator) { return los.getLOSDerivatives(i, date, generator); } /** Get the pixel normalized line-of-sight at some date, * and their derivatives with respect to estimated parameters. + * @param <T> derivative type * @param date current date * @param i pixel index (must be between 0 and {@link #getNbPixels()} - 1 - * @param generator generator to use for building {@link DerivativeStructure} instances + * @param generator generator to use for building {@link Derivative} instances * @return pixel normalized line-of-sight * @since 2.0 */ - public FieldVector3D<DerivativeStructure> getLOSDerivatives(final AbsoluteDate date, final double i, - final DSGenerator generator) { + public <T extends Derivative<T>> FieldVector3D<T> getLOSDerivatives(final AbsoluteDate date, final double i, + final DerivativeGenerator<T> generator) { // find surrounding pixels of pixelB (in order to interpolate LOS from pixelB (that is not an integer) final int iInf = FastMath.max(0, FastMath.min(getNbPixels() - 2, (int) FastMath.floor(i))); final int iSup = iInf + 1; - final FieldVector3D<DerivativeStructure> interpolatedLos = new FieldVector3D<DerivativeStructure> ( - iSup - i, - los.getLOSDerivatives(iInf, date, generator), - i - iInf, - los.getLOSDerivatives(iSup, date, generator)).normalize(); + final FieldVector3D<T> interpolatedLos = + new FieldVector3D<> (iSup - i, los.getLOSDerivatives(iInf, date, generator), + i - iInf, los.getLOSDerivatives(iSup, date, generator)).normalize(); return interpolatedLos; } diff --git a/src/main/java/org/orekit/rugged/los/FixedRotation.java b/src/main/java/org/orekit/rugged/los/FixedRotation.java index d2905bb9e13ee28cea2944ce6751f69e71475605..40187de276418cfd0b68d7ca9da3b86192640aa4 100644 --- a/src/main/java/org/orekit/rugged/los/FixedRotation.java +++ b/src/main/java/org/orekit/rugged/los/FixedRotation.java @@ -18,14 +18,14 @@ package org.orekit.rugged.los; import java.util.stream.Stream; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.geometry.euclidean.threed.FieldRotation; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Rotation; import org.hipparchus.geometry.euclidean.threed.RotationConvention; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.FastMath; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.utils.ParameterDriver; import org.orekit.utils.ParameterObserver; @@ -50,7 +50,7 @@ public class FixedRotation implements TimeIndependentLOSTransform { private Rotation rotation; /** Underlying rotation with derivatives. */ - private FieldRotation<DerivativeStructure> rDS; + private FieldRotation<?> rDS; /** Driver for rotation angle. */ private final ParameterDriver angleDriver; @@ -96,19 +96,31 @@ public class FixedRotation implements TimeIndependentLOSTransform { } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override - public FieldVector3D<DerivativeStructure> transformLOS(final int i, final FieldVector3D<DerivativeStructure> los, - final DSGenerator generator) { - if (rDS == null) { + public <T extends Derivative<T>> FieldVector3D<T> transformLOS(final int i, final FieldVector3D<T> los, + final DerivativeGenerator<T> generator) { + final FieldRotation<T> rD; + if (rDS == null || !rDS.getQ0().getField().equals(generator.getField())) { + // lazy evaluation of the rotation - final FieldVector3D<DerivativeStructure> axisDS = - new FieldVector3D<DerivativeStructure>(generator.constant(axis.getX()), - generator.constant(axis.getY()), - generator.constant(axis.getZ())); - final DerivativeStructure angleDS = generator.variable(angleDriver); - rDS = new FieldRotation<DerivativeStructure>(axisDS, angleDS, RotationConvention.VECTOR_OPERATOR); + final FieldVector3D<T> axisDS = + new FieldVector3D<>(generator.constant(axis.getX()), + generator.constant(axis.getY()), + generator.constant(axis.getZ())); + final T angleDS = generator.variable(angleDriver); + rD = new FieldRotation<>(axisDS, angleDS, RotationConvention.VECTOR_OPERATOR); + + // cache evaluated rotation + rDS = rD; + + } else { + // reuse cached value + rD = (FieldRotation<T>) rDS; } - return rDS.applyTo(los); + + return rD.applyTo(los); + } } diff --git a/src/main/java/org/orekit/rugged/los/FixedZHomothety.java b/src/main/java/org/orekit/rugged/los/FixedZHomothety.java index 855fcd0a865565489887d408716e591eb47732d4..071b5672b8d04544d44e298a10499d112da102ce 100644 --- a/src/main/java/org/orekit/rugged/los/FixedZHomothety.java +++ b/src/main/java/org/orekit/rugged/los/FixedZHomothety.java @@ -18,11 +18,11 @@ package org.orekit.rugged.los; import java.util.stream.Stream; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.FastMath; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.utils.ParameterDriver; import org.orekit.utils.ParameterObserver; @@ -46,7 +46,7 @@ public class FixedZHomothety implements TimeIndependentLOSTransform { private double factor; /** Underlying homothety with derivatives. */ - private DerivativeStructure factorDS; + private Derivative<?> factorDS; /** Driver for homothety factor. */ private final ParameterDriver factorDriver; @@ -91,14 +91,26 @@ public class FixedZHomothety implements TimeIndependentLOSTransform { } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override - public FieldVector3D<DerivativeStructure> transformLOS(final int i, final FieldVector3D<DerivativeStructure> los, - final DSGenerator generator) { - if (factorDS == null) { + public <T extends Derivative<T>> FieldVector3D<T> transformLOS(final int i, final FieldVector3D<T> los, + final DerivativeGenerator<T> generator) { + final T factorD; + if (factorDS == null || !factorDS.getField().equals(generator.getField())) { + // lazy evaluation of the homothety - factorDS = generator.variable(factorDriver); + factorD = generator.variable(factorDriver); + + // cache evaluated homothety + factorDS = factorD; + + } else { + // reuse cached value + factorD = (T) factorDS; } - return new FieldVector3D<DerivativeStructure>(los.getX(), los.getY(), factorDS.multiply(los.getZ())); + + return new FieldVector3D<>(los.getX(), los.getY(), factorD.multiply(los.getZ())); + } } diff --git a/src/main/java/org/orekit/rugged/los/LOSBuilder.java b/src/main/java/org/orekit/rugged/los/LOSBuilder.java index bfcce6b381763f46ce680d1387fd2fd7fdf18f29..c65796850490c5ffcbdeb59c3caa5c2a09e0e816 100644 --- a/src/main/java/org/orekit/rugged/los/LOSBuilder.java +++ b/src/main/java/org/orekit/rugged/los/LOSBuilder.java @@ -21,10 +21,10 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Stream; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.time.AbsoluteDate; import org.orekit.utils.ParameterDriver; import org.orekit.utils.ParameterObserver; @@ -122,8 +122,8 @@ public class LOSBuilder { /** {@inheritDoc} */ @Override - public FieldVector3D<DerivativeStructure> transformLOS(final int i, final FieldVector3D<DerivativeStructure> los, - final AbsoluteDate date, final DSGenerator generator) { + public <T extends Derivative<T>> FieldVector3D<T> transformLOS(final int i, final FieldVector3D<T> los, + final AbsoluteDate date, final DerivativeGenerator<T> generator) { return transform.transformLOS(i, los, generator); } @@ -179,14 +179,13 @@ public class LOSBuilder { /** {@inheritDoc} */ @Override - public FieldVector3D<DerivativeStructure> getLOSDerivatives(final int index, final AbsoluteDate date, - final DSGenerator generator) { + public <T extends Derivative<T>> FieldVector3D<T> getLOSDerivatives(final int index, final AbsoluteDate date, + final DerivativeGenerator<T> generator) { // the raw line of sights are considered to be constant - FieldVector3D<DerivativeStructure> los = - new FieldVector3D<DerivativeStructure>(generator.constant(raw[index].getX()), - generator.constant(raw[index].getY()), - generator.constant(raw[index].getZ())); + FieldVector3D<T> los = new FieldVector3D<>(generator.constant(raw[index].getX()), + generator.constant(raw[index].getY()), + generator.constant(raw[index].getZ())); // apply the transforms, which depend on parameters and hence may introduce non-zero derivatives for (final LOSTransform transform : transforms) { diff --git a/src/main/java/org/orekit/rugged/los/LOSTransform.java b/src/main/java/org/orekit/rugged/los/LOSTransform.java index b32af12a654485c9e80d82abf5ae83e2a057b7c5..7fd71d574c401662e96f19351d1904b9e6eb8600 100644 --- a/src/main/java/org/orekit/rugged/los/LOSTransform.java +++ b/src/main/java/org/orekit/rugged/los/LOSTransform.java @@ -18,10 +18,11 @@ package org.orekit.rugged.los; import java.util.stream.Stream; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.analysis.differentiation.DerivativeStructure; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.time.AbsoluteDate; import org.orekit.utils.ParameterDriver; @@ -46,14 +47,15 @@ public interface LOSTransform { * are typically polynomials coefficients representing rotation angles. * These polynomials can be used for example to model thermo-elastic effects. * </p> + * @param <T> derivative type * @param index los pixel index * @param los line-of-sight to transform * @param date date * @param generator generator to use for building {@link DerivativeStructure} instances * @return line of sight, and its first partial derivatives with respect to the parameters */ - FieldVector3D<DerivativeStructure> transformLOS(int index, FieldVector3D<DerivativeStructure> los, - AbsoluteDate date, DSGenerator generator); + <T extends Derivative<T>> FieldVector3D<T> transformLOS(int index, FieldVector3D<T> los, + AbsoluteDate date, DerivativeGenerator<T> generator); /** Get the drivers for LOS parameters. * @return drivers for LOS parameters diff --git a/src/main/java/org/orekit/rugged/los/PolynomialRotation.java b/src/main/java/org/orekit/rugged/los/PolynomialRotation.java index dec79d1ff21ae5e7b6e8aa98064963416ad2c020..e548781a69f8fa548625a1324075ddad916ab807 100644 --- a/src/main/java/org/orekit/rugged/los/PolynomialRotation.java +++ b/src/main/java/org/orekit/rugged/los/PolynomialRotation.java @@ -18,7 +18,8 @@ package org.orekit.rugged.los; import java.util.stream.Stream; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.Field; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.analysis.polynomials.PolynomialFunction; import org.hipparchus.geometry.euclidean.threed.FieldRotation; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; @@ -26,7 +27,8 @@ import org.hipparchus.geometry.euclidean.threed.Rotation; import org.hipparchus.geometry.euclidean.threed.RotationConvention; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.util.FastMath; -import org.orekit.rugged.utils.DSGenerator; +import org.hipparchus.util.MathArrays; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.time.AbsoluteDate; import org.orekit.utils.ParameterDriver; import org.orekit.utils.ParameterObserver; @@ -52,10 +54,10 @@ public class PolynomialRotation implements LOSTransform { private PolynomialFunction angle; /** Rotation axis and derivatives. */ - private FieldVector3D<DerivativeStructure> axisDS; + private FieldVector3D<?> axisDS; /** Rotation angle polynomial and derivatives. */ - private DerivativeStructure[] angleDS; + private Derivative<?>[] angleDS; /** Reference date for polynomial evaluation. */ private final AbsoluteDate referenceDate; @@ -143,30 +145,44 @@ public class PolynomialRotation implements LOSTransform { } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override - public FieldVector3D<DerivativeStructure> transformLOS(final int i, final FieldVector3D<DerivativeStructure> los, - final AbsoluteDate date, final DSGenerator generator) { + public <T extends Derivative<T>> FieldVector3D<T> transformLOS(final int i, final FieldVector3D<T> los, + final AbsoluteDate date, + final DerivativeGenerator<T> generator) { + + final Field<T> field = generator.getField(); + final FieldVector3D<T> axisD; + final T[] angleD; + if (axisDS == null || !axisDS.getX().getField().equals(field)) { - if (angleDS == null) { // lazy evaluation of the rotation - axisDS = new FieldVector3D<DerivativeStructure>(generator.constant(axis.getX()), - generator.constant(axis.getY()), - generator.constant(axis.getZ())); - angleDS = new DerivativeStructure[coefficientsDrivers.length]; - for (int k = 0; k < angleDS.length; ++k) { - angleDS[k] = generator.variable(coefficientsDrivers[k]); + axisD = new FieldVector3D<>(generator.constant(axis.getX()), + generator.constant(axis.getY()), + generator.constant(axis.getZ())); + angleD = MathArrays.buildArray(field, coefficientsDrivers.length); + for (int k = 0; k < angleD.length; ++k) { + angleD[k] = generator.variable(coefficientsDrivers[k]); } + + // cache evaluated rotation parameters + axisDS = axisD; + angleDS = angleD; + + } else { + // reuse cached values + axisD = (FieldVector3D<T>) axisDS; + angleD = (T[]) angleDS; } + // evaluate polynomial, with all its partial derivatives final double t = date.durationFrom(referenceDate); - DerivativeStructure alpha = axisDS.getX().getField().getZero(); + T alpha = field.getZero(); for (int k = angleDS.length - 1; k >= 0; --k) { - alpha = alpha.multiply(t).add(angleDS[k]); + alpha = alpha.multiply(t).add(angleD[k]); } - return new FieldRotation<DerivativeStructure>(axisDS, - alpha, - RotationConvention.VECTOR_OPERATOR).applyTo(los); + return new FieldRotation<>(axisD, alpha, RotationConvention.VECTOR_OPERATOR).applyTo(los); } diff --git a/src/main/java/org/orekit/rugged/los/TimeDependentLOS.java b/src/main/java/org/orekit/rugged/los/TimeDependentLOS.java index 5da881287ab79ba7fc9e3530fe01cf908c6d44f6..d12d6aba476b96f143276acab8c6088030a217c6 100644 --- a/src/main/java/org/orekit/rugged/los/TimeDependentLOS.java +++ b/src/main/java/org/orekit/rugged/los/TimeDependentLOS.java @@ -18,10 +18,10 @@ package org.orekit.rugged.los; import java.util.stream.Stream; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.time.AbsoluteDate; import org.orekit.utils.ParameterDriver; @@ -56,14 +56,15 @@ public interface TimeDependentLOS { * method must have been set to {@code true} for the various parameters returned * by {@link #getParametersDrivers()} that should be estimated. * </p> + * @param <T> derivative type * @param index los pixel index * @param date date - * @param generator generator to use for building {@link DerivativeStructure} instances + * @param generator generator to use for building {@link Derivative} instances * @return line of sight, and its first partial derivatives with respect to the parameters * @since 2.0 */ - FieldVector3D<DerivativeStructure> getLOSDerivatives(int index, AbsoluteDate date, - DSGenerator generator); + <T extends Derivative<T>> FieldVector3D<T> getLOSDerivatives(int index, AbsoluteDate date, + DerivativeGenerator<T> generator); /** Get the drivers for LOS parameters. * @return drivers for LOS parameters diff --git a/src/main/java/org/orekit/rugged/los/TimeIndependentLOSTransform.java b/src/main/java/org/orekit/rugged/los/TimeIndependentLOSTransform.java index 34e9f753ecce410204e75c2cff7f90a57038f34d..6c433a6fb96f8d00776e4441694491a52b77c391 100644 --- a/src/main/java/org/orekit/rugged/los/TimeIndependentLOSTransform.java +++ b/src/main/java/org/orekit/rugged/los/TimeIndependentLOSTransform.java @@ -18,10 +18,10 @@ package org.orekit.rugged.los; import java.util.stream.Stream; -import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Derivative; import org.hipparchus.geometry.euclidean.threed.FieldVector3D; import org.hipparchus.geometry.euclidean.threed.Vector3D; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.utils.ParameterDriver; /** Interface for lines-of-sight tranforms that do not depend on time. @@ -50,13 +50,14 @@ public interface TimeIndependentLOSTransform { * method must have been set to {@code true} for the various parameters returned * by {@link #getParametersDrivers()} that should be estimated. * </p> + * @param <T> derivative type * @param index los pixel index * @param los line-of-sight to transform - * @param generator generator to use for building {@link DerivativeStructure} instances + * @param generator generator to use for building {@link Derivative} instances * @return line of sight, and its first partial derivatives with respect to the parameters */ - FieldVector3D<DerivativeStructure> transformLOS(int index, FieldVector3D<DerivativeStructure> los, - DSGenerator generator); + <T extends Derivative<T>> FieldVector3D<T> transformLOS(int index, FieldVector3D<T> los, + DerivativeGenerator<T> generator); /** Get the drivers for LOS parameters. * @return drivers for LOS parameters diff --git a/src/main/java/org/orekit/rugged/utils/DSGenerator.java b/src/main/java/org/orekit/rugged/utils/DSGenerator.java index 5260cd093c2c3aa2085d21cdb11f8e6ce249b54e..938a32bae1a9290496b322293167d083dc834552 100644 --- a/src/main/java/org/orekit/rugged/utils/DSGenerator.java +++ b/src/main/java/org/orekit/rugged/utils/DSGenerator.java @@ -16,8 +16,6 @@ */ package org.orekit.rugged.utils; -import java.util.List; - import org.hipparchus.analysis.differentiation.DerivativeStructure; import org.orekit.utils.ParameterDriver; @@ -27,29 +25,8 @@ import org.orekit.utils.ParameterDriver; * </p> * @author Luc Maisonobe * @since 2.0 + * @deprecated as of 2.2, replaced by {@link DerivativeGenerator} */ -public interface DSGenerator { - - /** Get the parameters selected for estimation. - * @return parameters selected for estimation - */ - List<ParameterDriver> getSelected(); - - /** Generate a constant {@link DerivativeStructure}. - * @param value value of the constant - * @return constant {@link DerivativeStructure} - */ - DerivativeStructure constant(double value); - - /** Generate a {@link DerivativeStructure} representing the - * parameter driver either as a canonical variable or a constant. - * <p> - * The instance created is a variable only if the parameter - * has been selected for estimation, otherwise it is a constant. - * </p> - * @param driver driver for the variable - * @return variable {@link DerivativeStructure} - */ - DerivativeStructure variable(ParameterDriver driver); - +public interface DSGenerator extends DerivativeGenerator<DerivativeStructure> { + // nothing specialized here } diff --git a/src/main/java/org/orekit/rugged/utils/DerivativeGenerator.java b/src/main/java/org/orekit/rugged/utils/DerivativeGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..be87b7e7f953114597eb05121f56b8b37d2bf9a7 --- /dev/null +++ b/src/main/java/org/orekit/rugged/utils/DerivativeGenerator.java @@ -0,0 +1,64 @@ +/* Copyright 2013-2020 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.rugged.utils; + +import java.util.List; + +import org.hipparchus.Field; +import org.hipparchus.analysis.differentiation.Derivative; +import org.orekit.utils.ParameterDriver; + +/** Generator for {@link Derivative} instances from {@link ParameterDriver}. + * <p> + * Note that this interface is for Rugged library internal use only. + * </p> + * @author Luc Maisonobe + * @since 2.0 + */ +public interface DerivativeGenerator<T extends Derivative<T>> { + + /** Get the parameters selected for estimation. + * @return parameters selected for estimation + */ + List<ParameterDriver> getSelected(); + + /** Generate a constant {@link Derivative}. + * @param value value of the constant + * @return constant {@link Derivative} + */ + T constant(double value); + + /** Generate a {@link Derivative} representing the + * parameter driver either as a canonical variable or a constant. + * <p> + * The instance created is a variable only if the parameter + * has been selected for estimation, otherwise it is a constant. + * </p> + * @param driver driver for the variable + * @return variable {@link Derivative} + */ + T variable(ParameterDriver driver); + + /** Get the {@link Field} to which the generated derivatives belongs. + * @return {@link Field} to which the generated derivatives belongs + * @since 2.2 + */ + default Field<T> getField() { + return constant(0).getField(); + } + +} diff --git a/src/test/java/org/orekit/rugged/adjustment/util/InitInterRefiningTest.java b/src/test/java/org/orekit/rugged/adjustment/util/InitInterRefiningTest.java index 448c890414050dd49ac99e81fb9929f15eab55b5..e9991d95bfbd75b6eb53484dde11c3cd5297d415 100644 --- a/src/test/java/org/orekit/rugged/adjustment/util/InitInterRefiningTest.java +++ b/src/test/java/org/orekit/rugged/adjustment/util/InitInterRefiningTest.java @@ -8,6 +8,7 @@ import java.util.Arrays; import java.util.List; import org.hipparchus.analysis.differentiation.DerivativeStructure; +import org.hipparchus.analysis.differentiation.Gradient; import org.hipparchus.geometry.euclidean.threed.Vector3D; import org.hipparchus.random.GaussianRandomGenerator; import org.hipparchus.random.UncorrelatedRandomVectorGenerator; @@ -33,7 +34,7 @@ import org.orekit.rugged.api.Rugged; import org.orekit.rugged.api.RuggedBuilder; import org.orekit.rugged.linesensor.LineSensor; import org.orekit.rugged.linesensor.SensorPixel; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.rugged.utils.SpacecraftToObservedBody; import org.orekit.time.AbsoluteDate; import org.orekit.utils.AngularDerivativesFilter; @@ -268,11 +269,29 @@ public class InitInterRefiningTest { * @param realPixelA real pixel from sensor A * @param realPixelB real pixel from sensor B * @return the distances of two real pixels computed between LOS and to the ground + * @deprecated as of 2.2, replaced by {@link #computeDistancesBetweenLOSGradient(SensorPixel, SensorPixel, double, double)} */ public DerivativeStructure[] computeDistancesBetweenLOSDerivatives(final SensorPixel realPixelA, final SensorPixel realPixelB, - double losDistance, double earthDistance) + final double losDistance, final double earthDistance) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - + final Gradient[] gradient = computeDistancesBetweenLOSGradient(realPixelA, realPixelB, losDistance, earthDistance); + final DerivativeStructure[] ds = new DerivativeStructure[gradient.length]; + for (int i = 0; i < gradient.length; ++i) { + ds[i] = gradient[i].toDerivativeStructure(); + } + return ds; + } + + /** Compute the distances with derivatives between LOS of two real pixels (one from sensor A and one from sensor B) + * @param realPixelA real pixel from sensor A + * @param realPixelB real pixel from sensor B + * @return the distances of two real pixels computed between LOS and to the ground + * @since 2.2 + */ + public Gradient[] computeDistancesBetweenLOSGradient(final SensorPixel realPixelA, final SensorPixel realPixelB, + final double losDistance, final double earthDistance) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + final SpacecraftToObservedBody scToBodyA = ruggedA.getScToBody(); final AbsoluteDate realDateA = lineSensorA.getDate(realPixelA.getLineNumber()); @@ -301,15 +320,14 @@ public class InitInterRefiningTest { listLineSensor.addAll(ruggedA.getLineSensors()); listLineSensor.addAll(ruggedB.getLineSensors()); - DSGenerator generator = (DSGenerator) createGenerator.invoke(optimizationPbBuilder, listLineSensor); + @SuppressWarnings("unchecked") + DerivativeGenerator<Gradient> generator = (DerivativeGenerator<Gradient>) createGenerator.invoke(optimizationPbBuilder, listLineSensor); - final DerivativeStructure[] distanceLOSwithDS = ruggedB.distanceBetweenLOSderivatives( - lineSensorA, realDateA, realPixelA.getPixelNumber(), - scToBodyA, - lineSensorB, realDateB, realPixelB.getPixelNumber(), - generator); + return ruggedB.distanceBetweenLOSderivatives(lineSensorA, realDateA, realPixelA.getPixelNumber(), + scToBodyA, + lineSensorB, realDateB, realPixelB.getPixelNumber(), + generator); - return distanceLOSwithDS; } /** Generate noisy measurements (sensor to sensor mapping) diff --git a/src/test/java/org/orekit/rugged/api/RuggedTest.java b/src/test/java/org/orekit/rugged/api/RuggedTest.java index dff1e06f328c013e7c7850006c3a9f6dc1ea27de..8d44d62404433a65130d9553ff6221a8670d3ccb 100644 --- a/src/test/java/org/orekit/rugged/api/RuggedTest.java +++ b/src/test/java/org/orekit/rugged/api/RuggedTest.java @@ -37,6 +37,7 @@ import java.util.Locale; import org.hipparchus.analysis.differentiation.DSFactory; import org.hipparchus.analysis.differentiation.DerivativeStructure; import org.hipparchus.analysis.differentiation.FiniteDifferencesDifferentiator; +import org.hipparchus.analysis.differentiation.Gradient; import org.hipparchus.analysis.differentiation.UnivariateDifferentiableFunction; import org.hipparchus.geometry.euclidean.threed.Rotation; import org.hipparchus.geometry.euclidean.threed.RotationConvention; @@ -77,7 +78,7 @@ import org.orekit.rugged.los.TimeDependentLOS; import org.orekit.rugged.raster.RandomLandscapeUpdater; import org.orekit.rugged.raster.TileUpdater; import org.orekit.rugged.raster.VolcanicConeElevationUpdater; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.time.AbsoluteDate; import org.orekit.time.TimeScale; import org.orekit.time.TimeScalesFactory; @@ -1170,7 +1171,8 @@ public class RuggedTest { java.lang.reflect.Method getGenerator = GroundOptimizationProblemBuilder.class.getSuperclass().getDeclaredMethod("getGenerator"); getGenerator.setAccessible(true); - DSGenerator generator = (DSGenerator) getGenerator.invoke(optimizationPbBuilder); + @SuppressWarnings("unchecked") + DerivativeGenerator<Gradient> generator = (DerivativeGenerator<Gradient>) getGenerator.invoke(optimizationPbBuilder); double referenceLine = 0.87654 * dimension; GeodeticPoint[] gp = rugged.directLocation("line", referenceLine); @@ -1178,13 +1180,13 @@ public class RuggedTest { Method inverseLoc = Rugged.class.getDeclaredMethod("inverseLocationDerivatives", String.class, GeodeticPoint.class, Integer.TYPE, Integer.TYPE, - DSGenerator.class); + DerivativeGenerator.class); inverseLoc.setAccessible(true); int referencePixel = (3 * dimension) / 4; - DerivativeStructure[] result = - (DerivativeStructure[]) inverseLoc.invoke(rugged, - "line", gp[referencePixel], 0, dimension, - generator); + Gradient[] result = + (Gradient[]) inverseLoc.invoke(rugged, + "line", gp[referencePixel], 0, dimension, + generator); Assert.assertEquals(referenceLine, result[0].getValue(), lineTolerance); Assert.assertEquals(referencePixel, result[1].getValue(), pixelTolerance); Assert.assertEquals(2, result[0].getFreeParameters()); diff --git a/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java b/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java index 098e2bf697d24cf06d7ebcda40514f151b0bf6da..dd0330c9494c178a12df4fc12c0b9c8dbe809ada 100644 --- a/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java +++ b/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java @@ -53,7 +53,7 @@ import org.orekit.data.DirectoryCrawler; import org.orekit.rugged.api.Rugged; import org.orekit.rugged.linesensor.SensorPixel; import org.orekit.rugged.refraction.MultiLayerModel; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.time.AbsoluteDate; import org.orekit.time.TimeScalesFactory; import org.orekit.utils.ParameterDriver; @@ -643,11 +643,11 @@ public class DumpReplayerTest { // ParsedSensor.getLOSDerivatives // Needs some LOS to be set - Method getLOSDerivatives = innerClass.getDeclaredMethod("getLOSDerivatives", int.class, AbsoluteDate.class, DSGenerator.class); + Method getLOSDerivatives = innerClass.getDeclaredMethod("getLOSDerivatives", int.class, AbsoluteDate.class, DerivativeGenerator.class); getLOSDerivatives.setAccessible(true); final DSFactory factory = new DSFactory(1, 1); - DSGenerator generator = new DSGenerator() { + DerivativeGenerator<DerivativeStructure> generator = new DerivativeGenerator<DerivativeStructure>() { @Override public List<ParameterDriver> getSelected() { return null; diff --git a/src/test/java/org/orekit/rugged/linesensor/FixedRotationTest.java b/src/test/java/org/orekit/rugged/linesensor/FixedRotationTest.java index d49377ebd9bf15ac6b11a09e988d04c2f6f01715..cad43aeaac0cacb56540a6b8fa05bab3838ea67a 100644 --- a/src/test/java/org/orekit/rugged/linesensor/FixedRotationTest.java +++ b/src/test/java/org/orekit/rugged/linesensor/FixedRotationTest.java @@ -40,7 +40,7 @@ import org.junit.Test; import org.orekit.rugged.los.FixedRotation; import org.orekit.rugged.los.LOSBuilder; import org.orekit.rugged.los.TimeDependentLOS; -import org.orekit.rugged.utils.DSGenerator; +import org.orekit.rugged.utils.DerivativeGenerator; import org.orekit.time.AbsoluteDate; import org.orekit.utils.ParameterDriver; @@ -158,7 +158,7 @@ public class FixedRotationTest { driver.setSelected(true); } final DSFactory factoryS = new DSFactory(selected.size(), 1); - DSGenerator generator = new DSGenerator() { + DerivativeGenerator<DerivativeStructure> generator = new DerivativeGenerator<DerivativeStructure>() { /** {@inheritDoc} */ @Override