/* (non-Javadoc)
  * @see net.finmath.stochastic.RandomVariableInterface#sin()
  */
 public RandomVariableInterface sin() {
   if (isDeterministic()) {
     double newValueIfNonStochastic = FastMath.sin(valueIfNonStochastic);
     return new RandomVariable(time, newValueIfNonStochastic);
   } else {
     double[] newRealizations = new double[realizations.length];
     for (int i = 0; i < newRealizations.length; i++)
       newRealizations[i] = FastMath.sin(realizations[i]);
     return new RandomVariable(time, newRealizations);
   }
 }
 @Test
 public void testNoFlattening() throws OrekitException {
   final double r = 7000000.0;
   final double lambda = 2.345;
   final double phi = -1.23;
   final double cL = FastMath.cos(lambda);
   final double sL = FastMath.sin(lambda);
   final double cH = FastMath.cos(phi);
   final double sH = FastMath.sin(phi);
   checkCartesianToEllipsoidic(
       6378137.0, 0, r * cL * cH, r * sL * cH, r * sH, lambda, phi, r - 6378137.0);
 }
Example #3
0
  /**
   * ell2xyz Converts wgs84 ellipsoid cn to geocentric cartesian coord. input: - phi,lam,hei
   * (geodetic co-latitude, longitude, [rad] h [m] output: - cn XYZ
   */
  public static Point ell2xyz(final double phi, final double lambda, final double height)
      throws IllegalArgumentException {

    if (phi > Math.PI || phi < -Math.PI || lambda > Math.PI || lambda < -Math.PI) {
      throw new IllegalArgumentException(
          "Ellipsoid.ell2xyz : input values for phi/lambda have to be in radians!");
    }

    final double N = computeEllipsoidNormal(phi);
    final double Nph = N + height;
    final double A = Nph * FastMath.cos(phi);
    return new Point(
        A * FastMath.cos(lambda), A * FastMath.sin(lambda), (Nph - e2 * N) * FastMath.sin(phi));
  }
  @Test
  public void testEventsScheduling() {

    FirstOrderDifferentialEquations sincos =
        new FirstOrderDifferentialEquations() {

          public int getDimension() {
            return 2;
          }

          public void computeDerivatives(double t, double[] y, double[] yDot) {
            yDot[0] = y[1];
            yDot[1] = -y[0];
          }
        };

    SchedulingChecker sinChecker = new SchedulingChecker(0); // events at 0, PI, 2PI ...
    SchedulingChecker cosChecker = new SchedulingChecker(1); // events at PI/2, 3PI/2, 5PI/2 ...

    FirstOrderIntegrator integ = new DormandPrince853Integrator(0.001, 1.0, 1.0e-12, 0.0);
    integ.addEventHandler(sinChecker, 0.01, 1.0e-7, 100);
    integ.addStepHandler(sinChecker);
    integ.addEventHandler(cosChecker, 0.01, 1.0e-7, 100);
    integ.addStepHandler(cosChecker);
    double t0 = 0.5;
    double[] y0 = new double[] {FastMath.sin(t0), FastMath.cos(t0)};
    double t = 10.0;
    double[] y = new double[2];
    integ.integrate(sincos, t0, y0, t, y);
  }
Example #5
0
  /**
   * Computes the n-th roots of this complex number. The nth roots are defined by the formula:
   *
   * <pre>
   *  <code>
   *   z<sub>k</sub> = abs<sup>1/n</sup> (cos(phi + 2&pi;k/n) + i (sin(phi + 2&pi;k/n))
   *  </code>
   * </pre>
   *
   * for <i>{@code k=0, 1, ..., n-1}</i>, where {@code abs} and {@code phi} are respectively the
   * {@link #abs() modulus} and {@link #getArgument() argument} of this complex number. <br>
   * If one or both parts of this complex number is NaN, a list with just one element, {@link #NaN}
   * is returned. if neither part is NaN, but at least one part is infinite, the result is a
   * one-element list containing {@link #INF}.
   *
   * @param n Degree of root.
   * @return a List<Complex> of all {@code n}-th roots of {@code this}.
   * @throws NotPositiveException if {@code n <= 0}.
   * @since 2.0
   */
  public List<Complex> nthRoot(int n) throws NotPositiveException {

    if (n <= 0) {
      throw new NotPositiveException(LocalizedFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N, n);
    }

    final List<Complex> result = new ArrayList<Complex>();

    if (isNaN) {
      result.add(NaN);
      return result;
    }
    if (isInfinite()) {
      result.add(INF);
      return result;
    }

    // nth root of abs -- faster / more accurate to use a solver here?
    final double nthRootOfAbs = FastMath.pow(abs(), 1.0 / n);

    // Compute nth roots of complex number with k = 0, 1, ... n-1
    final double nthPhi = getArgument() / n;
    final double slice = 2 * FastMath.PI / n;
    double innerPart = nthPhi;
    for (int k = 0; k < n; k++) {
      // inner part
      final double realPart = nthRootOfAbs * FastMath.cos(innerPart);
      final double imaginaryPart = nthRootOfAbs * FastMath.sin(innerPart);
      result.add(createComplex(realPart, imaginaryPart));
      innerPart += slice;
    }

    return result;
  }
