All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apfloat.FixedPrecisionApfloatHelper Maven / Gradle / Ivy

There is a newer version: 1.14.0
Show newest version
package org.apfloat;

import java.math.RoundingMode;

import org.apfloat.spi.Util;

/**
 * Fixed-precision mathematical functions for floating-point numbers.

* * All results of the mathematical operations are set to have the specified precision. * Also all input arguments are set to the specified precision before the operation. * If the specified precision is not infinite, this helper class also avoids * InfiniteExpansionException e.g. in case where it would happen with * ApfloatMath.acos(Apfloat.ZERO). * * @since 1.5 * @version 1.7.0 * @author Mikko Tommila */ public class FixedPrecisionApfloatHelper extends FixedPrecisionApcomplexHelper { /** * Constructs an apfloat fixed-precison helper with the specified precision. * The results of all mathematical operations are set to the specified precision. * * @param precision The precision of the results. * * @exception java.lang.IllegalArgumentException In case the precision is invalid. */ public FixedPrecisionApfloatHelper(long precision) throws IllegalArgumentException { super(precision); } /** * Returns the value with the specified precision. * * @param x The value. * * @return The value with to the specified precision. */ public Apfloat valueOf(Apfloat x) { return super.valueOf(x); } /** * Negation. * * @param x The value to negate. * * @return -x. */ public Apfloat negate(Apfloat x) throws ApfloatRuntimeException { return valueOf(x).negate(); } /** * Addition. * * @param x The first operand. * @param y The second operand. * * @return x + y. */ public Apfloat add(Apfloat x, Apfloat y) throws ApfloatRuntimeException { return valueOf(setPrecision(x).add(valueOf(y))); } /** * Subtraction. * * @param x The first operand. * @param y The second operand. * * @return x - y. */ public Apfloat subtract(Apfloat x, Apfloat y) throws ApfloatRuntimeException { return valueOf(setPrecision(x).subtract(setPrecision(y))); } /** * Multiplication. * * @param x The first operand. * @param y The second operand. * * @return x * y. */ public Apfloat multiply(Apfloat x, Apfloat y) throws ApfloatRuntimeException { return valueOf(setPrecision(x).multiply(setPrecision(y))); } /** * Division. * * @param x The first operand. * @param y The second operand. * * @return x / y. * * @exception java.lang.ArithmeticException If y is zero. */ public Apfloat divide(Apfloat x, Apfloat y) throws ArithmeticException, ApfloatRuntimeException { return valueOf(setPrecision(x).divide(setPrecision(y))); } /** * Power. * * @param x The first operand. * @param y The second operand. * * @return xy. * * @exception java.lang.ArithmeticException If x and y are zero, or x is negative. */ public Apfloat pow(Apfloat x, Apfloat y) throws ArithmeticException, ApfloatRuntimeException { Apfloat result = ApfloatHelper.checkPow(x, y, precision()); if (result != null) { return valueOf(result); } return exp(multiply(log(x), y)); } /** * Integer power. * * @param x The first operand. * @param n The second operand. * * @return xn. * * @exception java.lang.ArithmeticException If x and n are zero, or x is zero and n is negative. */ public Apfloat pow(Apfloat x, long n) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.pow(setPrecision(x), n)); } /** * Absolute value. * * @param x The operand. * * @return The absolute value of x. */ public Apfloat abs(Apfloat x) throws ApfloatRuntimeException { return ApfloatMath.abs(valueOf(x)); } /** * Arc cosine. * * @param x The operand. * * @return The arc cosine of x. * * @exception java.lang.ArithmeticException If the absolute value of x is more than one. */ public Apfloat acos(Apfloat x) throws ArithmeticException, ApfloatRuntimeException { if (x.signum() == 0) { // Zero always has infinite precision so when zero input causes nonzero output special care must be taken return divide(pi(x.radix()), new Apfloat(2, precision(), x.radix())); } return valueOf(ApfloatMath.acos(setPrecision(x))); } /** * Hyperbolic arc cosine. * * @param x The operand. * * @return The hyperbolic arc cosine of x. * * @exception java.lang.ArithmeticException If the x is less than one. */ public Apfloat acosh(Apfloat x) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.acosh(setPrecision(x))); } /** * Arc sine. * * @param x The operand. * * @return The arc sine of x. * * @exception java.lang.ArithmeticException If the absolute value of x is more than one. */ public Apfloat asin(Apfloat x) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.asin(setPrecision(x))); } /** * Hyperbolic arc sine. * * @param x The operand. * * @return The hyperbolic arc sine of x. */ public Apfloat asinh(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.asinh(setPrecision(x))); } /** * Arc tangent. * * @param x The operand. * * @return The arc tangent of x. */ public Apfloat atan(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.atan(setPrecision(x))); } /** * Hyperbolic arc tangent. * * @param x The operand. * * @return The hyperbolic arc tangent of x. * * @exception java.lang.ArithmeticException If the absolute value of x is equal to or more than one. */ public Apfloat atanh(Apfloat x) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.atanh(setPrecision(x))); } /** * Cube root. * * @param x The operand. * * @return The cube root of x. */ public Apfloat cbrt(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.cbrt(setPrecision(x))); } /** * Cosine. * * @param x The operand. * * @return The cosine of x. */ public Apfloat cos(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.cos(setTrigonometricPrecision(x))); } /** * Hyperbolic cosine. * * @param x The operand. * * @return The hyperbolic cosine of x. */ public Apfloat cosh(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.cosh(setExponentialPrecision(x))); } /** * Exponential function. * * @param x The operand. * * @return ex. */ public Apfloat exp(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.exp(setExponentialPrecision(x))); } /** * Natural logarithm. * * @param x The operand. * * @return The natural logarithm of x. * * @exception java.lang.ArithmeticException If x is less than or equal to zero. */ public Apfloat log(Apfloat x) throws ArithmeticException, ApfloatRuntimeException { // If x is close to one then result will actually have limited accuracy // So, if the argument would have more precision, it could be used, however checking for // this as well as the computation itself could be very time-consuming so we don't do it return valueOf(ApfloatMath.log(setPrecision(x))); } /** * Logarithm in specified base. * * @param x The operand. * @param b The base. * * @return The base-b logarithm of x. * * @exception java.lang.ArithmeticException If x or b is less than or equal to zero. * * @since 1.6 */ public Apfloat log(Apfloat x, Apfloat b) throws ArithmeticException, ApfloatRuntimeException { // If x or b is close to one then result will actually have limited accuracy // So, if the argument would have more precision, it could be used, however checking for // this as well as the computation itself could be very time-consuming so we don't do it return valueOf(ApfloatMath.log(setPrecision(x), setPrecision(b))); } /** * Sine. * * @param x The operand. * * @return The sine of x. */ public Apfloat sin(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.sin(setTrigonometricPrecision(x))); } /** * Hyperbolic sine. * * @param x The operand. * * @return The hyperbolic sine of x. */ public Apfloat sinh(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.sinh(setExponentialPrecision(x))); } /** * Square root. * * @param x The operand. * * @return The square root of x. * * @exception java.lang.ArithmeticException If x is negative. */ public Apfloat sqrt(Apfloat x) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.sqrt(setPrecision(x))); } /** * Tangent. * * @param x The operand. * * @return The tangent of x. * * @exception java.lang.ArithmeticException If x is π/2 + n π where n is an integer. */ public Apfloat tan(Apfloat x) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.tan(setTrigonometricPrecision(x))); } /** * Hyperbolic tangent. * * @param x The operand. * * @return The hyperbolic tangent of x. */ public Apfloat tanh(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.tanh(setExponentialPrecision(x))); } /** * Arithmetic-geometric mean. * * @param a The first operand. * @param b The first operand. * * @return The arithmetic-geometric mean of a and b. */ public Apfloat agm(Apfloat a, Apfloat b) throws ApfloatRuntimeException { return valueOf(ApfloatMath.agm(setPrecision(a), setPrecision(b))); } /** * Inverse root. * * @param x The operand. * @param n Which inverse root to take. * * @return x-1/n. * * @exception java.lang.ArithmeticException If x or n is zero, or x is negative and n is even. */ public Apfloat inverseRoot(Apfloat x, long n) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.inverseRoot(setPrecision(x), n)); } /** * Root. * * @param x The operand. * @param n Which root to take. * * @return x1/n. * * @exception java.lang.ArithmeticException If n is zero, or x is negative and n is even. */ public Apfloat root(Apfloat x, long n) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.root(setPrecision(x), n)); } /** * Move the radix point. * * @param x The operand. * @param scale The amount to move the radix point. * * @return x * x.radix()scale. */ public Apfloat scale(Apfloat x, long scale) throws ApfloatRuntimeException { return ApfloatMath.scale(valueOf(x), scale); } /** * Modulus. * * @param x The first operand. * @param y The second operand. * * @return x % y. */ public Apfloat mod(Apfloat x, Apfloat y) throws ApfloatRuntimeException { return fmod(x, y); } /** * Ceiling function. * * @param x The operand. * * @return The nearest integer greater than or equal to x. */ public Apfloat ceil(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.ceil(setPrecision(x))); } /** * Floor function. * * @param x The operand. * * @return The nearest integer less than or equal to x. */ public Apfloat floor(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.floor(setPrecision(x))); } /** * Truncate fractional part. * * @param x The operand. * * @return The nearest integer rounded towards zero from x. */ public Apfloat truncate(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.truncate(setPrecision(x))); } /** * Extract fractional part. * * @param x The operand. * * @return The fractional part of x. * * @since 1.7.0 */ public Apfloat frac(Apfloat x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.frac(x)); } /** * Round with specified rounding mode. * * @param x The operand. * @param roundingMode The rounding mode. * * @return x rounded with the specified rounding mode. * * @since 1.7.0 */ public Apfloat round(Apfloat x, RoundingMode roundingMode) throws ApfloatRuntimeException { return ApfloatMath.round(x, precision(), roundingMode); } /** * Angle of point. * * @param x The operand. * @param y The operand. * * @return The angle of the point (y, x). * * @exception java.lang.ArithmeticException If x and y are zero. */ public Apfloat atan2(Apfloat x, Apfloat y) throws ArithmeticException, ApfloatRuntimeException { return valueOf(ApfloatMath.atan2(setPrecision(x), setPrecision(y))); } /** * Copies the sign from one number to another. * * @param x The number to copy the sign to. * @param y The number to copy the sign from. * * @return x with the sign of y. */ public Apfloat copySign(Apfloat x, Apfloat y) throws ApfloatRuntimeException { return ApfloatMath.copySign(valueOf(x), y); } /** * Modulus. * * @param x The first operand. * @param y The second operand. * * @return x % y. */ public Apfloat fmod(Apfloat x, Apfloat y) throws ApfloatRuntimeException { return valueOf(ApfloatMath.fmod(x, setPrecision(y))); // Since x might be much larger in scale we do not limit precision yet here } /** * Split to integer and fractional parts. * * @param x The operand. * * @return An array of two numbers [i, f] where i is floor(x) and f is x - floor(x). */ public Apfloat[] modf(Apfloat x) throws ApfloatRuntimeException { if (x.scale() > 0) { long precision = Util.ifFinite(precision(), precision() + x.scale()); x = x.precision(precision); } else { x = setPrecision(x); } Apfloat[] modfs = ApfloatMath.modf(x); modfs[0] = valueOf(modfs[0]); modfs[1] = valueOf(modfs[1]); return modfs; } /** * Factorial. * * @param n The operand. * * @return n!. */ public Apfloat factorial(long n) throws ApfloatRuntimeException { // For low precision and high n the result could be approximated faster with Stirling's formula return valueOf(ApfloatMath.factorial(n, precision())); } /** * Factorial. * * @param n The operand. * @param radix The radix of the result. * * @return n!. */ public Apfloat factorial(long n, int radix) throws ApfloatRuntimeException { // For low precision and high n the result could be approximated faster with Stirling's formula return valueOf(ApfloatMath.factorial(n, precision(), radix)); } /** * π. * * @return π. */ public Apfloat pi() throws ApfloatRuntimeException { return super.pi(); } /** * π. * * @param radix The radix of the result. * * @return π. * * @exception java.lang.NumberFormatException If the radix is invalid. */ public Apfloat pi(int radix) throws NumberFormatException, ApfloatRuntimeException { return super.pi(radix); } /** * Logarithm. * * @param radix The radix of the result. * * @return log(radix). * * @exception java.lang.NumberFormatException If the radix is invalid. */ public Apfloat logRadix(int radix) throws NumberFormatException, ApfloatRuntimeException { return ApfloatMath.logRadix(precision(), radix); } /** * Fused multiply-add. * * @param a The first operand. * @param b The second operand. * @param c The third operand. * @param d The fourth operand. * * @return a * b + c * d. */ public Apfloat multiplyAdd(Apfloat a, Apfloat b, Apfloat c, Apfloat d) throws ApfloatRuntimeException { return valueOf(ApfloatMath.multiplyAdd(setPrecision(a), setPrecision(b), setPrecision(c), setPrecision(d))); } /** * Fused multiply-subtract. * * @param a The first operand. * @param b The second operand. * @param c The third operand. * @param d The fourth operand. * * @return a * b - c * d. */ public Apfloat multiplySubtract(Apfloat a, Apfloat b, Apfloat c, Apfloat d) throws ApfloatRuntimeException { return valueOf(ApfloatMath.multiplySubtract(setPrecision(a), setPrecision(b), setPrecision(c), setPrecision(d))); } /** * Product. * * @param x The operand(s). * * @return The product of the operands. */ public Apfloat product(Apfloat... x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.product(setPrecision(x))); } /** * Sum. * * @param x The operand(s). * * @return The sum of the operands. */ public Apfloat sum(Apfloat... x) throws ApfloatRuntimeException { return valueOf(ApfloatMath.sum(setPrecision(x))); } private Apfloat setPrecision(Apfloat x) throws ApfloatRuntimeException { return x.precision(precision()); } private Apfloat[] setPrecision(Apfloat[] x) throws ApfloatRuntimeException { Apfloat[] tmp = new Apfloat[x.length]; for (int i = 0; i < x.length; i++) { tmp[i] = setPrecision(x[i]); } return tmp; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy