package org.matheclipse.core.reflection.system;
import java.math.BigInteger;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.interfaces.IFunctionEvaluator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.IFraction;
import org.matheclipse.core.interfaces.INum;
import org.matheclipse.core.interfaces.IRational;
import org.matheclipse.core.interfaces.ISymbol;
/**
* ContinuedFraction of a double or fraction number
*
* See: Continued fraction
*
* @see org.matheclipse.core.reflection.system.FromContinuedFraction
*/
public class ContinuedFraction implements IFunctionEvaluator {
public ContinuedFraction() {
}
public IExpr evaluate(final IAST ast) {
Validate.checkRange(ast, 2, 3);
IExpr arg1 = ast.arg1();
int maxIterations = Integer.MAX_VALUE;
if (ast.size() == 3 && ast.arg2().isInteger()) {
maxIterations = Validate.checkIntType(ast, 2);
}
if (arg1 instanceof INum) {
arg1 = F.fraction(((INum) arg1).getRealPart());
} else if (arg1.isAST() || arg1.isSymbol() && arg1.isNumericFunction()) {
IExpr num = F.evaln(arg1);
if (num instanceof INum) {
arg1 = F.fraction(((INum) num).getRealPart());
}
}
if (arg1.isRational()) {
IRational rat = (IRational) arg1;
IAST continuedFractionList = F.List();
if (rat.getDenominator().equals(F.C1)) {
continuedFractionList.add(rat.getNumerator());
} else if (rat.getNumerator().equals(F.C1)) {
continuedFractionList.add(F.C0);
continuedFractionList.add(rat.getDenominator());
} else {
IFraction temp = F.fraction(rat.getNumerator(), rat.getDenominator());
BigInteger quotient;
BigInteger remainder;
while (temp.getDenominator().isGreaterThan(F.C1) && (0 < maxIterations--)) {
quotient = temp.getBigNumerator().divide(temp.getBigDenominator());
remainder = temp.getBigNumerator().mod(temp.getBigDenominator());
continuedFractionList.add(F.integer(quotient));
temp = F.fraction(temp.getBigDenominator(), remainder);
if (temp.getDenominator().equals(F.C1)) {
continuedFractionList.add(temp.getNumerator());
}
}
}
return continuedFractionList;
}
return null;
}
public IExpr numericEval(final IAST functionList) {
return evaluate(functionList);
}
public void setUp(ISymbol symbol) {
symbol.setAttributes(ISymbol.NHOLDREST);
}
}
Ads help maintain this website.