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

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

Introduction

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

Prototype

public T[][] derivatives(T x, int order) throws NoDataException, NullArgumentException 

Source Link

Document

Interpolate value and first derivatives at a specified abscissa.

Usage

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

/** Interpolate angular coordinates.
 * <p>//from   ww  w  .  ja v a 2 s.  c  om
 * 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 . jav a 2  s . c  o m*/
 * 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]));

}