Example usage for org.apache.commons.math3.analysis.interpolation FieldHermiteInterpolator FieldHermiteInterpolator

List of usage examples for org.apache.commons.math3.analysis.interpolation FieldHermiteInterpolator FieldHermiteInterpolator

Introduction

In this page you can find the example usage for org.apache.commons.math3.analysis.interpolation FieldHermiteInterpolator FieldHermiteInterpolator.

Prototype

public FieldHermiteInterpolator() 

Source Link

Document

Create an empty interpolator.

Usage

From source file:org.orekit.utils.TimeStampedFieldAngularCoordinates.java

/** Interpolate angular coordinates.
 * <p>/*ww  w  .jav  a 2  s . co m*/
 * The interpolated instance is created by polynomial Hermite interpolation
 * on Rodrigues vector ensuring FieldRotation<T> rate remains the exact derivative of FieldRotation<T>.
 * </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 FieldRotation<T>s
 * when this singularity is detected.
 * </p>
 * <p>
 * Note that even if first time derivatives (FieldRotation<T> rates)
 * 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 FieldRotation<T>s.
 * </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
 * @param <T> the type of the field elements
 * @return a new position-velocity, interpolated at specified date
 * @exception OrekitException if the number of point is too small for interpolating
 */
@SuppressWarnings("unchecked")
public static <T extends RealFieldElement<T>> TimeStampedFieldAngularCoordinates<T> interpolate(
        final AbsoluteDate date, final AngularDerivativesFilter filter,
        final Collection<TimeStampedFieldAngularCoordinates<T>> sample) throws OrekitException {

    // get field properties
    final Field<T> field = sample.iterator().next().getRotation().getQ0().getField();
    final T zero = field.getZero();
    final T one = field.getOne();

    // 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 FieldVector3D<T> meanRate;
    if (filter != AngularDerivativesFilter.USE_R) {
        FieldVector3D<T> sum = new FieldVector3D<T>(zero, zero, zero);
        for (final TimeStampedFieldAngularCoordinates<T> datedAC : sample) {
            sum = sum.add(datedAC.getRotationRate());
        }
        meanRate = new FieldVector3D<T>(1.0 / sample.size(), sum);
    } else {
        if (sample.size() < 2) {
            throw new OrekitException(OrekitMessages.NOT_ENOUGH_DATA_FOR_INTERPOLATION, sample.size());
        }
        FieldVector3D<T> sum = new FieldVector3D<T>(zero, zero, zero);
        TimeStampedFieldAngularCoordinates<T> previous = null;
        for (final TimeStampedFieldAngularCoordinates<T> datedAC : sample) {
            if (previous != null) {
                sum = sum.add(estimateRate(previous.getRotation(), datedAC.getRotation(),
                        datedAC.date.durationFrom(previous.getDate())));
            }
            previous = datedAC;
        }
        meanRate = new FieldVector3D<T>(1.0 / (sample.size() - 1), sum);
    }
    TimeStampedFieldAngularCoordinates<T> offset = new TimeStampedFieldAngularCoordinates<T>(date,
            new FieldRotation<T>(one, zero, zero, zero, false), meanRate,
            new FieldVector3D<T>(zero, zero, 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 FieldHermiteInterpolator<T> interpolator = new FieldHermiteInterpolator<T>();

        // add sample points
        final double[] previous = new double[] { 1.0, 0.0, 0.0, 0.0 };

        for (final TimeStampedFieldAngularCoordinates<T> ac : sample) {

            // remove linear offset from the current coordinates
            final T dt = zero.add(ac.date.durationFrom(date));
            final TimeStampedFieldAngularCoordinates<T> fixed = ac
                    .subtractOffset(offset.shiftedBy(dt.getReal()));

            final T[][] rodrigues = getModifiedRodrigues(fixed, previous, threshold);
            if (rodrigues == null) {
                // 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;
            }
            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 FieldAngularCoordinates<T>(
                    new FieldRotation<T>(new FieldVector3D<T>(one, zero, zero), zero.add(epsilon)),
                    new FieldVector3D<T>(zero, zero, zero), new FieldVector3D<T>(zero, zero, zero)));
        } else {
            // interpolation succeeded with the current offset
            final T[][] p = interpolator.derivatives(field.getZero(), 2);
            return createFromModifiedRodrigues(p, offset);
        }

    }

    // this should never happen
    throw new OrekitInternalError(null);

}

From source file:org.orekit.utils.TimeStampedFieldPVCoordinates.java

/** Interpolate position-velocity.
 * <p>//from www .  j a v a 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
 * @param <T> the type of the field elements
 * @return a new position-velocity, interpolated at specified date
 */
@SuppressWarnings("unchecked")
public static <T extends RealFieldElement<T>> TimeStampedFieldPVCoordinates<T> interpolate(
        final AbsoluteDate date, final CartesianDerivativesFilter filter,
        final Collection<TimeStampedFieldPVCoordinates<T>> sample) {

    // get field properties
    final T prototype = sample.iterator().next().getPosition().getX();
    final T zero = prototype.getField().getZero();

    // set up an interpolator taking derivatives into account
    final FieldHermiteInterpolator<T> interpolator = new FieldHermiteInterpolator<T>();

    // add sample points
    switch (filter) {
    case USE_P:
        // populate sample with position data, ignoring velocity
        for (final TimeStampedFieldPVCoordinates<T> datedPV : sample) {
            final FieldVector3D<T> position = datedPV.getPosition();
            interpolator.addSamplePoint(zero.add(datedPV.getDate().durationFrom(date)), position.toArray());
        }
        break;
    case USE_PV:
        // populate sample with position and velocity data
        for (final TimeStampedFieldPVCoordinates<T> datedPV : sample) {
            final FieldVector3D<T> position = datedPV.getPosition();
            final FieldVector3D<T> velocity = datedPV.getVelocity();
            interpolator.addSamplePoint(zero.add(datedPV.getDate().durationFrom(date)), position.toArray(),
                    velocity.toArray());
        }
        break;
    case USE_PVA:
        // populate sample with position, velocity and acceleration data
        for (final TimeStampedFieldPVCoordinates<T> datedPV : sample) {
            final FieldVector3D<T> position = datedPV.getPosition();
            final FieldVector3D<T> velocity = datedPV.getVelocity();
            final FieldVector3D<T> acceleration = datedPV.getAcceleration();
            interpolator.addSamplePoint(zero.add(datedPV.getDate().durationFrom(date)), position.toArray(),
                    velocity.toArray(), acceleration.toArray());
        }
        break;
    default:
        // this should never happen
        throw new OrekitInternalError(null);
    }

    // interpolate
    final T[][] p = interpolator.derivatives(zero, 2);

    // build a new interpolated instance
    return new TimeStampedFieldPVCoordinates<T>(date, new FieldVector3D<T>(p[0]), new FieldVector3D<T>(p[1]),
            new FieldVector3D<T>(p[2]));

}