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