CalculusFieldElement.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus;

  22. import org.hipparchus.exception.MathIllegalArgumentException;
  23. import org.hipparchus.util.FastMath;
  24. import org.hipparchus.util.FieldSinCos;
  25. import org.hipparchus.util.FieldSinhCosh;
  26. import org.hipparchus.util.MathArrays;

  27. /**
  28.  * Interface representing a <a href="http://mathworld.wolfram.com/Field.html">field</a>
  29.  * with calculus capabilities (sin, cos, ...).
  30.  * @param <T> the type of the field elements
  31.  * @see FieldElement
  32.  * @since 1.7
  33.  */
  34. public interface CalculusFieldElement<T extends FieldElement<T>> extends FieldElement<T> {

  35.     /** Get the addendum to the real value of the number.
  36.      * <p>
  37.      * The addendum is considered to be the part that when added back to
  38.      * the {@link #getReal() real part} recovers the instance. This means
  39.      * that when {@code e.getReal()} is finite (i.e. neither infinite
  40.      * nor NaN), then {@code e.getAddendum().add(e.getReal())} is {@code e}
  41.      * and {@code e.subtract(e.getReal())} is {@code e.getAddendum()}.
  42.      * Beware that for non-finite numbers, these two equalities may not hold.
  43.      * The first equality (with the addition), always holds even for infinity
  44.      * and NaNs if the real part is independent of the addendum (this is the
  45.      * case for all derivatives types, as well as for complex and Dfp, but it
  46.      * is not the case for Tuple and FieldTuple). The second equality (with
  47.      * the subtraction), generally doesn't hold for non-finite numbers, because
  48.      * the subtraction generates NaNs.
  49.      * </p>
  50.      * @return real value
  51.      * @since 4.0
  52.      */
  53.     T getAddendum();

  54.     /** Get the Archimedes constant π.
  55.      * <p>
  56.      * Archimedes constant is the ratio of a circle's circumference to its diameter.
  57.      * </p>
  58.      * @return Archimedes constant π
  59.      * @since 2.0
  60.      */
  61.     default T getPi() {
  62.         return newInstance(FastMath.PI);
  63.     }

  64.     /** Create an instance corresponding to a constant real value.
  65.      * @param value constant real value
  66.      * @return instance corresponding to a constant real value
  67.      */
  68.     T newInstance(double value);

  69.     /** '+' operator.
  70.      * @param a right hand side parameter of the operator
  71.      * @return this+a
  72.      */
  73.     default T add(double a) {
  74.         return add(newInstance(a));
  75.     }

  76.     /** '-' operator.
  77.      * @param a right hand side parameter of the operator
  78.      * @return this-a
  79.      */
  80.     default T subtract(double a) {
  81.         return subtract(newInstance(a));
  82.     }

  83.     /** {@inheritDoc} */
  84.     @Override
  85.     default T subtract(T a) {
  86.         return add(a.negate());
  87.     }

  88.     /** '&times;' operator.
  89.      * @param a right hand side parameter of the operator
  90.      * @return this&times;a
  91.      */
  92.     default T multiply(double a) {
  93.         return multiply(newInstance(a));
  94.     }

  95.     /** {@inheritDoc} */
  96.     @Override
  97.     default T multiply(int n) {
  98.         return multiply((double) n);
  99.     }

  100.     /** '&divide;' operator.
  101.      * @param a right hand side parameter of the operator
  102.      * @return this&divide;a
  103.      */
  104.     default T divide(double a) {
  105.         return divide(newInstance(a));
  106.     }

  107.     /**
  108.      * Return the exponent of the instance, removing the bias.
  109.      * <p>
  110.      * For double numbers of the form 2<sup>x</sup>, the unbiased
  111.      * exponent is exactly x.
  112.      * </p>
  113.      * @return exponent for the instance, without bias
  114.      */
  115.     default int getExponent() {
  116.         return FastMath.getExponent(getReal());
  117.     }

  118.     /**
  119.      * Multiply the instance by a power of 2.
  120.      * @param n power of 2
  121.      * @return this &times; 2<sup>n</sup>
  122.      */
  123.     T scalb(int n);

  124.     /**
  125.      * Compute least significant bit (Unit in Last Position) for a number.
  126.      * @return ulp(this)
  127.      * @since 2.0
  128.      */
  129.     default T ulp() {
  130.         return newInstance(FastMath.ulp(getReal()));
  131.     }

  132.     /**
  133.      * Returns the hypotenuse of a triangle with sides {@code this} and {@code y}
  134.      * - sqrt(<i>this</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
  135.      * avoiding intermediate overflow or underflow.
  136.      *
  137.      * <ul>
  138.      * <li> If either argument is infinite, then the result is positive infinity.</li>
  139.      * <li> else, if either argument is NaN then the result is NaN.</li>
  140.      * </ul>
  141.      *
  142.      * @param y a value
  143.      * @return sqrt(<i>this</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
  144.      * @exception MathIllegalArgumentException if number of free parameters or orders are inconsistent
  145.      */
  146.     T hypot(T y)
  147.         throws MathIllegalArgumentException;

  148.     /** {@inheritDoc} */
  149.     @Override
  150.     default T divide(T a) {
  151.         return multiply(a.reciprocal());
  152.     }

  153.     /** Square root.
  154.      * @return square root of the instance
  155.      */
  156.     default T sqrt() {
  157.         return rootN(2);
  158.     }

  159.     /** Cubic root.
  160.      * @return cubic root of the instance
  161.      */
  162.     default T cbrt() {
  163.         return rootN(3);
  164.     }

  165.     /** N<sup>th</sup> root.
  166.      * @param n order of the root
  167.      * @return n<sup>th</sup> root of the instance
  168.      */
  169.     default T rootN(int n) {
  170.         return pow(1. / n);
  171.     }

  172.     /** Compute this &times; this.
  173.      * @return a new element representing this &times; this
  174.      * @since 3.1
  175.      */
  176.     default T square() {
  177.         return pow(2);
  178.     }

  179.     /** Power operation.
  180.      * @param p power to apply
  181.      * @return this<sup>p</sup>
  182.      */
  183.     default T pow(double p) {
  184.         return pow(newInstance(p));
  185.     }

  186.     /** Integer power operation.
  187.      * @param n power to apply
  188.      * @return this<sup>n</sup>
  189.      */
  190.     default T pow(int n) {
  191.         return pow((double) n);
  192.     }

  193.     /** Power operation.
  194.      * @param e exponent
  195.      * @return this<sup>e</sup>
  196.      * @exception MathIllegalArgumentException if number of free parameters or orders are inconsistent
  197.      */
  198.     T pow(T e)
  199.         throws MathIllegalArgumentException;

  200.     /** Exponential.
  201.      * @return exponential of the instance
  202.      */
  203.     T exp();

  204.     /** Exponential minus 1.
  205.      * @return exponential minus one of the instance
  206.      */
  207.     T expm1();

  208.     /** Natural logarithm.
  209.      * @return logarithm of the instance
  210.      */
  211.     T log();

  212.     /** Shifted natural logarithm.
  213.      * @return logarithm of one plus the instance
  214.      */
  215.     T log1p();

  216.     /** Base 10 logarithm.
  217.      * @return base 10 logarithm of the instance
  218.      */
  219.     T log10();

  220.     /** Cosine operation.
  221.      * @return cos(this)
  222.      */
  223.     T cos();

  224.     /** Sine operation.
  225.      * @return sin(this)
  226.      */
  227.     T sin();

  228.     /** Combined Sine and Cosine operation.
  229.      * @return [sin(this), cos(this)]
  230.      * @since 1.4
  231.      */
  232.     default FieldSinCos<T> sinCos() {
  233.         return new FieldSinCos<>(sin(), cos());
  234.     }

  235.     /** Tangent operation.
  236.      * @return tan(this)
  237.      */
  238.     default T tan() {
  239.         return sin().divide(cos());
  240.     }

  241.     /** Arc cosine operation.
  242.      * @return acos(this)
  243.      */
  244.     T acos();

  245.     /** Arc sine operation.
  246.      * @return asin(this)
  247.      */
  248.     T asin();

  249.     /** Arc tangent operation.
  250.      * @return atan(this)
  251.      */
  252.     T atan();

  253.     /** Two arguments arc tangent operation.
  254.      * <p>
  255.      * Beware of the order or arguments! As this is based on a
  256.      * two-arguments functions, in order to be consistent with
  257.      * arguments order, the instance is the <em>first</em> argument
  258.      * and the single provided argument is the <em>second</em> argument.
  259.      * In order to be consistent with programming languages {@code atan2},
  260.      * this method computes {@code atan2(this, x)}, i.e. the instance
  261.      * represents the {@code y} argument and the {@code x} argument is
  262.      * the one passed as a single argument. This may seem confusing especially
  263.      * for users of Wolfram alpha, as this site is <em>not</em> consistent
  264.      * with programming languages {@code atan2} two-arguments arc tangent
  265.      * and puts {@code x} as its first argument.
  266.      * </p>
  267.      * @param x second argument of the arc tangent
  268.      * @return atan2(this, x)
  269.      * @exception MathIllegalArgumentException if number of free parameters or orders are inconsistent
  270.      */
  271.     T atan2(T x)
  272.         throws MathIllegalArgumentException;

  273.     /** Hyperbolic cosine operation.
  274.      * @return cosh(this)
  275.      */
  276.     T cosh();

  277.     /** Hyperbolic sine operation.
  278.      * @return sinh(this)
  279.      */
  280.     T sinh();

  281.     /** Combined hyperbolic sine and cosine operation.
  282.      * @return [sinh(this), cosh(this)]
  283.      * @since 2.0
  284.      */
  285.     default FieldSinhCosh<T> sinhCosh() {
  286.         return new FieldSinhCosh<>(sinh(), cosh());
  287.     }

  288.     /** Hyperbolic tangent operation.
  289.      * @return tanh(this)
  290.      */
  291.     default T tanh() {
  292.         return sinh().divide(cosh());
  293.     }

  294.     /** Inverse hyperbolic cosine operation.
  295.      * @return acosh(this)
  296.      */
  297.     T acosh();

  298.     /** Inverse hyperbolic sine operation.
  299.      * @return asin(this)
  300.      */
  301.     T asinh();

  302.     /** Inverse hyperbolic  tangent operation.
  303.      * @return atanh(this)
  304.      */
  305.     T atanh();

  306.     /** Convert radians to degrees, with error of less than 0.5 ULP
  307.      *  @return instance converted into degrees
  308.      */
  309.     default T toDegrees() {
  310.         return multiply(FastMath.toDegrees(1.));
  311.     }

  312.     /** Convert degrees to radians, with error of less than 0.5 ULP
  313.      *  @return instance converted into radians
  314.      */
  315.     default T toRadians() {
  316.         return multiply(FastMath.toRadians(1.));
  317.     }

  318.     /**
  319.      * Compute a linear combination.
  320.      * @param a Factors.
  321.      * @param b Factors.
  322.      * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
  323.      * @throws MathIllegalArgumentException if arrays dimensions don't match
  324.      */
  325.     T linearCombination(T[] a, T[] b)
  326.         throws MathIllegalArgumentException;

  327.     /**
  328.      * Compute a linear combination.
  329.      * @param a Factors.
  330.      * @param b Factors.
  331.      * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
  332.      * @throws MathIllegalArgumentException if arrays dimensions don't match
  333.      */
  334.     default T linearCombination(double[] a, T[] b) throws MathIllegalArgumentException {
  335.         final T[] newInstances = MathArrays.buildArray(getField(), a.length);
  336.         for (int i = 0; i < a.length; i++) {
  337.             newInstances[i] = newInstance(a[i]);
  338.         }
  339.         return linearCombination(newInstances, b);
  340.     }

  341.     /**
  342.      * Compute a linear combination.
  343.      * @param a1 first factor of the first term
  344.      * @param b1 second factor of the first term
  345.      * @param a2 first factor of the second term
  346.      * @param b2 second factor of the second term
  347.      * @return a<sub>1</sub>&times;b<sub>1</sub> +
  348.      * a<sub>2</sub>&times;b<sub>2</sub>
  349.      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement)
  350.      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement)
  351.      */
  352.     T linearCombination(T a1, T b1, T a2, T b2);

  353.     /**
  354.      * Compute a linear combination.
  355.      * @param a1 first factor of the first term
  356.      * @param b1 second factor of the first term
  357.      * @param a2 first factor of the second term
  358.      * @param b2 second factor of the second term
  359.      * @return a<sub>1</sub>&times;b<sub>1</sub> +
  360.      * a<sub>2</sub>&times;b<sub>2</sub>
  361.      * @see #linearCombination(double, FieldElement, double, FieldElement, double, FieldElement)
  362.      * @see #linearCombination(double, FieldElement, double, FieldElement, double, FieldElement, double, FieldElement)
  363.      */
  364.     default T linearCombination(double a1, T b1, double a2, T b2) {
  365.         return linearCombination(newInstance(a1), b1, newInstance(a2), b2);
  366.     }

  367.     /**
  368.      * Compute a linear combination.
  369.      * @param a1 first factor of the first term
  370.      * @param b1 second factor of the first term
  371.      * @param a2 first factor of the second term
  372.      * @param b2 second factor of the second term
  373.      * @param a3 first factor of the third term
  374.      * @param b3 second factor of the third term
  375.      * @return a<sub>1</sub>&times;b<sub>1</sub> +
  376.      * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
  377.      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement)
  378.      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement)
  379.      */
  380.     T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3);

  381.     /**
  382.      * Compute a linear combination.
  383.      * @param a1 first factor of the first term
  384.      * @param b1 second factor of the first term
  385.      * @param a2 first factor of the second term
  386.      * @param b2 second factor of the second term
  387.      * @param a3 first factor of the third term
  388.      * @param b3 second factor of the third term
  389.      * @return a<sub>1</sub>&times;b<sub>1</sub> +
  390.      * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
  391.      * @see #linearCombination(double, FieldElement, double, FieldElement)
  392.      * @see #linearCombination(double, FieldElement, double, FieldElement, double, FieldElement, double, FieldElement)
  393.      */
  394.     default T linearCombination(double a1, T b1, double a2, T b2, double a3, T b3) {
  395.         return linearCombination(newInstance(a1), b1, newInstance(a2), b2, newInstance(a3), b3);
  396.     }

  397.     /**
  398.      * Compute a linear combination.
  399.      * @param a1 first factor of the first term
  400.      * @param b1 second factor of the first term
  401.      * @param a2 first factor of the second term
  402.      * @param b2 second factor of the second term
  403.      * @param a3 first factor of the third term
  404.      * @param b3 second factor of the third term
  405.      * @param a4 first factor of the fourth term
  406.      * @param b4 second factor of the fourth term
  407.      * @return a<sub>1</sub>&times;b<sub>1</sub> +
  408.      * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
  409.      * a<sub>4</sub>&times;b<sub>4</sub>
  410.      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement)
  411.      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement)
  412.      */
  413.     T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3, T a4, T b4);

  414.     /**
  415.      * Compute a linear combination.
  416.      * @param a1 first factor of the first term
  417.      * @param b1 second factor of the first term
  418.      * @param a2 first factor of the second term
  419.      * @param b2 second factor of the second term
  420.      * @param a3 first factor of the third term
  421.      * @param b3 second factor of the third term
  422.      * @param a4 first factor of the fourth term
  423.      * @param b4 second factor of the fourth term
  424.      * @return a<sub>1</sub>&times;b<sub>1</sub> +
  425.      * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
  426.      * a<sub>4</sub>&times;b<sub>4</sub>
  427.      * @see #linearCombination(double, FieldElement, double, FieldElement)
  428.      * @see #linearCombination(double, FieldElement, double, FieldElement, double, FieldElement)
  429.      */
  430.     default T linearCombination(double a1, T b1, double a2, T b2, double a3, T b3, double a4, T b4) {
  431.         return linearCombination(newInstance(a1), b1, newInstance(a2), b2, newInstance(a3), b3,
  432.                 newInstance(a4), b4);
  433.     }

  434.     /** Get the smallest whole number larger than instance.
  435.      * @return ceil(this)
  436.      */
  437.     default T ceil() {
  438.         return newInstance(FastMath.ceil(getReal()));
  439.     }

  440.     /** Get the largest whole number smaller than instance.
  441.      * @return floor(this)
  442.      */
  443.     default T floor() {
  444.         return newInstance(FastMath.floor(getReal()));
  445.     }

  446.     /** Get the whole number that is the nearest to the instance, or the even one if x is exactly half way between two integers.
  447.      * @return a double number r such that r is an integer r - 0.5 &le; this &le; r + 0.5
  448.      */
  449.     default T rint() {
  450.         return newInstance(FastMath.rint(getReal()));
  451.     }

  452.     /** IEEE remainder operator.
  453.      * @param a right hand side parameter of the operator
  454.      * @return this - n &times; a where n is the closest integer to this/a
  455.      */
  456.     T remainder(double a);

  457.     /** IEEE remainder operator.
  458.      * @param a right hand side parameter of the operator
  459.      * @return this - n &times; a where n is the closest integer to this/a
  460.      */
  461.     T remainder(T a);

  462.     /** Compute the sign of the instance.
  463.      * The sign is -1 for negative numbers, +1 for positive numbers and 0 otherwise,
  464.      * for Complex number, it is extended on the unit circle (equivalent to z/|z|,
  465.      * with special handling for 0 and NaN)
  466.      * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
  467.      */
  468.     default T sign() {
  469.         return newInstance(FastMath.signum(getReal()));
  470.     }

  471.     /**
  472.      * Returns the instance with the sign of the argument.
  473.      * A NaN {@code sign} argument is treated as positive.
  474.      *
  475.      * @param sign the sign for the returned value
  476.      * @return the instance with the same sign as the {@code sign} argument
  477.      */
  478.     T copySign(T sign);

  479.     /**
  480.      * Returns the instance with the sign of the argument.
  481.      * A NaN {@code sign} argument is treated as positive.
  482.      *
  483.      * @param sign the sign for the returned value
  484.      * @return the instance with the same sign as the {@code sign} argument
  485.      */
  486.     default T copySign(double sign) {
  487.         return copySign(newInstance(sign));
  488.     }

  489.     /**
  490.      * Check if the instance is infinite.
  491.      * @return true if the instance is infinite
  492.      */
  493.     default boolean isInfinite() {
  494.         return Double.isInfinite(getReal());
  495.     }

  496.     /**
  497.      * Check if the instance is finite (neither infinite nor NaN).
  498.      * @return true if the instance is finite (neither infinite nor NaN)
  499.      * @since 2.0
  500.      */
  501.     default boolean isFinite() {
  502.         return Double.isFinite(getReal());
  503.     }

  504.     /**
  505.      * Check if the instance is Not a Number.
  506.      * @return true if the instance is Not a Number
  507.      */
  508.     default boolean isNaN() {
  509.         return Double.isNaN(getReal());
  510.     }

  511.     /** norm.
  512.      * @return norm(this)
  513.      * @since 2.0
  514.      */
  515.     default double norm() {
  516.         return abs().getReal();
  517.     }

  518.     /** absolute value.
  519.      * @return abs(this)
  520.      */
  521.     T abs();

  522.     /** Get the closest long to instance real value.
  523.      * @return closest long to {@link #getReal()}
  524.      */
  525.     default long round() {
  526.         return FastMath.round(getReal());
  527.     }

  528. }