View Javadoc
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  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus;
23  
24  import org.hipparchus.exception.MathIllegalArgumentException;
25  import org.hipparchus.util.FastMath;
26  import org.hipparchus.util.FieldSinCos;
27  import org.hipparchus.util.FieldSinhCosh;
28  
29  /**
30   * Interface representing a <a href="http://mathworld.wolfram.com/Field.html">field</a>
31   * with calculus capabilities (sin, cos, ...).
32   * @param <T> the type of the field elements
33   * @see FieldElement
34   * @since 1.7
35   */
36  public interface CalculusFieldElement<T extends FieldElement<T>> extends FieldElement<T> {
37  
38      /** Get the Archimedes constant π.
39       * <p>
40       * Archimedes constant is the ratio of a circle's circumference to its diameter.
41       * </p>
42       * @return Archimedes constant π
43       * @since 2.0
44       */
45      T getPi();
46  
47      /** Create an instance corresponding to a constant real value.
48       * @param value constant real value
49       * @return instance corresponding to a constant real value
50       */
51      T newInstance(double value);
52  
53      /** '+' operator.
54       * @param a right hand side parameter of the operator
55       * @return this+a
56       */
57      T add(double a);
58  
59      /** '-' operator.
60       * @param a right hand side parameter of the operator
61       * @return this-a
62       */
63      T subtract(double a);
64  
65      /** '&times;' operator.
66       * @param a right hand side parameter of the operator
67       * @return this&times;a
68       */
69      T multiply(double a);
70  
71      /** '&divide;' operator.
72       * @param a right hand side parameter of the operator
73       * @return this&divide;a
74       */
75      T divide(double a);
76  
77      /**
78       * Return the exponent of the instance, removing the bias.
79       * <p>
80       * For double numbers of the form 2<sup>x</sup>, the unbiased
81       * exponent is exactly x.
82       * </p>
83       * @return exponent for the instance, without bias
84       */
85      default int getExponent() {
86          return FastMath.getExponent(getReal());
87      }
88  
89      /**
90       * Multiply the instance by a power of 2.
91       * @param n power of 2
92       * @return this &times; 2<sup>n</sup>
93       */
94      T scalb(int n);
95  
96      /**
97       * Compute least significant bit (Unit in Last Position) for a number.
98       * @return ulp(this)
99       * @since 2.0
100      */
101     T ulp();
102 
103     /**
104      * Returns the hypotenuse of a triangle with sides {@code this} and {@code y}
105      * - sqrt(<i>this</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
106      * avoiding intermediate overflow or underflow.
107      *
108      * <ul>
109      * <li> If either argument is infinite, then the result is positive infinity.</li>
110      * <li> else, if either argument is NaN then the result is NaN.</li>
111      * </ul>
112      *
113      * @param y a value
114      * @return sqrt(<i>this</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
115      * @exception MathIllegalArgumentException if number of free parameters or orders are inconsistent
116      */
117     T hypot(T y)
118         throws MathIllegalArgumentException;
119 
120     /** {@inheritDoc} */
121     @Override
122     T reciprocal();
123 
124     /** Square root.
125      * @return square root of the instance
126      */
127     T sqrt();
128 
129     /** Cubic root.
130      * @return cubic root of the instance
131      */
132     T cbrt();
133 
134     /** N<sup>th</sup> root.
135      * @param n order of the root
136      * @return n<sup>th</sup> root of the instance
137      */
138     T rootN(int n);
139 
140     /** Power operation.
141      * @param p power to apply
142      * @return this<sup>p</sup>
143      */
144     T pow(double p);
145 
146     /** Integer power operation.
147      * @param n power to apply
148      * @return this<sup>n</sup>
149      */
150     T pow(int n);
151 
152     /** Power operation.
153      * @param e exponent
154      * @return this<sup>e</sup>
155      * @exception MathIllegalArgumentException if number of free parameters or orders are inconsistent
156      */
157     T pow(T e)
158         throws MathIllegalArgumentException;
159 
160     /** Exponential.
161      * @return exponential of the instance
162      */
163     T exp();
164 
165     /** Exponential minus 1.
166      * @return exponential minus one of the instance
167      */
168     T expm1();
169 
170     /** Natural logarithm.
171      * @return logarithm of the instance
172      */
173     T log();
174 
175     /** Shifted natural logarithm.
176      * @return logarithm of one plus the instance
177      */
178     T log1p();
179 
180     /** Base 10 logarithm.
181      * @return base 10 logarithm of the instance
182      */
183     T log10();
184 
185     /** Cosine operation.
186      * @return cos(this)
187      */
188     T cos();
189 
190     /** Sine operation.
191      * @return sin(this)
192      */
193     T sin();
194 
195     /** Combined Sine and Cosine operation.
196      * @return [sin(this), cos(this)]
197      * @since 1.4
198      */
199     FieldSinCos<T> sinCos();
200 
201     /** Tangent operation.
202      * @return tan(this)
203      */
204     T tan();
205 
206     /** Arc cosine operation.
207      * @return acos(this)
208      */
209     T acos();
210 
211     /** Arc sine operation.
212      * @return asin(this)
213      */
214     T asin();
215 
216     /** Arc tangent operation.
217      * @return atan(this)
218      */
219     T atan();
220 
221     /** Two arguments arc tangent operation.
222      * <p>
223      * Beware of the order or arguments! As this is based on a
224      * two-arguments functions, in order to be consistent with
225      * arguments order, the instance is the <em>first</em> argument
226      * and the single provided argument is the <em>second</em> argument.
227      * In order to be consistent with programming languages {@code atan2},
228      * this method computes {@code atan2(this, x)}, i.e. the instance
229      * represents the {@code y} argument and the {@code x} argument is
230      * the one passed as a single argument. This may seem confusing especially
231      * for users of Wolfram alpha, as this site is <em>not</em> consistent
232      * with programming languages {@code atan2} two-arguments arc tangent
233      * and puts {@code x} as its first argument.
234      * </p>
235      * @param x second argument of the arc tangent
236      * @return atan2(this, x)
237      * @exception MathIllegalArgumentException if number of free parameters or orders are inconsistent
238      */
239     T atan2(T x)
240         throws MathIllegalArgumentException;
241 
242     /** Hyperbolic cosine operation.
243      * @return cosh(this)
244      */
245     T cosh();
246 
247     /** Hyperbolic sine operation.
248      * @return sinh(this)
249      */
250     T sinh();
251 
252     /** Combined hyperbolic sine and sosine operation.
253      * @return [sinh(this), cosh(this)]
254      * @since 2.0
255      */
256     FieldSinhCosh<T> sinhCosh();
257 
258     /** Hyperbolic tangent operation.
259      * @return tanh(this)
260      */
261     T tanh();
262 
263     /** Inverse hyperbolic cosine operation.
264      * @return acosh(this)
265      */
266     T acosh();
267 
268     /** Inverse hyperbolic sine operation.
269      * @return asin(this)
270      */
271     T asinh();
272 
273     /** Inverse hyperbolic  tangent operation.
274      * @return atanh(this)
275      */
276     T atanh();
277 
278     /** Convert radians to degrees, with error of less than 0.5 ULP
279      *  @return instance converted into degrees
280      */
281     T toDegrees();
282 
283     /** Convert degrees to radians, with error of less than 0.5 ULP
284      *  @return instance converted into radians
285      */
286     T toRadians();
287 
288     /**
289      * Compute a linear combination.
290      * @param a Factors.
291      * @param b Factors.
292      * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
293      * @throws MathIllegalArgumentException if arrays dimensions don't match
294      */
295     T linearCombination(T[] a, T[] b)
296         throws MathIllegalArgumentException;
297 
298     /**
299      * Compute a linear combination.
300      * @param a Factors.
301      * @param b Factors.
302      * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
303      * @throws MathIllegalArgumentException if arrays dimensions don't match
304      */
305     T linearCombination(double[] a, T[] b)
306         throws MathIllegalArgumentException;
307 
308     /**
309      * Compute a linear combination.
310      * @param a1 first factor of the first term
311      * @param b1 second factor of the first term
312      * @param a2 first factor of the second term
313      * @param b2 second factor of the second term
314      * @return a<sub>1</sub>&times;b<sub>1</sub> +
315      * a<sub>2</sub>&times;b<sub>2</sub>
316      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement)
317      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement)
318      */
319     T linearCombination(T a1, T b1, T a2, T b2);
320 
321     /**
322      * Compute a linear combination.
323      * @param a1 first factor of the first term
324      * @param b1 second factor of the first term
325      * @param a2 first factor of the second term
326      * @param b2 second factor of the second term
327      * @return a<sub>1</sub>&times;b<sub>1</sub> +
328      * a<sub>2</sub>&times;b<sub>2</sub>
329      * @see #linearCombination(double, FieldElement, double, FieldElement, double, FieldElement)
330      * @see #linearCombination(double, FieldElement, double, FieldElement, double, FieldElement, double, FieldElement)
331      */
332     T linearCombination(double a1, T b1, double a2, T b2);
333 
334     /**
335      * Compute a linear combination.
336      * @param a1 first factor of the first term
337      * @param b1 second factor of the first term
338      * @param a2 first factor of the second term
339      * @param b2 second factor of the second term
340      * @param a3 first factor of the third term
341      * @param b3 second factor of the third term
342      * @return a<sub>1</sub>&times;b<sub>1</sub> +
343      * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
344      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement)
345      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement)
346      */
347     T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3);
348 
349     /**
350      * Compute a linear combination.
351      * @param a1 first factor of the first term
352      * @param b1 second factor of the first term
353      * @param a2 first factor of the second term
354      * @param b2 second factor of the second term
355      * @param a3 first factor of the third term
356      * @param b3 second factor of the third term
357      * @return a<sub>1</sub>&times;b<sub>1</sub> +
358      * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
359      * @see #linearCombination(double, FieldElement, double, FieldElement)
360      * @see #linearCombination(double, FieldElement, double, FieldElement, double, FieldElement, double, FieldElement)
361      */
362     T linearCombination(double a1, T b1, double a2, T b2, double a3, T b3);
363 
364     /**
365      * Compute a linear combination.
366      * @param a1 first factor of the first term
367      * @param b1 second factor of the first term
368      * @param a2 first factor of the second term
369      * @param b2 second factor of the second term
370      * @param a3 first factor of the third term
371      * @param b3 second factor of the third term
372      * @param a4 first factor of the fourth term
373      * @param b4 second factor of the fourth term
374      * @return a<sub>1</sub>&times;b<sub>1</sub> +
375      * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
376      * a<sub>4</sub>&times;b<sub>4</sub>
377      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement)
378      * @see #linearCombination(FieldElement, FieldElement, FieldElement, FieldElement, FieldElement, FieldElement)
379      */
380     T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3, T a4, T b4);
381 
382     /**
383      * Compute a linear combination.
384      * @param a1 first factor of the first term
385      * @param b1 second factor of the first term
386      * @param a2 first factor of the second term
387      * @param b2 second factor of the second term
388      * @param a3 first factor of the third term
389      * @param b3 second factor of the third term
390      * @param a4 first factor of the fourth term
391      * @param b4 second factor of the fourth term
392      * @return a<sub>1</sub>&times;b<sub>1</sub> +
393      * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
394      * a<sub>4</sub>&times;b<sub>4</sub>
395      * @see #linearCombination(double, FieldElement, double, FieldElement)
396      * @see #linearCombination(double, FieldElement, double, FieldElement, double, FieldElement)
397      */
398     T linearCombination(double a1, T b1, double a2, T b2, double a3, T b3, double a4, T b4);
399 
400     /** Get the smallest whole number larger than instance.
401      * @return ceil(this)
402      */
403     T ceil();
404 
405     /** Get the largest whole number smaller than instance.
406      * @return floor(this)
407      */
408     T floor();
409 
410     /** Get the whole number that is the nearest to the instance, or the even one if x is exactly half way between two integers.
411      * @return a double number r such that r is an integer r - 0.5 &le; this &le; r + 0.5
412      */
413     T rint();
414 
415     /** IEEE remainder operator.
416      * @param a right hand side parameter of the operator
417      * @return this - n &times; a where n is the closest integer to this/a
418      */
419     T remainder(double a);
420 
421     /** IEEE remainder operator.
422      * @param a right hand side parameter of the operator
423      * @return this - n &times; a where n is the closest integer to this/a
424      */
425     T remainder(T a);
426 
427     /** Compute the sign of the instance.
428      * The sign is -1 for negative numbers, +1 for positive numbers and 0 otherwise,
429      * for Complex number, it is extended on the unit circle (equivalent to z/|z|,
430      * with special handling for 0 and NaN)
431      * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
432      */
433     T sign();
434 
435     /**
436      * Returns the instance with the sign of the argument.
437      * A NaN {@code sign} argument is treated as positive.
438      *
439      * @param sign the sign for the returned value
440      * @return the instance with the same sign as the {@code sign} argument
441      */
442     T copySign(T sign);
443 
444     /**
445      * Returns the instance with the sign of the argument.
446      * A NaN {@code sign} argument is treated as positive.
447      *
448      * @param sign the sign for the returned value
449      * @return the instance with the same sign as the {@code sign} argument
450      */
451     T copySign(double sign);
452 
453     /**
454      * Check if the instance is infinite.
455      * @return true if the instance is infinite
456      */
457     default boolean isInfinite() {
458         return Double.isInfinite(getReal());
459     }
460 
461     /**
462      * Check if the instance is finite (neither infinite nor NaN).
463      * @return true if the instance is finite (neither infinite nor NaN)
464      * @since 2.0
465      */
466     default boolean isFinite() {
467         return Double.isFinite(getReal());
468     }
469 
470     /**
471      * Check if the instance is Not a Number.
472      * @return true if the instance is Not a Number
473      */
474     default boolean isNaN() {
475         return Double.isNaN(getReal());
476     }
477 
478     /** norm.
479      * @return norm(this)
480      * @since 2.0
481      */
482     default double norm() {
483         return abs().getReal();
484     }
485 
486     /** absolute value.
487      * <p>
488      * Just another name for {@link #norm()}
489      * </p>
490      * @return abs(this)
491      */
492     T abs();
493 
494     /** Get the closest long to instance real value.
495      * @return closest long to {@link #getReal()}
496      */
497     default long round() {
498         return FastMath.round(getReal());
499     }
500 
501 }