
cc.redberry.core.number.NumberUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Redberry is an open source computer algebra system designed for tensor
manipulation. It implements basic computer algebra system routines as well as
complex tools for real computations in physics.
This is Redberry core, which contains the implementation of the basic
computer algebra routines and general-purpose transformations.
/*
* Redberry: symbolic tensor computations.
*
* Copyright (c) 2010-2015:
* Stanislav Poslavsky
* Bolotin Dmitriy
*
* This file is part of Redberry.
*
* Redberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Redberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Redberry. If not, see .
*/
package cc.redberry.core.number;
import cc.redberry.core.tensor.Tensor;
import org.apache.commons.math3.fraction.BigFraction;
import java.math.BigInteger;
/**
* @author Stanislav Poslavsky
*/
public final class NumberUtils {
private NumberUtils() {
}
/**
* Checks that an object is not null.
*
* @param o Object to be checked.
* @throws NullPointerException if {@code o} is {@code null}.
*/
static void checkNotNull(Object o)
throws NullPointerException {
if (o == null)
throw new NullPointerException();
}
public static Numeric createNumeric(double d) {
//todo review performance profit
if (d == 0)
return Numeric.ZERO;
else if (d == 1)
return Numeric.ONE;
else if (d == Double.POSITIVE_INFINITY)
return Numeric.POSITIVE_INFINITY;
else if (d == Double.NEGATIVE_INFINITY)
return Numeric.NEGATIVE_INFINITY;
else if (d != d)// d is NaN
return Numeric.NaN;
else
return new Numeric(d);
}
public static Rational createRational(BigFraction fraction) {
//FUTURE investigate performance
if (fraction.getNumerator().equals(BigInteger.ZERO))
return Rational.ZERO;
if (BigFraction.ONE.equals(fraction))
return Rational.ONE;
return new Rational(fraction);
}
private final static BigInteger TWO = new BigInteger("2");
/**
* Computes the integer square root of a number.
*
* @param n The number.
* @return The integer square root, i.e. the largest number whose square
* doesn't exceed n.
*/
public static BigInteger sqrt(BigInteger n) {
if (n.signum() >= 0) {
final int bitLength = n.bitLength();
BigInteger root = BigInteger.ONE.shiftLeft(bitLength / 2);
while (!isSqrtXXX(n, root))
root = root.add(n.divide(root)).divide(TWO);
return root;
} else
throw new ArithmeticException("square root of negative number");
}
private static boolean isSqrtXXX(BigInteger n, BigInteger root) {
final BigInteger lowerBound = root.pow(2);
final BigInteger upperBound = root.add(BigInteger.ONE).pow(2);
return lowerBound.compareTo(n) <= 0
&& n.compareTo(upperBound) < 0;
}
public static boolean isSqrt(BigInteger n, BigInteger root) {
return n.compareTo(root.pow(2)) == 0;
}
public static BigInteger TWO_BIG_INT = new BigInteger("2");
public static boolean isIntegerOdd(Complex complex) {
if (complex.isInteger())
return !complex.getReal().bigIntValue().mod(TWO_BIG_INT).equals(BigInteger.ZERO);
return false;
}
public static boolean isIntegerEven(Complex complex) {
if (complex.isInteger())
return complex.getReal().bigIntValue().mod(TWO_BIG_INT).equals(BigInteger.ZERO);
return false;
}
public static boolean isZeroOrIndeterminate(Complex complex) {
return complex.isZero() || complex.isInfinite() || complex.isNaN();
}
public static boolean isIndeterminate(Complex complex) {
return complex.isInfinite() || complex.isNaN();
}
public static boolean isRealNegative(Complex complex) {
return complex.isReal() && complex.getReal().signum() < 0;
}
public static boolean isRealNumerical(Tensor tensor) {
if (tensor instanceof Complex && ((Complex) tensor).isReal())
return true;
for (Tensor t : tensor)
if (!isRealNumerical(t))
return false;
return true;
}
public static BigInteger pow(BigInteger base, BigInteger exponent) {
BigInteger result = BigInteger.ONE;
while (exponent.signum() > 0) {
if (exponent.testBit(0)) result = result.multiply(base);
base = base.multiply(base);
exponent = exponent.shiftRight(1);
}
return result;
}
public static long pow(long base, long exponent) {
long result = 1;
while (exponent > 0) {
if (exponent % 2 == 1) result *= base;
base *= base;
exponent >>= 1;
}
return result;
}
public static BigInteger factorial(int n) {
BigInteger result = BigInteger.ONE;
while (n != 0) {
result = result.multiply(BigInteger.valueOf(n));
--n;
}
return result;
}
// public static Boolean getSignOfNumerical(Tensor tensor) {
// //todo write better code
// if (!isRealNumerical(tensor))
// return null;
// return getSignOfNumerical1(tensor);
// }
//
// private static Boolean getSignOfNumerical1(Tensor tensor) {
// if (tensor instanceof Complex) {
// Complex complex = (Complex) tensor;
// return complex.isReal() && complex.getReal().signum() < 0;
// }
// if (tensor instanceof Power) {
// Tensor base = tensor.get(0),
// exponent = tensor.get(1);
// Boolean baseSign = getSignOfNumerical1(base);
// if (baseSign == null)
// return null;
//
// //base is positive
// if (baseSign == false)
// return false;
//
// //base is negative
// if (!(exponent instanceof Complex))
// return null;
//
// Real real = ((Complex) exponent).getReal();
// if (real.isNumeric())
// return null;
// Rational rational = (Rational) real;
// rational.ge
//
// return null;
// }
// }
//
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy