package org.matheclipse.core.convert;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
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.IComplex;
import org.matheclipse.core.interfaces.IComplexNum;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.IFraction;
import org.matheclipse.core.interfaces.IInteger;
import org.matheclipse.core.interfaces.INum;
import org.matheclipse.core.interfaces.INumber;
import org.matheclipse.core.interfaces.ISignedNumber;
import org.matheclipse.core.interfaces.ISymbol;
import edu.jas.arith.BigRational;
import edu.jas.arith.ModIntegerRing;
import edu.jas.integrate.Integral;
import edu.jas.integrate.LogIntegral;
import edu.jas.integrate.QuotIntegral;
import edu.jas.poly.AlgebraicNumber;
import edu.jas.poly.AlgebraicNumberRing;
import edu.jas.poly.Complex;
import edu.jas.poly.ComplexRing;
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.RingElem;
import edu.jas.structure.RingFactory;
import edu.jas.structure.UnaryFunctor;
import edu.jas.ufd.Quotient;
/**
* Convert JAS objects from and to MathEclipse objects
*
*
* @param
*/
public class JASConvert> {
private final RingFactory fRingFactory;
private final TermOrder fTermOrder;
private final GenPolynomialRing fPolyFactory;
private final GenPolynomialRing fBigIntegerPolyFactory;
private final List extends IExpr> fVariables;
public JASConvert(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 JASConvert(final List extends IExpr> variablesList, RingFactory ringFactory) {
this(variablesList, ringFactory, new TermOrder(TermOrder.INVLEX));
}
public JASConvert(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);
}
public GenPolynomial expr2JAS(final IExpr exprPoly) throws JASConversionException {
try {
return expr2Poly(exprPoly, false);
} catch (Exception ae) {
// ae.printStackTrace();
throw new JASConversionException();
}
}
/**
* Convert the given expression into a JAS polynomial. INum
* double values are internally converted to IFractions and converte into the pokynomial structure.
*
* @param exprPoly
* @return
* @throws JASConversionException
*/
public GenPolynomial numericExpr2JAS(final IExpr exprPoly) throws JASConversionException {
try {
return numericExpr2Poly(exprPoly);
} catch (Exception ae) {
// ae.printStackTrace();
throw new JASConversionException();
}
}
/**
* Convert the given expression into a JAS polynomial. INum
* values are internally converted to IFractions and expr2Poly was called for the expression
*
* @param exprPoly
* @return
* @throws ArithmeticException
* @throws ClassCastException
*/
private GenPolynomial numericExpr2Poly(final IExpr exprPoly) throws ArithmeticException, ClassCastException {
return expr2Poly(exprPoly, true);
}
/**
* Convert the given expression into a JAS polynomial
*
* @param exprPoly
* @param numeric2Rational
* if true, INum double values are converted to BigRational internally
*
* @return
* @throws ArithmeticException
* @throws ClassCastException
*/
private GenPolynomial expr2Poly(final IExpr exprPoly, boolean numeric2Rational) 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 = expr2Poly(expr, numeric2Rational);
for (int i = 2; i < ast.size(); i++) {
expr = ast.get(i);
p = expr2Poly(expr, numeric2Rational);
result = result.sum(p);
}
return result;
} else if (ast.isTimes()) {
IExpr expr = ast.get(1);
result = expr2Poly(expr, numeric2Rational);
for (int i = 2; i < ast.size(); i++) {
expr = ast.get(i);
p = expr2Poly(expr, numeric2Rational);
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.valueOf(e);
// 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);
}
}
// class cast exception
} else if (exprPoly instanceof IInteger) {
return fPolyFactory.fromInteger((java.math.BigInteger) ((IInteger) exprPoly).asType(java.math.BigInteger.class));
} else if (exprPoly instanceof IFraction) {
return fraction2Poly((IFraction) exprPoly);
} else if (exprPoly instanceof INum && numeric2Rational) {
IFraction frac = F.fraction(((INum) exprPoly).getRealPart());
return fraction2Poly(frac);
} else if (exprPoly instanceof IComplexNum && numeric2Rational) {
if (F.isZero(((IComplexNum) exprPoly).getImaginaryPart())) {
// the imaginary part is zero
IFraction frac = F.fraction(((INum) exprPoly).getRealPart());
return fraction2Poly(frac);
}
}
throw new ClassCastException(exprPoly.toString());
}
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);
if (fRingFactory instanceof ComplexRing) {
ComplexRing ring = (ComplexRing) fRingFactory;
Complex c = new Complex(ring, r);
return new GenPolynomial(fPolyFactory, c);
} else {
return new GenPolynomial(fPolyFactory, r);
}
}
/**
* 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;
}
}
/**
* Convert a jas Integral into a matheclipse expression
*
* @param integral
* the JAS Integral
* @return
*/
public IAST integral2Expr(Integral integral) {
IAST sum = F.Plus();
GenPolynomial pol = integral.pol;
List> rational = integral.rational;
List> logarithm = integral.logarithm;
if (!pol.isZERO()) {
sum.add(poly2Expr(pol, null));
}
if (rational.size() != 0) {
int i = 0;
while (i < rational.size()) {
sum.add(F.Times(poly2Expr(rational.get(i++), null), F.Power(poly2Expr(rational.get(i++), null), F.CN1)));
}
}
if (logarithm.size() != 0) {
for (LogIntegral pf : logarithm) {
sum.add(logIntegral2Expr(pf));
}
}
return sum;
}
/**
* Convert a jas LogIntegral into a matheclipse expression
*
* @param logIntegral
* the JAS LogIntegral
* @return
*/
public IAST logIntegral2Expr(LogIntegral logIntegral) {
IAST plus = F.Plus();
List cfactors = logIntegral.cfactors;
List> cdenom = logIntegral.cdenom;
List> afactors = logIntegral.afactors;
List>> adenom = logIntegral.adenom;
if (cfactors.size() > 0) {
for (int i = 0; i < cfactors.size(); i++) {
BigRational cp = cfactors.get(i);
GenPolynomial p = cdenom.get(i);
plus.add(F.Times(F.fraction(cp.numerator(), cp.denominator()), F.Log(poly2Expr(p, null))));
}
}
// TODO implement this conversion for AlgebraicNumbers...
if (afactors.size() > 0) {
for (int i = 0; i < afactors.size(); i++) {
AlgebraicNumber ap = afactors.get(i);
AlgebraicNumberRing ar = ap.factory();
GenPolynomial> p = adenom.get(i);
if (p.degree(0) < ar.modul.degree(0) && ar.modul.degree(0) > 2) {
}
GenPolynomial v = ap.getVal();
IAST times = F.Times();
AlgebraicNumber arGen = ar.getGenerator();
// sb.append(" ## over " + ap.factory() + "\n");
if (p.degree(0) < ar.modul.degree(0) && ar.modul.degree(0) > 2) {
IAST rootOf = F.ast(F.RootOf);
rootOf.add(poly2Expr(ar.modul, null));
// rootOf.add(variable);
// sb.append("sum_(" + ar.getGenerator() + " in ");
// sb.append("rootOf(" + ar.modul + ") ) ");
times.add(rootOf);
throw new UnsupportedOperationException("JASConvert#logIntegral2Expr()");
}
times.add(poly2Expr(v, null));
times.add(F.Log(polyAlgebraicNumber2Expr(p)));
plus.add(times);
}
}
return plus;
}
// public IAST modIntegerPoly2Expr(final GenPolynomial poly) throws ArithmeticException, ClassCastException {
// if (poly.length() == 0) {
// return F.Plus(F.C0);
// }
// IAST result = F.Plus();
// for (Monomial monomial : poly) {
// ModInteger 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)));
// }
// }
// result.add(monomTimes);
// }
// return result;
// }
/**
* Converts a JAS polynomial to a MathEclipse AST with head Plus
*
* @param poly
* a JAS polynomial
* @return
* @throws ArithmeticException
* @throws ClassCastException
*/
public IAST poly2Expr(final GenPolynomial poly) throws ArithmeticException, ClassCastException {
return poly2Expr(poly, null);
}
/**
* 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 poly2Expr(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) {
BigRational coeff = monomial.coefficient();
ExpVector exp = monomial.exponent();
IFraction coeffValue = F.fraction(coeff.numerator(), coeff.denominator());
IAST monomTimes = F.Times(coeffValue);
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;
}
/**
* 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;
}
public IAST polyAlgebraicNumber2Expr(final GenPolynomial> poly) throws ArithmeticException,
ClassCastException {
if (poly.length() == 0) {
return F.Plus(F.C0);
}
SortedMap> val = poly.getMap();
if (val.size() == 0) {
return F.Plus(F.C0);
} else {
IAST result = F.Plus();
String symbolName = poly.factory().getVars()[0];
IExpr sym = F.$s(symbolName);
for (Map.Entry> m : val.entrySet()) {
AlgebraicNumber c = m.getValue();
IAST times = F.Times();
ExpVector e = m.getKey();
if (!c.isONE() || e.isZERO()) {
times.add(algebraicNumber2Expr(c, sym));
}
if (e != null && sym != null) {
long lExp = e.getVal(0);
if (lExp != 0) {
times.add(F.Power(sym, F.integer(lExp)));
} else {
times.add(F.Power(sym, F.integer(lExp)));
}
}
if (times.size() > 1) {
result.add(times);
}
}
return result;
}
}
public IAST algebraicNumber2Expr(final AlgebraicNumber coeff, IExpr variable) throws ArithmeticException,
ClassCastException {
GenPolynomial val = coeff.val;
return poly2Expr(val, variable);
}
/**
* Convert a jas Integral into a matheclipse expression
*
* @param integral
* the JAS Integral
* @return
*/
public IAST quotIntegral2Expr(QuotIntegral integral) {
IAST sum = F.Plus();
List> rational = integral.rational;
List> logarithm = integral.logarithm;
// StringBuffer sb = new StringBuffer();
// sb.append("integral( " + quot.toString() + " )" );
// sb.append(" =\n");
// boolean first = true;
if (rational.size() != 0) {
Quotient qTemp;
GenPolynomial qNum;
GenPolynomial qDen;
for (int i = 0; i < rational.size(); i++) {
qTemp = rational.get(i);
qNum = qTemp.num;
qDen = qTemp.den;
sum.add(F.Times(poly2Expr(qNum, null), F.Power(poly2Expr(qDen, null), F.CN1)));
}
}
if (logarithm.size() != 0) {
for (LogIntegral pf : logarithm) {
sum.add(logIntegral2Expr(pf));
}
}
return sum;
}
public IAST rationalPoly2Expr(final GenPolynomial poly) throws ArithmeticException, ClassCastException {
if (poly.length() == 0) {
return F.Plus(F.C0);
}
IAST result = F.Plus();
for (Monomial monomial : poly) {
BigRational coeff = monomial.coefficient();
ExpVector exp = monomial.exponent();
IFraction coeffValue = F.fraction(coeff.numerator(), coeff.denominator());
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)));
}
}
result.add(monomTimes);
}
return result;
}
public static ModIntegerRing option2ModIntegerRing(ISignedNumber option) {
// TODO convert to long value
long longValue = option.toLong();
final BigInteger value = BigInteger.valueOf(longValue);
return new ModIntegerRing(longValue, value.isProbablePrime(32));
}
public static IComplex jas2Complex(edu.jas.poly.Complex c) {
IFraction re = F.fraction(c.getRe().numerator(), c.getRe().denominator());
IFraction im = F.fraction(c.getIm().numerator(), c.getIm().denominator());
return F.complex(re, im);
}
public static INumber jas2Numeric(edu.jas.poly.Complex c, double epsilon) {
IFraction re = F.fraction(c.getRe().numerator(), c.getRe().denominator());
double red = re.doubleValue();
IFraction im = F.fraction(c.getIm().numerator(), c.getIm().denominator());
double imd = im.doubleValue();
if (F.isZero(imd, epsilon)) {
return F.num(red);
}
return F.complexNum(red, imd);
}
/**
* * Conversion of BigRational to BigInteger. result = (num/gcd)*(lcm/denom).
*/
static class RatToRatFactor implements UnaryFunctor {
final java.math.BigInteger lcm;
final java.math.BigInteger gcd;
public RatToRatFactor(java.math.BigInteger gcd, java.math.BigInteger lcm) {
this.gcd = gcd;
this.lcm = lcm; // .getVal();
}
public BigRational eval(BigRational c) {
if (c == null) {
return BigRational.ZERO;
}
if (gcd.equals(java.math.BigInteger.ONE)) {
// p = num*(lcm/denom)
java.math.BigInteger b = lcm.divide(c.denominator());
return BigRational.valueOf(c.numerator().multiply(b));
}
// p = (num/gcd)*(lcm/denom)
java.math.BigInteger a = c.numerator().divide(gcd);
java.math.BigInteger b = lcm.divide(c.denominator());
return BigRational.valueOf(a.multiply(b));
}
}
/**
* BigRational 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 fac
* result polynomial factory.
* @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 static Object[] rationalFromRationalCoefficientsFactor(GenPolynomialRing fac, GenPolynomial A) {
Object[] result = new Object[3];
if (A == null || A.isZERO()) {
result[0] = java.math.BigInteger.ONE;
result[1] = java.math.BigInteger.ZERO;
result[2] = fac.getZERO();
return result;
}
java.math.BigInteger gcd = null;
java.math.BigInteger lcm = null;
int sLCM = 0;
int sGCD = 0;
// lcm of denominators
Iterator iter = A.coefficientIterator();
while (iter.hasNext()) {
BigRational y = iter.next();
java.math.BigInteger numerator = y.numerator();
java.math.BigInteger denominator = y.denominator();
// lcm = lcm(lcm,x)
if (lcm == null) {
lcm = denominator;
sLCM = denominator.signum();
} else {
java.math.BigInteger d = lcm.gcd(denominator);
lcm = lcm.multiply(denominator.divide(d));
}
// gcd = gcd(gcd,x)
if (gcd == null) {
gcd = numerator;
sGCD = numerator.signum();
} else {
gcd = gcd.gcd(numerator);
}
}
if (sLCM < 0) {
lcm = lcm.negate();
}
if (sGCD < 0) {
gcd = gcd.negate();
}
result[0] = gcd;
result[1] = lcm;
result[2] = PolyUtil. map(fac, A, new RatToRatFactor(gcd, lcm));
return result;
}
}
Ads help maintain this website.