List of usage examples for org.apache.commons.math3.analysis.interpolation HermiteInterpolator HermiteInterpolator
public HermiteInterpolator()
From source file:org.orekit.propagation.semianalytical.dsst.utilities.ShortPeriodicsInterpolatedCoefficient.java
/**Compute the value of the coefficient. * @param date date at which the coefficient should be computed * @return value of the coefficient/* w w w. jav a 2 s. co m*/ */ public double value(final AbsoluteDate date) { //Get the closest points from the input date final int[] neighbors = getNeighborsIndices(date); //Creation and set up of the interpolator final HermiteInterpolator interpolator = new HermiteInterpolator(); for (int i : neighbors) { final double abscissa = abscissae.get(i).durationFrom(date); final double value = values.get(i); interpolator.addSamplePoint(abscissa, new double[] { value }); } //interpolation return interpolator.value(0.0)[0]; }
From source file:org.orekit.propagation.SpacecraftState.java
/** {@inheritDoc} * <p>//from w w w. ja v a 2s .c om * The additional states that are interpolated are the ones already present * in the instance. The sample instances must therefore have at least the same * additional states has the instance. They may have more additional states, * but the extra ones will be ignored. * </p> * <p> * As this implementation of interpolation is polynomial, it should be used only * with small samples (about 10-20 points) in order to avoid <a * href="http://en.wikipedia.org/wiki/Runge%27s_phenomenon">Runge's phenomenon</a> * and numerical problems (including NaN appearing). * </p> */ public SpacecraftState interpolate(final AbsoluteDate date, final Collection<SpacecraftState> sample) throws OrekitException { // prepare interpolators final List<Orbit> orbits = new ArrayList<Orbit>(sample.size()); final List<Attitude> attitudes = new ArrayList<Attitude>(sample.size()); final HermiteInterpolator massInterpolator = new HermiteInterpolator(); final Map<String, HermiteInterpolator> additionalInterpolators = new HashMap<String, HermiteInterpolator>( additional.size()); for (final String name : additional.keySet()) { additionalInterpolators.put(name, new HermiteInterpolator()); } // extract sample data for (final SpacecraftState state : sample) { final double deltaT = state.getDate().durationFrom(date); orbits.add(state.getOrbit()); attitudes.add(state.getAttitude()); massInterpolator.addSamplePoint(deltaT, new double[] { state.getMass() }); for (final Map.Entry<String, HermiteInterpolator> entry : additionalInterpolators.entrySet()) { entry.getValue().addSamplePoint(deltaT, state.getAdditionalState(entry.getKey())); } } // perform interpolations final Orbit interpolatedOrbit = orbit.interpolate(date, orbits); final Attitude interpolatedAttitude = attitude.interpolate(date, attitudes); final double interpolatedMass = massInterpolator.value(0)[0]; final Map<String, double[]> interpolatedAdditional; if (additional.isEmpty()) { interpolatedAdditional = null; } else { interpolatedAdditional = new HashMap<String, double[]>(additional.size()); for (final Map.Entry<String, HermiteInterpolator> entry : additionalInterpolators.entrySet()) { interpolatedAdditional.put(entry.getKey(), entry.getValue().value(0)); } } // create the complete interpolated state return new SpacecraftState(interpolatedOrbit, interpolatedAttitude, interpolatedMass, interpolatedAdditional); }
From source file:org.orekit.utils.TimeStampedAngularCoordinates.java
/** Interpolate angular coordinates. * <p>//from w w w . j a v a2 s . co m * The interpolated instance is created by polynomial Hermite interpolation * on Rodrigues vector ensuring rotation rate remains the exact derivative of rotation. * </p> * <p> * This method is based on Sergei Tanygin's paper <a * href="http://www.agi.com/downloads/resources/white-papers/Attitude-interpolation.pdf">Attitude * Interpolation</a>, changing the norm of the vector to match the modified Rodrigues * vector as described in Malcolm D. Shuster's paper <a * href="http://www.ladispe.polito.it/corsi/Meccatronica/02JHCOR/2011-12/Slides/Shuster_Pub_1993h_J_Repsurv_scan.pdf">A * Survey of Attitude Representations</a>. This change avoids the singularity at . * There is still a singularity at 2, which is handled by slightly offsetting all rotations * when this singularity is detected. * </p> * <p> * Note that even if first and second time derivatives (rotation rates and acceleration) * from sample can be ignored, the interpolated instance always includes * interpolated derivatives. This feature can be used explicitly to * compute these derivatives when it would be too complex to compute them * from an analytical formula: just compute a few sample points from the * explicit formula and set the derivatives to zero in these sample points, * then use interpolation to add derivatives consistent with the rotations. * </p> * @param date interpolation date * @param filter filter for derivatives from the sample to use in interpolation * @param sample sample points on which interpolation should be done * @return a new position-velocity, interpolated at specified date * @exception OrekitException if the number of point is too small for interpolating */ public static TimeStampedAngularCoordinates interpolate(final AbsoluteDate date, final AngularDerivativesFilter filter, final Collection<TimeStampedAngularCoordinates> sample) throws OrekitException { // set up safety elements for 2 singularity avoidance final double epsilon = 2 * FastMath.PI / sample.size(); final double threshold = FastMath.min(-(1.0 - 1.0e-4), -FastMath.cos(epsilon / 4)); // set up a linear model canceling mean rotation rate final Vector3D meanRate; if (filter != AngularDerivativesFilter.USE_R) { Vector3D sum = Vector3D.ZERO; for (final TimeStampedAngularCoordinates datedAC : sample) { sum = sum.add(datedAC.getRotationRate()); } meanRate = new Vector3D(1.0 / sample.size(), sum); } else { if (sample.size() < 2) { throw new OrekitException(OrekitMessages.NOT_ENOUGH_DATA_FOR_INTERPOLATION, sample.size()); } Vector3D sum = Vector3D.ZERO; TimeStampedAngularCoordinates previous = null; for (final TimeStampedAngularCoordinates datedAC : sample) { if (previous != null) { sum = sum.add(estimateRate(previous.getRotation(), datedAC.getRotation(), datedAC.date.durationFrom(previous.date))); } previous = datedAC; } meanRate = new Vector3D(1.0 / (sample.size() - 1), sum); } TimeStampedAngularCoordinates offset = new TimeStampedAngularCoordinates(date, Rotation.IDENTITY, meanRate, Vector3D.ZERO); boolean restart = true; for (int i = 0; restart && i < sample.size() + 2; ++i) { // offset adaptation parameters restart = false; // set up an interpolator taking derivatives into account final HermiteInterpolator interpolator = new HermiteInterpolator(); // add sample points double sign = +1.0; Rotation previous = Rotation.IDENTITY; for (final TimeStampedAngularCoordinates ac : sample) { // remove linear offset from the current coordinates final double dt = ac.date.durationFrom(date); final TimeStampedAngularCoordinates fixed = ac.subtractOffset(offset.shiftedBy(dt)); // make sure all interpolated points will be on the same branch final double dot = MathArrays.linearCombination(fixed.getRotation().getQ0(), previous.getQ0(), fixed.getRotation().getQ1(), previous.getQ1(), fixed.getRotation().getQ2(), previous.getQ2(), fixed.getRotation().getQ3(), previous.getQ3()); sign = FastMath.copySign(1.0, dot * sign); previous = fixed.getRotation(); // check modified Rodrigues vector singularity if (fixed.getRotation().getQ0() * sign < threshold) { // the sample point is close to a modified Rodrigues vector singularity // we need to change the linear offset model to avoid this restart = true; break; } final double[][] rodrigues = fixed.getModifiedRodrigues(sign); switch (filter) { case USE_RRA: // populate sample with rotation, rotation rate and acceleration data interpolator.addSamplePoint(dt, rodrigues[0], rodrigues[1], rodrigues[2]); break; case USE_RR: // populate sample with rotation and rotation rate data interpolator.addSamplePoint(dt, rodrigues[0], rodrigues[1]); break; case USE_R: // populate sample with rotation data only interpolator.addSamplePoint(dt, rodrigues[0]); break; default: // this should never happen throw new OrekitInternalError(null); } } if (restart) { // interpolation failed, some intermediate rotation was too close to 2 // we need to offset all rotations to avoid the singularity offset = offset.addOffset(new AngularCoordinates(new Rotation(Vector3D.PLUS_I, epsilon), Vector3D.ZERO, Vector3D.ZERO)); } else { // interpolation succeeded with the current offset final DerivativeStructure zero = new DerivativeStructure(1, 2, 0, 0.0); final DerivativeStructure[] p = interpolator.value(zero); final AngularCoordinates ac = createFromModifiedRodrigues( new double[][] { { p[0].getValue(), p[1].getValue(), p[2].getValue() }, { p[0].getPartialDerivative(1), p[1].getPartialDerivative(1), p[2].getPartialDerivative(1) }, { p[0].getPartialDerivative(2), p[1].getPartialDerivative(2), p[2].getPartialDerivative(2) } }); return new TimeStampedAngularCoordinates(offset.getDate(), ac.getRotation(), ac.getRotationRate(), ac.getRotationAcceleration()).addOffset(offset); } } // this should never happen throw new OrekitInternalError(null); }
From source file:org.orekit.utils.TimeStampedPVCoordinates.java
/** Interpolate position-velocity. * <p>/*from w ww. j a va 2s . c om*/ * The interpolated instance is created by polynomial Hermite interpolation * ensuring velocity remains the exact derivative of position. * </p> * <p> * Note that even if first time derivatives (velocities) * from sample can be ignored, the interpolated instance always includes * interpolated derivatives. This feature can be used explicitly to * compute these derivatives when it would be too complex to compute them * from an analytical formula: just compute a few sample points from the * explicit formula and set the derivatives to zero in these sample points, * then use interpolation to add derivatives consistent with the positions. * </p> * @param date interpolation date * @param filter filter for derivatives from the sample to use in interpolation * @param sample sample points on which interpolation should be done * @return a new position-velocity, interpolated at specified date */ public static TimeStampedPVCoordinates interpolate(final AbsoluteDate date, final CartesianDerivativesFilter filter, final Collection<TimeStampedPVCoordinates> sample) { // set up an interpolator taking derivatives into account final HermiteInterpolator interpolator = new HermiteInterpolator(); // add sample points switch (filter) { case USE_P: // populate sample with position data, ignoring velocity for (final TimeStampedPVCoordinates pv : sample) { final Vector3D position = pv.getPosition(); interpolator.addSamplePoint(pv.getDate().durationFrom(date), new double[] { position.getX(), position.getY(), position.getZ() }); } break; case USE_PV: // populate sample with position and velocity data for (final TimeStampedPVCoordinates pv : sample) { final Vector3D position = pv.getPosition(); final Vector3D velocity = pv.getVelocity(); interpolator.addSamplePoint(pv.getDate().durationFrom(date), new double[] { position.getX(), position.getY(), position.getZ() }, new double[] { velocity.getX(), velocity.getY(), velocity.getZ() }); } break; case USE_PVA: // populate sample with position, velocity and acceleration data for (final TimeStampedPVCoordinates pv : sample) { final Vector3D position = pv.getPosition(); final Vector3D velocity = pv.getVelocity(); final Vector3D acceleration = pv.getAcceleration(); interpolator.addSamplePoint(pv.getDate().durationFrom(date), new double[] { position.getX(), position.getY(), position.getZ() }, new double[] { velocity.getX(), velocity.getY(), velocity.getZ() }, new double[] { acceleration.getX(), acceleration.getY(), acceleration.getZ() }); } break; default: // this should never happen throw new OrekitInternalError(null); } // interpolate final DerivativeStructure zero = new DerivativeStructure(1, 2, 0, 0.0); final DerivativeStructure[] p = interpolator.value(zero); // build a new interpolated instance return new TimeStampedPVCoordinates(date, new Vector3D(p[0].getValue(), p[1].getValue(), p[2].getValue()), new Vector3D(p[0].getPartialDerivative(1), p[1].getPartialDerivative(1), p[2].getPartialDerivative(1)), new Vector3D(p[0].getPartialDerivative(2), p[1].getPartialDerivative(2), p[2].getPartialDerivative(2))); }