Example #6
0
 @Override
 public IComplexNumber exp() {
   IComplexNumber result = dup();
   double realExp = FastMath.exp(realComponent());
   return result.set(
       realExp * FastMath.cos(imaginaryComponent()), realExp * FastMath.sin(imaginaryComponent()));
 }
Example #7
0
  public double applyCalibration(
      final double v,
      final double rangeIndex,
      final double azimuthIndex,
      final double slantRange,
      final double satelliteHeight,
      final double sceneToEarthCentre,
      final double localIncidenceAngle,
      final String bandPolar,
      final Unit.UnitType bandUnit,
      int[] subSwathIndex) {

    double sigma = 0.0;
    if (bandUnit == Unit.UnitType.AMPLITUDE) {
      sigma = v * v;
    } else if (bandUnit == Unit.UnitType.INTENSITY
        || bandUnit == Unit.UnitType.REAL
        || bandUnit == Unit.UnitType.IMAGINARY) {
      sigma = v;
    } else if (bandUnit == Unit.UnitType.INTENSITY_DB) {
      sigma = FastMath.pow(10, v / 10.0); // convert dB to linear scale
    } else {
      throw new OperatorException("Unknown band unit");
    }

    if (incidenceAngleSelection.contains(USE_INCIDENCE_ANGLE_FROM_DEM)) {
      return sigma * calibrationFactor * FastMath.sin(localIncidenceAngle * Constants.DTOR);
    } else { // USE_INCIDENCE_ANGLE_FROM_ELLIPSOID
      return sigma * calibrationFactor;
    }
  }
Example #8
0
  public static Point ell2xyz(final double[] phiLambdaHeight) throws IllegalArgumentException {

    final double phi = phiLambdaHeight[0];
    final double lambda = phiLambdaHeight[1];
    final double height = phiLambdaHeight[2];

    if (phi > Math.PI || phi < -Math.PI || lambda > Math.PI || lambda < -Math.PI) {
      throw new IllegalArgumentException(
          "Ellipsoid.ell2xyz(): phi/lambda values has to be in radians!");
    }

    final double N = computeEllipsoidNormal(phi);
    final double Nph = N + height;
    final double A = Nph * FastMath.cos(phi);
    return new Point(
        A * FastMath.cos(lambda), A * FastMath.sin(lambda), (Nph - e2 * N) * FastMath.sin(phi));
  }
Example #9
0
 public double applyRetroCalibration(
     int x, int y, double v, String bandPolar, final Unit.UnitType bandUnit, int[] subSwathIndex) {
   if (incidenceAngleSelection.contains(USE_INCIDENCE_ANGLE_FROM_DEM)) {
     return v / FastMath.sin(incidenceAngle.getPixelDouble(x, y) * Constants.DTOR);
   } else { // USE_INCIDENCE_ANGLE_FROM_ELLIPSOID
     return v;
   }
 }
Example #10
0
  private List<Vector2D> makeCircles(double noise, double factor) {
    Preconditions.checkArgument(factor >= 0 && factor <= 1);

    NormalDistribution dist = new NormalDistribution(random, 0.0, noise, 1e-9);

    List<Vector2D> points = new ArrayList<>();
    double step = 2.0 * PI / (samples / 2.0 + 1);
    for (double angle = 0; angle < 2.0 * FastMath.PI; angle += step) {
      points.add(
          new Vector2D(FastMath.cos(angle), FastMath.sin(angle)).add(generateNoiseVector(dist)));
      points.add(
          new Vector2D(FastMath.cos(angle), FastMath.sin(angle))
              .scalarMultiply(factor)
              .add(generateNoiseVector(dist)));
    }
    return points;
  }
Example #11
0
  /**
   * Compute the <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
   * exponential function</a> of this complex number. Implements the formula:
   *
   * <pre>
   *  <code>
   *   exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i
   *  </code>
   * </pre>
   *
   * where the (real) functions on the right-hand side are {@link java.lang.Math#exp}, {@link
   * java.lang.Math#cos}, and {@link java.lang.Math#sin}. <br>
   * Returns {@link Complex#NaN} if either real or imaginary part of the input argument is {@code
   * NaN}. <br>
   * Infinite values in real or imaginary parts of the input may result in infinite or NaN values
   * returned in parts of the result.
   *
   * <pre>
   *  Examples:
   *  <code>
   *   exp(1 &plusmn; INFINITY i) = NaN + NaN i
   *   exp(INFINITY + i) = INFINITY + INFINITY i
   *   exp(-INFINITY + i) = 0 + 0i
   *   exp(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
   *  </code>
   * </pre>
   *
   * @return <code><i>e</i><sup>this</sup></code>.
   * @since 1.2
   */
  public Complex exp() {
    if (isNaN) {
      return NaN;
    }

    double expReal = FastMath.exp(real);
    return createComplex(expReal * FastMath.cos(imaginary), expReal * FastMath.sin(imaginary));
  }
Example #12
0
  /**
   * Compute the <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
   * hyperbolic sine</a> of this complex number. Implements the formula:
   *
   * <pre>
   *  <code>
   *   sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i
   *  </code>
   * </pre>
   *
   * where the (real) functions on the right-hand side are {@link java.lang.Math#sin}, {@link
   * java.lang.Math#cos}, {@link FastMath#cosh} and {@link FastMath#sinh}. <br>
   * Returns {@link Complex#NaN} if either real or imaginary part of the input argument is {@code
   * NaN}. <br>
   * Infinite values in real or imaginary parts of the input may result in infinite or NaN values
   * returned in parts of the result.
   *
   * <pre>
   *  Examples:
   *  <code>
   *   sinh(1 &plusmn; INFINITY i) = NaN + NaN i
   *   sinh(&plusmn;INFINITY + i) = &plusmn; INFINITY + INFINITY i
   *   sinh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
   *  </code>
   * </pre>
   *
   * @return the hyperbolic sine of {@code this}.
   * @since 1.2
   */
  public Complex sinh() {
    if (isNaN) {
      return NaN;
    }

    return createComplex(
        FastMath.sinh(real) * FastMath.cos(imaginary),
        FastMath.cosh(real) * FastMath.sin(imaginary));
  }
 private double sincHanning(final double x) {
   return x >= -halfKernelSize && x <= halfKernelSize
       ? x == 0
           ? 1.0
           : FastMath.sin(x * Math.PI)
               / (x * Math.PI)
               * (0.5 * (1.0 + FastMath.cos(DoublePI * x / kernelSize1)))
       : 0.0;
 }
Example #14
0
  public double execute(double in) throws DMLRuntimeException {
    switch (bFunc) {
      case SIN:
        return FASTMATH ? FastMath.sin(in) : Math.sin(in);
      case COS:
        return FASTMATH ? FastMath.cos(in) : Math.cos(in);
      case TAN:
        return FASTMATH ? FastMath.tan(in) : Math.tan(in);
      case ASIN:
        return FASTMATH ? FastMath.asin(in) : Math.asin(in);
      case ACOS:
        return FASTMATH ? FastMath.acos(in) : Math.acos(in);
      case ATAN:
        return Math.atan(in); // faster in Math
      case CEIL:
        return FASTMATH ? FastMath.ceil(in) : Math.ceil(in);
      case FLOOR:
        return FASTMATH ? FastMath.floor(in) : Math.floor(in);
      case LOG:
        return FASTMATH ? FastMath.log(in) : Math.log(in);
      case LOG_NZ:
        return (in == 0) ? 0 : FASTMATH ? FastMath.log(in) : Math.log(in);
      case ABS:
        return Math.abs(in); // no need for FastMath	
      case SIGN:
        return FASTMATH ? FastMath.signum(in) : Math.signum(in);
      case SQRT:
        return Math.sqrt(in); // faster in Math
      case EXP:
        return FASTMATH ? FastMath.exp(in) : Math.exp(in);
      case ROUND:
        return Math.round(in); // no need for FastMath

      case PLOGP:
        if (in == 0.0) return 0.0;
        else if (in < 0) return Double.NaN;
        else return (in * (FASTMATH ? FastMath.log(in) : Math.log(in)));

      case SPROP:
        // sample proportion: P*(1-P)
        return in * (1 - in);

      case SIGMOID:
        // sigmoid: 1/(1+exp(-x))
        return FASTMATH ? 1 / (1 + FastMath.exp(-in)) : 1 / (1 + Math.exp(-in));

      case SELP:
        // select positive: x*(x>0)
        return (in > 0) ? in : 0;

      default:
        throw new DMLRuntimeException("Builtin.execute(): Unknown operation: " + bFunc);
    }
  }
Example #15
0
  private List<Vector2D> makeMoons(double noise) {
    NormalDistribution dist = new NormalDistribution(random, 0.0, noise, 1e-9);

    int nSamplesOut = samples / 2;
    int nSamplesIn = samples - nSamplesOut;

    List<Vector2D> points = new ArrayList<>();
    double step = PI / (nSamplesOut / 2.0);
    for (double angle = 0; angle < PI; angle += step) {
      points.add(
          new Vector2D(FastMath.cos(angle), FastMath.sin(angle)).add(generateNoiseVector(dist)));
    }

    step = PI / (nSamplesIn / 2.0);
    for (double angle = 0; angle < PI; angle += step) {
      points.add(
          new Vector2D(1 - FastMath.cos(angle), 1 - FastMath.sin(angle) - 0.5)
              .add(generateNoiseVector(dist)));
    }
    return points;
  }
