use of org.hipparchus.fraction.BigFraction in project symja_android_library by axkr.
the class AbstractFractionSym method valueOfExact.
/**
* Rationalizes the given double value exactly.
* <p>
* This methods returns an {@link IExpr} that, when being evaluated to a double value (using
* {@link IExpr#evalDouble()}), results to the exact same value (per bit) as the given one.
* <p>
* Although it is not possible to express all real numbers as a fraction of two integers, it is
* possible for all finite floating-point numbers to be expressed as fraction with exact same
* value, because floating-point numbers are finite in their representation and therefore cannot
* express all real numbers exactly. But this allows the exact representation as a fraction.<br>
* Nevertheless this may lead to unexpected results. For example the value {@code 0.7} is
* rationalized to {@code 3152519739159347/4503599627370496} and not the expected {@code 7/10}.
* </p>
* </p>
* There is no guarantee made about the specific type of the returned expression. Not all possible
* values of a double, especially small ones, can be expressed as {@link IFraction} in such way
* that it evaluates to the same double value. In such cases the value is expressed by
* {@code mantissa * 2 ^ power}.
*
* @param value the double value to convert
* @return an IExpr that evaluates to the exact same double value
*/
public static IExpr valueOfExact(double value) {
IExpr ii = getInfiniteOrInteger(value);
if (ii != null) {
return ii;
}
// computes exact fraction representation
BigFraction exactFraction = new BigFraction(value);
int denominatorExponent2 = exactFraction.getDenominator().bitLength() - 1;
if (denominatorExponent2 <= Double.MAX_EXPONENT) {
return valueOf(exactFraction);
}
// The fractions denominator cannot be expressed as double value and would lead to an infinite
// denominator double-value this has the consequence that the fraction will become return zero
// when evaluated to double. Instead express the value as mantissa2 * 2 ^ exp2
int exp2 = Math.getExponent(value);
double mantissa2 = value * Math.pow(2, -exp2);
// try shortcut
IExpr mantissaFraction = getInfiniteOrInteger(mantissa2);
if (mantissaFraction == null) {
mantissaFraction = valueOf(new BigFraction(mantissa2));
}
return F.Times(mantissaFraction, F.Power(F.C2, F.ZZ(exp2)));
}
use of org.hipparchus.fraction.BigFraction in project symja_android_library by axkr.
the class BigFractionSym method add.
/**
* Return a new rational representing <code>this + other</code>.
*
* @param other Rational to add.
* @return Sum of <code>this</code> and <code>other</code>.
*/
@Override
public IFraction add(IFraction other) {
if (other.isZero()) {
return this;
}
if (other instanceof BigFractionSym) {
BigFraction res = fFraction.add(((BigFractionSym) other).toBigFraction());
return valueOf(res);
}
BigInteger tdenom = toBigDenominator();
BigInteger odenom = other.toBigDenominator();
if (tdenom.equals(odenom)) {
return valueOf(toBigNumerator().add(other.toBigNumerator()), tdenom);
}
BigInteger gcd = tdenom.gcd(odenom);
BigInteger tdenomgcd = tdenom.divide(gcd);
BigInteger odenomgcd = odenom.divide(gcd);
BigInteger newnum = toBigNumerator().multiply(odenomgcd).add(other.toBigNumerator().multiply(tdenomgcd));
BigInteger newdenom = tdenom.multiply(odenomgcd);
return valueOf(newnum, newdenom);
}
use of org.hipparchus.fraction.BigFraction in project symja_android_library by axkr.
the class BigFractionSym method compareTo.
@Override
public int compareTo(IExpr expr) {
if (expr instanceof IRational) {
if (expr instanceof IFraction) {
BigInteger valthis = toBigNumerator().multiply(((IFraction) expr).toBigDenominator());
BigInteger valo = ((IFraction) expr).toBigNumerator().multiply(toBigDenominator());
return valthis.compareTo(valo);
}
if (expr instanceof IInteger) {
return fFraction.compareTo(new BigFraction(((IInteger) expr).toBigNumerator(), BigInteger.ONE));
}
}
if (expr.isReal()) {
return Double.compare(fFraction.doubleValue(), ((ISignedNumber) expr).doubleValue());
}
return -1;
// return super.compareTo(expr);
}
use of org.hipparchus.fraction.BigFraction in project symja_android_library by axkr.
the class PolynomialsUtils method computeUpToDegree.
/**
* Compute polynomial coefficients up to a given degree.
*
* @param degree maximal degree
* @param maxDegree current maximal degree
* @param generator recurrence coefficients generator
* @param coefficients list where the computed coefficients should be appended
*/
private static void computeUpToDegree(final int degree, final int maxDegree, final RecurrenceCoefficientsGenerator generator, final List<BigFraction> coefficients) {
int startK = (maxDegree - 1) * maxDegree / 2;
for (int k = maxDegree; k < degree; ++k) {
// start indices of two previous polynomials Pk(X) and Pk-1(X)
int startKm1 = startK;
startK += k;
// Pk+1(X) = (a[0] + a[1] X) Pk(X) - a[2] Pk-1(X)
BigFraction[] ai = generator.generate(k);
BigFraction ck = coefficients.get(startK);
BigFraction ckm1 = coefficients.get(startKm1);
// degree 0 coefficient
coefficients.add(ck.multiply(ai[0]).subtract(ckm1.multiply(ai[2])));
// degree 1 to degree k-1 coefficients
for (int i = 1; i < k; ++i) {
final BigFraction ckPrev = ck;
ck = coefficients.get(startK + i);
ckm1 = coefficients.get(startKm1 + i);
coefficients.add(ck.multiply(ai[0]).add(ckPrev.multiply(ai[1])).subtract(ckm1.multiply(ai[2])));
if (coefficients.size() > Config.MAX_AST_SIZE) {
ASTElementLimitExceeded.throwIt(coefficients.size());
}
}
// degree k coefficient
final BigFraction ckPrev = ck;
ck = coefficients.get(startK + k);
coefficients.add(ck.multiply(ai[0]).add(ckPrev.multiply(ai[1])));
// degree k+1 coefficient
coefficients.add(ck.multiply(ai[1]));
if (coefficients.size() > Config.MAX_AST_SIZE) {
ASTElementLimitExceeded.throwIt(coefficients.size());
}
}
}
use of org.hipparchus.fraction.BigFraction in project symja_android_library by axkr.
the class TeXFormFactory method convert.
public void convert(final StringBuffer buf, final Object o, final int precedence) {
if (o instanceof IExpr) {
IExpr expr = (IExpr) o;
String str = CONSTANT_EXPRS.get(expr);
if (str != null) {
buf.append(str);
return;
}
}
if (o instanceof IAST) {
final IAST f = ((IAST) o);
IExpr h = f.head();
if (h.isSymbol()) {
IConverter converter = reflection(((ISymbol) h).getSymbolName());
if ((converter != null) && (converter.convert(buf, f, precedence))) {
return;
}
}
convertAST(buf, f);
return;
}
if (o instanceof IInteger) {
convertInteger(buf, (IInteger) o, precedence);
return;
}
if (o instanceof IFraction) {
convertFraction(buf, (IFraction) o, precedence);
return;
}
if (o instanceof INum) {
convertDouble(buf, (INum) o, precedence);
return;
}
if (o instanceof IComplexNum) {
convertDoubleComplex(buf, (IComplexNum) o, precedence);
return;
}
if (o instanceof IComplex) {
convertComplex(buf, (IComplex) o, precedence);
return;
}
if (o instanceof ISymbol) {
convertSymbol(buf, (ISymbol) o);
return;
}
if (o instanceof BigFraction) {
convertFraction(buf, (BigFraction) o, precedence);
return;
}
convertString(buf, o.toString());
}
Aggregations