package org.matheclipse.core.convert;
import java.util.ArrayList;
import java.util.List;
import org.matheclipse.core.eval.exception.JASConversionException;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.exception.WrongArgumentType;
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.IInteger;
import org.matheclipse.core.interfaces.ISymbol;
import com.google.common.base.Predicates;
import edu.jas.arith.BigRational;
import edu.jas.poly.Complex;
import edu.jas.poly.ExpVector;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.Monomial;
import edu.jas.poly.PolyUtil;
import edu.jas.poly.TermOrder;
import edu.jas.structure.RingFactory;
/**
* Convert JAS objects from and to MathEclipse objects
*
*
* @param
*/
public class JASIExpr {
private final RingFactory fRingFactory;
private final TermOrder fTermOrder;
private final GenPolynomialRing fPolyFactory;
private final GenPolynomialRing fBigIntegerPolyFactory;
private final List extends IExpr> fVariables;
public JASIExpr(IExpr variable, RingFactory ringFactory) {
List varList = new ArrayList();
varList.add(variable);
this.fRingFactory = ringFactory;
this.fVariables = varList;
String[] vars = new String[fVariables.size()];
for (int i = 0; i < fVariables.size(); i++) {
vars[i] = fVariables.get(i).toString();
}
this.fTermOrder = new TermOrder(TermOrder.INVLEX);
this.fPolyFactory = new GenPolynomialRing(fRingFactory, fVariables.size(), fTermOrder, vars);
this.fBigIntegerPolyFactory = new GenPolynomialRing(edu.jas.arith.BigInteger.ZERO,
fVariables.size(), fTermOrder, vars);
}
public JASIExpr(final List extends IExpr> variablesList, RingFactory ringFactory) {
this(variablesList, ringFactory, new TermOrder(TermOrder.INVLEX));
}
public JASIExpr(final List extends IExpr> variablesList, RingFactory ringFactory, TermOrder termOrder) {
this.fRingFactory = ringFactory;
this.fVariables = variablesList;
String[] vars = new String[fVariables.size()];
for (int i = 0; i < fVariables.size(); i++) {
vars[i] = fVariables.get(i).toString();
}
this.fTermOrder = termOrder;
this.fPolyFactory = new GenPolynomialRing(fRingFactory, fVariables.size(), fTermOrder, vars);
this.fBigIntegerPolyFactory = new GenPolynomialRing(edu.jas.arith.BigInteger.ZERO,
fVariables.size(), fTermOrder, vars);
}
/**
* Convert the given expression into a JAS polynomial. Only symbolic numbers
* are converted (i.e. no INum or IComplexNum values are converted into the polynomial structure)
*
* @param exprPoly
* @return
* @throws JASConversionException
*/
public GenPolynomial expr2IExprJAS(final IExpr exprPoly) throws JASConversionException {
try {
return expr2IExprPoly(exprPoly);
} catch (Exception ae) {
// ae.printStackTrace();
throw new JASConversionException();
}
}
// private GenPolynomial fraction2Poly(final IFraction exprPoly) {
// BigInteger n = exprPoly.getBigNumerator();// .toJavaBigInteger();
// BigInteger d = exprPoly.getBigDenominator();// .toJavaBigInteger();
// BigRational nr = new BigRational(n);
// BigRational dr = new BigRational(d);
// BigRational r = nr.divide(dr);
// return new GenPolynomial(fPolyFactory, r);
// }
private GenPolynomial expr2IExprPoly(final IExpr exprPoly) throws ArithmeticException, ClassCastException {
if (exprPoly instanceof IAST) {
final IAST ast = (IAST) exprPoly;
GenPolynomial result = fPolyFactory.getZERO();
GenPolynomial p = fPolyFactory.getZERO();
if (ast.isPlus()) {
IExpr expr = ast.get(1);
result = expr2IExprPoly(expr);
for (int i = 2; i < ast.size(); i++) {
expr = ast.get(i);
p = expr2IExprPoly(expr);
result = result.sum(p);
}
return result;
} else if (ast.isTimes()) {
IExpr expr = ast.get(1);
result = expr2IExprPoly(expr);
for (int i = 2; i < ast.size(); i++) {
expr = ast.get(i);
p = expr2IExprPoly(expr);
result = result.multiply(p);
}
return result;
} else if (ast.isPower()) {
final IExpr expr = ast.get(1);
for (int i = 0; i < fVariables.size(); i++) {
if (fVariables.get(i).equals(expr)) {
int exponent = -1;
try {
exponent = Validate.checkPowerExponent(ast);
} catch (WrongArgumentType e) {
//
}
if (exponent < 0) {
throw new ArithmeticException("JASConvert:expr2Poly - invalid exponent: " + ast.get(2).toString());
}
ExpVector e = ExpVector.create(fVariables.size(), i, exponent);
return fPolyFactory.getONE().multiply(e);
}
}
}
} else if (exprPoly instanceof ISymbol) {
for (int i = 0; i < fVariables.size(); i++) {
if (fVariables.get(i).equals(exprPoly)) {
ExpVector e = ExpVector.create(fVariables.size(), i, 1L);
return fPolyFactory.getONE().multiply(e);
}
}
return new GenPolynomial(fPolyFactory, exprPoly);
} else if (exprPoly instanceof IInteger) {
return new GenPolynomial(fPolyFactory, exprPoly);
// return fPolyFactory.fromInteger((java.math.BigInteger) ((IInteger) exprPoly).asType(java.math.BigInteger.class));
} else if (exprPoly instanceof IFraction) {
return new GenPolynomial(fPolyFactory, exprPoly);
// return fraction2Poly((IFraction) exprPoly);
}
if (exprPoly.isFree(Predicates.in(fVariables), true)) {
return new GenPolynomial(fPolyFactory, exprPoly);
} else {
for (int i = 0; i < fVariables.size(); i++) {
if (fVariables.get(i).equals(exprPoly)) {
ExpVector e = ExpVector.create(fVariables.size(), i, 1L);
return fPolyFactory.getONE().multiply(e);
}
}
}
throw new ClassCastException(exprPoly.toString());
}
/**
* BigInteger from BigRational coefficients. Represent as polynomial with BigInteger coefficients by multiplication with the gcd
* of the numerators and the lcm of the denominators of the BigRational coefficients.
*
* @param A
* polynomial with BigRational coefficients to be converted.
* @return Object[] with 3 entries: [0]->gcd [1]->lcm and [2]->polynomial with BigInteger coefficients.
*/
public Object[] factorTerms(GenPolynomial A) {
return PolyUtil.integerFromRationalCoefficientsFactor(fBigIntegerPolyFactory, A);
}
/**
* @return the fPolyFactory
*/
public GenPolynomialRing getPolynomialRingFactory() {
return fPolyFactory;
}
/**
* BigInteger from BigRational coefficients. Represent as polynomial with BigInteger coefficients by multiplication with the lcm
* of the numerators of the BigRational coefficients.
*
* @param A
* polynomial with BigRational coefficients to be converted.
* @return polynomial with BigInteger coefficients.
*/
public GenPolynomial integerFromRationalCoefficients(GenPolynomial A) {
return PolyUtil.integerFromRationalCoefficients(fBigIntegerPolyFactory, A);
}
/**
* Convert a JAS integer polynomial to IExpr.
*
* @param poly
* @return
* @throws ArithmeticException
* @throws ClassCastException
*/
public IExpr integerPoly2Expr(final GenPolynomial poly) throws ArithmeticException,
ClassCastException {
if (poly.length() == 0) {
return F.C0;
}
IAST result = F.Plus();
for (Monomial monomial : poly) {
edu.jas.arith.BigInteger coeff = monomial.coefficient();
ExpVector exp = monomial.exponent();
IInteger coeffValue = F.integer(coeff.getVal());
IAST monomTimes = F.Times(coeffValue);
long lExp;
for (int i = 0; i < exp.length(); i++) {
lExp = exp.getVal(i);
if (lExp != 0) {
monomTimes.add(F.Power(fVariables.get(i), F.integer(lExp)));
}
}
if (monomTimes.size() == 2) {
result.add(monomTimes.get(1));
} else {
result.add(monomTimes);
}
}
if (result.size() == 2) {
return result.get(1);
} else {
return result;
}
}
/**
* Convert a JAS complex polynomial to IExpr.
*
* @param poly
* @return
* @throws ArithmeticException
* @throws ClassCastException
*/
public IExpr complexPoly2Expr(final GenPolynomial> poly) throws ArithmeticException, ClassCastException {
if (poly.length() == 0) {
return F.C0;
}
IAST result = F.Plus();
for (Monomial> monomial : poly) {
Complex coeff = monomial.coefficient();
ExpVector exp = monomial.exponent();
BigRational re = coeff.getRe();
BigRational im = coeff.getIm();
IAST monomTimes = F.Times(F.complex(F.fraction(re.numerator(), re.denominator()),
F.fraction(im.numerator(), im.denominator())));
long lExp;
for (int i = 0; i < exp.length(); i++) {
lExp = exp.getVal(i);
if (lExp != 0) {
monomTimes.add(F.Power(fVariables.get(i), F.integer(lExp)));
}
}
if (monomTimes.size() == 2) {
result.add(monomTimes.get(1));
} else {
result.add(monomTimes);
}
}
if (result.size() == 2) {
return result.get(1);
} else {
return result;
}
}
/**
* Converts a JAS polynomial to a MathEclipse AST with head Plus
*
* @param poly
* a JAS polynomial
* @param variable
* @return
* @throws ArithmeticException
* @throws ClassCastException
*/
public IAST exprPoly2Expr(final GenPolynomial poly, IExpr variable) throws ArithmeticException, ClassCastException {
if (poly.length() == 0) {
return F.Plus(F.C0);
}
boolean getVar = variable == null;
IAST result = F.Plus();
for (Monomial monomial : poly) {
IExpr coeff = monomial.coefficient();
ExpVector exp = monomial.exponent();
// IFraction coeffValue = F.fraction(coeff.numerator(),
// coeff.denominator());
IAST monomTimes = F.Times(coeff);
long lExp;
for (int i = 0; i < exp.length(); i++) {
lExp = exp.getVal(i);
if (lExp != 0) {
if (getVar) {
variable = fVariables.get(i);
}
monomTimes.add(F.Power(variable, F.integer(lExp)));
}
}
result.add(monomTimes);
}
return result;
}
}
Ads help maintain this website.