Example #16
0
  /**
   * Set this ray to a random diffuse reflection of the input ray.
   *
   * @param ray
   * @param random
   */
  public final void diffuseReflection(Ray ray, Random random) {
    set(ray);

    // get random point on unit disk
    double x1 = random.nextDouble();
    double x2 = random.nextDouble();
    double r = FastMath.sqrt(x1);
    double theta = 2 * Math.PI * x2;

    // project to point on hemisphere in tangent space
    double tx = r * FastMath.cos(theta);
    double ty = r * FastMath.sin(theta);
    double tz = FastMath.sqrt(1 - x1);

    // transform from tangent space to world space
    double xx, xy, xz;
    double ux, uy, uz;
    double vx, vy, vz;

    if (QuickMath.abs(n.x) > .1) {
      xx = 0;
      xy = 1;
      xz = 0;
    } else {
      xx = 1;
      xy = 0;
      xz = 0;
    }

    ux = xy * n.z - xz * n.y;
    uy = xz * n.x - xx * n.z;
    uz = xx * n.y - xy * n.x;

    r = 1 / FastMath.sqrt(ux * ux + uy * uy + uz * uz);

    ux *= r;
    uy *= r;
    uz *= r;

    vx = uy * n.z - uz * n.y;
    vy = uz * n.x - ux * n.z;
    vz = ux * n.y - uy * n.x;

    d.x = ux * tx + vx * ty + n.x * tz;
    d.y = uy * tx + vy * ty + n.y * tz;
    d.z = uz * tx + vz * ty + n.z * tz;

    x.scaleAdd(Ray.OFFSET, d, x);
    currentMaterial = prevMaterial;
    specular = false;
  }
Example #17
0
  /**
   * Compute the differential effect of J2 on an orbit.
   *
   * @param orbit1 original orbit at t₁, without differential J2
   * @return orbit at t₁, always taking the effect into account
   */
  private Orbit updateOrbit(final Orbit orbit1) {

    // convert current orbital state to equinoctial elements
    final EquinoctialOrbit original = (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(orbit1);

    // compute differential effect
    final AbsoluteDate date = original.getDate();
    final double dt = date.durationFrom(referenceDate);
    final double dPaRaan = (dPaDot + dRaanDot) * dt;
    final double cPaRaan = FastMath.cos(dPaRaan);
    final double sPaRaan = FastMath.sin(dPaRaan);
    final double dRaan = dRaanDot * dt;
    final double cRaan = FastMath.cos(dRaan);
    final double sRaan = FastMath.sin(dRaan);

    final double ex = original.getEquinoctialEx() * cPaRaan - original.getEquinoctialEy() * sPaRaan;
    final double ey = original.getEquinoctialEx() * sPaRaan + original.getEquinoctialEy() * cPaRaan;
    final double hx = original.getHx() * cRaan - original.getHy() * sRaan;
    final double hy = original.getHx() * sRaan + original.getHy() * cRaan;
    final double lambda = original.getLv() + dPaRaan;

    // build updated orbit
    final EquinoctialOrbit updated =
        new EquinoctialOrbit(
            original.getA(),
            ex,
            ey,
            hx,
            hy,
            lambda,
            PositionAngle.TRUE,
            original.getFrame(),
            date,
            original.getMu());

    // convert to required type
    return orbit1.getType().convertType(updated);
  }
    /**
     * Computes the value of the gradient at {@code x}. The components of the gradient vector are
     * the partial derivatives of the function with respect to each of the <em>parameters</em>
     * (amplitude, angular frequency and phase).
     *
     * @param x Value at which the gradient must be computed.
     * @param param Values of amplitude, angular frequency and phase.
     * @return the gradient vector at {@code x}.
     * @throws NullArgumentException if {@code param} is {@code null}.
     * @throws DimensionMismatchException if the size of {@code param} is not 3.
     */
    public double[] gradient(double x, double... param) {
      validateParameters(param);

      final double amplitude = param[0];
      final double omega = param[1];
      final double phase = param[2];

      final double xTimesOmegaPlusPhase = omega * x + phase;
      final double a = HarmonicOscillator.value(xTimesOmegaPlusPhase, 1);
      final double p = -amplitude * FastMath.sin(xTimesOmegaPlusPhase);
      final double w = p * x;

      return new double[] {a, w, p};
    }
Example #19
0
  /**
   * Convert xyz cartesian coordinates to Geodetic ellipsoid coordinates latlonh xyz2ell
   *
   * <p>Converts geocentric cartesian coordinates in the XXXX reference frame to geodetic
   * coordinates. method of bowring see globale en locale geodetische systemen input: - ellipsinfo,
   * xyz, (phi,lam,hei) output: - void (returned double[] lam<-pi,pi>, phi<-pi,pi>, hei)
   */
  public static double[] xyz2ell(final Point xyz) {

    final double r = Math.sqrt(xyz.x * xyz.x + xyz.y * xyz.y);
    final double nu = Math.atan2((xyz.z * a), (r * b));
    final double sinNu = FastMath.sin(nu);
    final double cosNu = FastMath.cos(nu);
    final double sin3 = sinNu * sinNu * sinNu;
    final double cos3 = cosNu * cosNu * cosNu;
    final double phi = Math.atan2((xyz.z + e2b * b * sin3), (r - e2 * a * cos3));
    final double lambda = Math.atan2(xyz.y, xyz.x);
    final double N = computeEllipsoidNormal(phi);
    final double height = (r / FastMath.cos(phi)) - N;

    return new double[] {phi, lambda, height};
  }
Example #20
0
  /**
   * Compute the <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
   * hyperbolic tangent</a> of this complex number. Implements the formula:
   *
   * <pre>
   *  <code>
   *   tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i
   *  </code>
   * </pre>
   *
   * where the (real) functions on the right-hand side are {@link FastMath#sin}, {@link
   * FastMath#cos}, {@link FastMath#cosh} and {@link FastMath#sinh}. <br>
   * Returns {@link Complex#NaN} if either real or imaginary part of the input argument is {@code
   * NaN}. <br>
   * Infinite values in real or imaginary parts of the input may result in infinite or NaN values
   * returned in parts of the result.
   *
   * <pre>
   *  Examples:
   *  <code>
   *   tanh(a &plusmn; INFINITY i) = NaN + NaN i
   *   tanh(&plusmn;INFINITY + bi) = &plusmn;1 + 0 i
   *   tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
   *   tanh(0 + (&pi;/2)i) = NaN + INFINITY i
   *  </code>
   * </pre>
   *
   * @return the hyperbolic tangent of {@code this}.
   * @since 1.2
   */
  public Complex tanh() {
    if (isNaN || Double.isInfinite(imaginary)) {
      return NaN;
    }
    if (real > 20.0) {
      return createComplex(1.0, 0.0);
    }
    if (real < -20.0) {
      return createComplex(-1.0, 0.0);
    }
    double real2 = 2.0 * real;
    double imaginary2 = 2.0 * imaginary;
    double d = FastMath.cosh(real2) + FastMath.cos(imaginary2);

    return createComplex(FastMath.sinh(real2) / d, FastMath.sin(imaginary2) / d);
  }
  @Test
  public void testModelsMerging() throws MaxCountExceededException, MathIllegalArgumentException {

    // theoretical solution: y[0] = cos(t), y[1] = sin(t)
    FirstOrderDifferentialEquations problem =
        new FirstOrderDifferentialEquations() {
          public void computeDerivatives(double t, double[] y, double[] dot) {
            dot[0] = -y[1];
            dot[1] = y[0];
          }

          public int getDimension() {
            return 2;
          }
        };

    // integrate backward from &pi; to 0;
    ContinuousOutputModel cm1 = new ContinuousOutputModel();
    FirstOrderIntegrator integ1 = new DormandPrince853Integrator(0, 1.0, 1.0e-8, 1.0e-8);
    integ1.addStepHandler(cm1);
    integ1.integrate(problem, FastMath.PI, new double[] {-1.0, 0.0}, 0, new double[2]);

    // integrate backward from 2&pi; to &pi;
    ContinuousOutputModel cm2 = new ContinuousOutputModel();
    FirstOrderIntegrator integ2 = new DormandPrince853Integrator(0, 0.1, 1.0e-12, 1.0e-12);
    integ2.addStepHandler(cm2);
    integ2.integrate(
        problem, 2.0 * FastMath.PI, new double[] {1.0, 0.0}, FastMath.PI, new double[2]);

    // merge the two half circles
    ContinuousOutputModel cm = new ContinuousOutputModel();
    cm.append(cm2);
    cm.append(new ContinuousOutputModel());
    cm.append(cm1);

    // check circle
    Assert.assertEquals(2.0 * FastMath.PI, cm.getInitialTime(), 1.0e-12);
    Assert.assertEquals(0, cm.getFinalTime(), 1.0e-12);
    Assert.assertEquals(cm.getFinalTime(), cm.getInterpolatedTime(), 1.0e-12);
    for (double t = 0; t < 2.0 * FastMath.PI; t += 0.1) {
      cm.setInterpolatedTime(t);
      double[] y = cm.getInterpolatedState();
      Assert.assertEquals(FastMath.cos(t), y[0], 1.0e-7);
      Assert.assertEquals(FastMath.sin(t), y[1], 1.0e-7);
    }
  }
Example #22
0
    /** {@inheritDoc} */
    public double[] gradient(final double x, final double... parameters) {
      final double[] gradient = new double[secularDegree + 1 + 2 * pulsations.length];

      // secular part
      double xN = 1.0;
      for (int i = 0; i <= secularDegree; ++i) {
        gradient[i] = xN;
        xN *= x;
      }

      // harmonic part
      for (int i = 0; i < pulsations.length; ++i) {
        gradient[secularDegree + 2 * i + 1] = FastMath.cos(pulsations[i] * x);
        gradient[secularDegree + 2 * i + 2] = FastMath.sin(pulsations[i] * x);
      }

      return gradient;
    }
Example #23
0
  /**
   * Simple constructor.
   *
   * <p>The {@code applyBefore} parameter is mainly used when the differential effect is associated
   * with a maneuver. In this case, the parameter must be set to {@code false}.
   *
   * @param orbit0 original orbit at reference date
   * @param orbit1 shifted orbit at reference date
   * @param applyBefore if true, effect is applied both before and after reference date, if false it
   *     is only applied after reference date
   * @param referenceRadius reference radius of the Earth for the potential model (m)
   * @param mu central attraction coefficient (m³/s²)
   * @param j2 un-normalized zonal coefficient (about +1.08e-3 for Earth)
   */
  public J2DifferentialEffect(
      final Orbit orbit0,
      final Orbit orbit1,
      final boolean applyBefore,
      final double referenceRadius,
      final double mu,
      final double j2) {

    this.referenceDate = orbit0.getDate();
    this.applyBefore = applyBefore;

    // extract useful parameters
    final double a0 = orbit0.getA();
    final double e0 = orbit0.getE();
    final double i0 = orbit0.getI();
    final double a1 = orbit1.getA();
    final double e1 = orbit1.getE();
    final double i1 = orbit1.getI();

    // compute reference drifts
    final double oMe2 = 1 - e0 * e0;
    final double ratio = referenceRadius / (a0 * oMe2);
    final double cosI = FastMath.cos(i0);
    final double sinI = FastMath.sin(i0);
    final double n = FastMath.sqrt(mu / a0) / a0;
    final double c = ratio * ratio * n * j2;
    final double refPaDot = 0.75 * c * (4 - 5 * sinI * sinI);
    final double refRaanDot = -1.5 * c * cosI;

    // differential model on perigee argument drift
    final double dPaDotDa = -3.5 * refPaDot / a0;
    final double dPaDotDe = 4 * refPaDot * e0 / oMe2;
    final double dPaDotDi = -7.5 * c * sinI * cosI;
    dPaDot = dPaDotDa * (a1 - a0) + dPaDotDe * (e1 - e0) + dPaDotDi * (i1 - i0);

    // differential model on ascending node drift
    final double dRaanDotDa = -3.5 * refRaanDot / a0;
    final double dRaanDotDe = 4 * refRaanDot * e0 / oMe2;
    final double dRaanDotDi = -refRaanDot * FastMath.tan(i0);
    dRaanDot = dRaanDotDa * (a1 - a0) + dRaanDotDe * (e1 - e0) + dRaanDotDi * (i1 - i0);
  }
Example #24
0
  /**
   * Get value truncated to first components.
   *
   * @param degree degree of polynomial secular part
   * @param harmonics number of harmonics terms to consider
   * @param time time parameter
   * @param parameters models parameters (must include all parameters, including the ones ignored
   *     due to model truncation)
   * @return truncated value
   */
  private double truncatedValue(
      final int degree, final int harmonics, final double time, final double... parameters) {

    double value = 0;

    // secular part
    double tN = 1.0;
    for (int i = 0; i <= degree; ++i) {
      value += parameters[i] * tN;
      tN *= time;
    }

    // harmonic part
    for (int i = 0; i < harmonics; ++i) {
      value +=
          parameters[secularDegree + 2 * i + 1] * FastMath.cos(pulsations[i] * time)
              + parameters[secularDegree + 2 * i + 2] * FastMath.sin(pulsations[i] * time);
    }

    return value;
  }
Example #25
0
  /**
   * Get second derivative truncated to first components.
   *
   * @param degree degree of polynomial secular part
   * @param harmonics number of harmonics terms to consider
   * @param time time parameter
   * @param parameters models parameters (must include all parameters, including the ones ignored
   *     due to model truncation)
   * @return truncated second derivative
   */
  private double truncatedSecondDerivative(
      final int degree, final int harmonics, final double time, final double... parameters) {

    double d2 = 0;

    // secular part
    double tN = 1.0;
    for (int i = 2; i <= degree; ++i) {
      d2 += (i - 1) * i * parameters[i] * tN;
      tN *= time;
    }

    // harmonic part
    for (int i = 0; i < harmonics; ++i) {
      d2 +=
          -pulsations[i]
              * pulsations[i]
              * (parameters[secularDegree + 2 * i + 1] * FastMath.cos(pulsations[i] * time)
                  + parameters[secularDegree + 2 * i + 2] * FastMath.sin(pulsations[i] * time));
    }

    return d2;
  }
Example #26
0
 private double computeCurvatureRadiusInMeridianPlane(final double phi) {
   return a * (1 - e2) / FastMath.pow((1 - e2 * FastMath.pow(FastMath.sin(phi), 2)), 3 / 2);
 }
Example #27
0
  /**
   * Computes the potential U derivatives.
   *
   * <p>The following elements are computed from expression 3.3 - (4).
   *
   * <pre>
   *  dU / da
   *  dU / dh
   *  dU / dk
   *  dU / dλ
   *  dU / dα
   *  dU / dβ
   *  dU / dγ
   *  </pre>
   *
   * @param date current date
   * @return potential derivatives
   * @throws OrekitException if an error occurs
   */
  private double[] computeUDerivatives(final AbsoluteDate date) throws OrekitException {

    // Potential derivatives
    double dUda = 0.;
    double dUdh = 0.;
    double dUdk = 0.;
    double dUdl = 0.;
    double dUdAl = 0.;
    double dUdBe = 0.;
    double dUdGa = 0.;

    // Compute only if there is at least one resonant tesseral
    if (!resOrders.isEmpty()) {
      // Gmsj and Hmsj polynomials
      final GHmsjPolynomials ghMSJ = new GHmsjPolynomials(k, h, alpha, beta, I);

      // GAMMAmns function
      final GammaMnsFunction gammaMNS = new GammaMnsFunction(fact, gamma, I);

      // R / a up to power degree
      final double[] roaPow = new double[maxDegree + 1];
      roaPow[0] = 1.;
      for (int i = 1; i <= maxDegree; i++) {
        roaPow[i] = roa * roaPow[i - 1];
      }

      // SUM over resonant terms {j,m}
      for (int m : resOrders) {

        // Resonant index for the current resonant order
        final int j = FastMath.max(1, (int) FastMath.round(ratio * m));

        // Phase angle
        final double jlMmt = j * lm - m * theta;
        final double sinPhi = FastMath.sin(jlMmt);
        final double cosPhi = FastMath.cos(jlMmt);

        // Potential derivatives components for a given resonant pair {j,m}
        double dUdaCos = 0.;
        double dUdaSin = 0.;
        double dUdhCos = 0.;
        double dUdhSin = 0.;
        double dUdkCos = 0.;
        double dUdkSin = 0.;
        double dUdlCos = 0.;
        double dUdlSin = 0.;
        double dUdAlCos = 0.;
        double dUdAlSin = 0.;
        double dUdBeCos = 0.;
        double dUdBeSin = 0.;
        double dUdGaCos = 0.;
        double dUdGaSin = 0.;

        // s-SUM from -sMin to sMax
        final int sMin = FastMath.min(maxEccPow - j, maxDegree);
        final int sMax = FastMath.min(maxEccPow + j, maxDegree);
        for (int s = 0; s <= sMax; s++) {

          // Compute the initial values for Hansen coefficients using newComb operators
          this.hansenObjects[s + maxDegree][j].computeInitValues(e2, chi, chi2);

          // n-SUM for s positive
          final double[][] nSumSpos =
              computeNSum(date, j, m, s, maxDegree, roaPow, ghMSJ, gammaMNS);
          dUdaCos += nSumSpos[0][0];
          dUdaSin += nSumSpos[0][1];
          dUdhCos += nSumSpos[1][0];
          dUdhSin += nSumSpos[1][1];
          dUdkCos += nSumSpos[2][0];
          dUdkSin += nSumSpos[2][1];
          dUdlCos += nSumSpos[3][0];
          dUdlSin += nSumSpos[3][1];
          dUdAlCos += nSumSpos[4][0];
          dUdAlSin += nSumSpos[4][1];
          dUdBeCos += nSumSpos[5][0];
          dUdBeSin += nSumSpos[5][1];
          dUdGaCos += nSumSpos[6][0];
          dUdGaSin += nSumSpos[6][1];

          // n-SUM for s negative
          if (s > 0 && s <= sMin) {
            // Compute the initial values for Hansen coefficients using newComb operators
            this.hansenObjects[maxDegree - s][j].computeInitValues(e2, chi, chi2);

            final double[][] nSumSneg =
                computeNSum(date, j, m, -s, maxDegree, roaPow, ghMSJ, gammaMNS);
            dUdaCos += nSumSneg[0][0];
            dUdaSin += nSumSneg[0][1];
            dUdhCos += nSumSneg[1][0];
            dUdhSin += nSumSneg[1][1];
            dUdkCos += nSumSneg[2][0];
            dUdkSin += nSumSneg[2][1];
            dUdlCos += nSumSneg[3][0];
            dUdlSin += nSumSneg[3][1];
            dUdAlCos += nSumSneg[4][0];
            dUdAlSin += nSumSneg[4][1];
            dUdBeCos += nSumSneg[5][0];
            dUdBeSin += nSumSneg[5][1];
            dUdGaCos += nSumSneg[6][0];
            dUdGaSin += nSumSneg[6][1];
          }
        }

        // Assembly of potential derivatives componants
        dUda += cosPhi * dUdaCos + sinPhi * dUdaSin;
        dUdh += cosPhi * dUdhCos + sinPhi * dUdhSin;
        dUdk += cosPhi * dUdkCos + sinPhi * dUdkSin;
        dUdl += cosPhi * dUdlCos + sinPhi * dUdlSin;
        dUdAl += cosPhi * dUdAlCos + sinPhi * dUdAlSin;
        dUdBe += cosPhi * dUdBeCos + sinPhi * dUdBeSin;
        dUdGa += cosPhi * dUdGaCos + sinPhi * dUdGaSin;
      }

      dUda *= -moa / a;
      dUdh *= moa;
      dUdk *= moa;
      dUdl *= moa;
      dUdAl *= moa;
      dUdBe *= moa;
      dUdGa *= moa;
    }

    return new double[] {dUda, dUdh, dUdk, dUdl, dUdAl, dUdBe, dUdGa};
  }
Example #28
0
  /** {@inheritDoc} */
  @Override
  public double[] getShortPeriodicVariations(final AbsoluteDate date, final double[] meanElements)
      throws OrekitException {

    // Initialise the short periodic variations
    final double[] shortPeriodicVariation = new double[] {0., 0., 0., 0., 0., 0.};

    // Compute only if there is at least one non-resonant tesseral or
    // only the m-daily tesseral should be taken into account
    if (!nonResOrders.isEmpty() || mDailiesOnly) {

      // Build an Orbit object from the mean elements
      final Orbit meanOrbit =
          OrbitType.EQUINOCTIAL.mapArrayToOrbit(
              meanElements, PositionAngle.MEAN, date, provider.getMu(), this.frame);

      // Build an auxiliary object
      final AuxiliaryElements aux = new AuxiliaryElements(meanOrbit, I);

      // Central body rotation angle from equation 2.7.1-(3)(4).
      final Transform t = bodyFrame.getTransformTo(aux.getFrame(), aux.getDate());
      final Vector3D xB = t.transformVector(Vector3D.PLUS_I);
      final Vector3D yB = t.transformVector(Vector3D.PLUS_J);
      final double currentTheta =
          FastMath.atan2(
              -f.dotProduct(yB) + I * g.dotProduct(xB), f.dotProduct(xB) + I * g.dotProduct(yB));

      // Add the m-daily contribution
      for (int m = 1; m <= maxOrderMdailyTesseralSP; m++) {
        // Phase angle
        final double jlMmt = -m * currentTheta;
        final double sinPhi = FastMath.sin(jlMmt);
        final double cosPhi = FastMath.cos(jlMmt);

        // compute contribution for each element
        for (int i = 0; i < 6; i++) {
          shortPeriodicVariation[i] +=
              tesseralSPCoefs.getCijm(i, 0, m, date) * cosPhi
                  + tesseralSPCoefs.getSijm(i, 0, m, date) * sinPhi;
        }
      }

      // loop through all non-resonant (j,m) pairs
      for (final Map.Entry<Integer, List<Integer>> entry : nonResOrders.entrySet()) {
        final int m = entry.getKey();
        final List<Integer> listJ = entry.getValue();

        for (int j : listJ) {
          // Phase angle
          final double jlMmt = j * meanElements[5] - m * currentTheta;
          final double sinPhi = FastMath.sin(jlMmt);
          final double cosPhi = FastMath.cos(jlMmt);

          // compute contribution for each element
          for (int i = 0; i < 6; i++) {
            shortPeriodicVariation[i] +=
                tesseralSPCoefs.getCijm(i, j, m, date) * cosPhi
                    + tesseralSPCoefs.getSijm(i, j, m, date) * sinPhi;
          }
        }
      }
    }

    return shortPeriodicVariation;
  }
Example #29
0
 /** {@inheritDoc} */
 public double value(double x) {
   return FastMath.sin(x);
 }
Example #30
0
 private static double computeEllipsoidNormal(final double phi) {
   return a / Math.sqrt(1.0 - e2 * FastMath.pow(FastMath.sin(phi), 2));
 }