use of org.matheclipse.core.interfaces.IASTAppendable in project symja_android_library by axkr.
the class GraphFunctions method graphToIExpr.
/**
* Convert a graph into an IExpr object.
*
* @param g
* @return
*/
public static IExpr graphToIExpr(AbstractBaseGraph<IExpr, ExprEdge> g) {
IASTAppendable vertexes = vertexToIExpr(g);
IASTAppendable[] edgeData = edgesToIExpr(g);
if (edgeData[1] == null) {
return F.Graph(vertexes, edgeData[0]);
}
return F.Graph(vertexes, edgeData[0], F.list(F.Rule(S.EdgeWeight, edgeData[1])));
}
use of org.matheclipse.core.interfaces.IASTAppendable in project symja_android_library by axkr.
the class RootsFunctions method nthComplexRoot.
/**
* Solve polynomials of the form <code>a * x^n + b == 0</code>.
*
* @param n
* @param polynomial
* @return
*/
private static IASTAppendable nthComplexRoot(int n, ExprPolynomial polynomial) {
IExpr coefficientN = C0;
IExpr coefficient0 = C0;
for (ExprMonomial monomial : polynomial) {
IExpr coefficient = monomial.coefficient();
long lExp = monomial.exponent().getVal(0);
if (lExp == n) {
coefficientN = coefficient;
} else if (lExp == 0) {
coefficient0 = coefficient;
} else {
return F.NIL;
}
}
if (coefficientN.isZero() || coefficient0.isZero()) {
return F.NIL;
}
EvalEngine engine = EvalEngine.get();
IExpr a = engine.evaluate(F.Divide(F.Negate(coefficient0), coefficientN));
if (a.isNumber()) {
// z = r*(Cos(θ)+I*Sin(θ))
IAST z = ((INumber) a).toPolarCoordinates();
IExpr r = z.arg1();
IExpr theta = z.arg2();
IRational fraction = F.fraction(1, n);
IExpr f1 = F.Power(r, fraction);
IASTAppendable result = F.ListAlloc(n);
for (int k = 0; k < n; k++) {
IAST argCosSin = F.Times(fraction, F.Plus(theta, F.Times(F.ZZ(k + k), S.Pi)));
IAST f2 = F.Plus(F.Cos(argCosSin), F.Times(F.CI, F.Sin(argCosSin)));
result.append(F.Times(f1, f2));
}
return result;
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTAppendable in project symja_android_library by axkr.
the class RootsFunctions method unitPolynomial.
/**
* Solve polynomials of the form <code>a * x^varDegree + b == 0</code>
*
* @param varDegree
* @param polynomial
* @return
*/
private static IASTAppendable unitPolynomial(int varDegree, ExprPolynomial polynomial) {
IExpr a = C0;
IExpr b = C0;
for (ExprMonomial monomial : polynomial) {
IExpr coeff = monomial.coefficient();
long lExp = monomial.exponent().getVal(0);
if (lExp == varDegree) {
a = coeff;
} else if (lExp == 0) {
b = coeff;
} else {
return F.NIL;
}
}
if (a.isZero() || b.isZero()) {
return F.NIL;
}
boolean isNegative = false;
IExpr rhsNumerator = EvalEngine.get().evaluate(b.negate());
// EvalEngine.get().evaluate(F.Divide(F.C1, a));
IExpr rhsDenominator = a;
if ((varDegree & 0x0001) == 0x0001) {
// odd
IExpr zNumerator;
if (rhsNumerator.isTimes()) {
IASTMutable temp = ((IAST) rhsNumerator).mapThread(F.Power(F.Slot1, F.fraction(1, varDegree)), 1);
if (rhsNumerator.first().isNegative()) {
isNegative = true;
temp.set(1, rhsNumerator.first().negate());
}
zNumerator = EvalEngine.get().evaluate(temp);
} else {
if (rhsNumerator.isNegative()) {
isNegative = true;
rhsNumerator = rhsNumerator.negate();
}
zNumerator = EvalEngine.get().evaluate(F.Power(rhsNumerator, F.fraction(1, varDegree)));
}
IExpr zDenominator;
if (rhsDenominator.isTimes()) {
IASTMutable temp = ((IAST) rhsDenominator).mapThread(F.Power(F.Slot1, F.fraction(-1, varDegree)), 1);
if (rhsDenominator.first().isNegative()) {
isNegative = !isNegative;
temp.set(1, rhsDenominator.first().negate());
}
zDenominator = EvalEngine.get().evaluate(temp);
} else {
if (rhsDenominator.isNegative()) {
isNegative = !isNegative;
rhsDenominator = rhsDenominator.negate();
}
zDenominator = EvalEngine.get().evaluate(F.Power(rhsDenominator, F.fraction(-1, varDegree)));
}
IASTAppendable result = F.ListAlloc(varDegree);
for (int i = 0; i < varDegree; i++) {
if (isNegative) {
result.append(F.Times(F.Power(F.CN1, i + 1), F.Power(F.CN1, F.fraction(i, varDegree)), zNumerator, zDenominator));
} else {
result.append(F.Times(F.Power(F.CN1, i), F.Power(F.CN1, F.fraction(i, varDegree)), zNumerator, zDenominator));
}
}
return result;
} else {
// even
IExpr zNumerator;
if (rhsNumerator.isTimes()) {
IExpr temp = ((IAST) rhsNumerator).mapThread(F.Power(F.Slot1, F.fraction(1, varDegree)), 1);
zNumerator = EvalEngine.get().evaluate(temp);
} else {
zNumerator = EvalEngine.get().evaluate(F.Power(rhsNumerator, F.fraction(1, varDegree)));
}
IExpr zDenominator;
if (rhsDenominator.isTimes()) {
IExpr temp = ((IAST) rhsDenominator).mapThread(F.Power(F.Slot1, F.fraction(-1, varDegree)), 1);
zDenominator = EvalEngine.get().evaluate(temp);
} else {
zDenominator = EvalEngine.get().evaluate(F.Power(rhsDenominator, F.fraction(-1, varDegree)));
}
IASTAppendable result = F.ListAlloc(varDegree);
long size = varDegree / 2;
// isNegative?1:0;
int k = 0;
for (int i = 1; i <= size; i++) {
result.append(F.Times(F.CN1, F.Power(F.CN1, F.fraction(k, varDegree)), zNumerator, zDenominator));
result.append(F.Times(F.Power(F.CN1, F.fraction(k, varDegree)), zNumerator, zDenominator));
k += 2;
}
return result;
}
}
use of org.matheclipse.core.interfaces.IASTAppendable in project symja_android_library by axkr.
the class RootsFunctions method rootsOfQuadraticPolynomial.
/**
* Solve a polynomial with degree <= 2.
*
* @param polynomial the polynomial
* @return <code>F.NIL</code> if no evaluation was possible.
*/
private static IASTAppendable rootsOfQuadraticPolynomial(ExprPolynomial polynomial) {
long varDegree = polynomial.degree(0);
if (polynomial.isConstant()) {
return F.ListAlloc(1);
}
IExpr a;
IExpr b;
IExpr c;
IExpr d;
IExpr e;
if (varDegree <= 2) {
IEvalStepListener listener = EvalEngine.get().getStepListener();
if (listener != null) {
IASTAppendable temp = listener.rootsOfQuadraticPolynomial(polynomial);
if (temp.isPresent()) {
return temp;
}
}
// solve quadratic equation:
a = C0;
b = C0;
c = C0;
d = C0;
e = C0;
for (ExprMonomial monomial : polynomial) {
IExpr coeff = monomial.coefficient();
long lExp = monomial.exponent().getVal(0);
if (lExp == 4) {
a = coeff;
} else if (lExp == 3) {
b = coeff;
} else if (lExp == 2) {
c = coeff;
} else if (lExp == 1) {
d = coeff;
} else if (lExp == 0) {
e = coeff;
} else {
throw new ArithmeticException("Roots::Unexpected exponent value: " + lExp);
}
}
IASTAppendable result = QuarticSolver.quarticSolve(a, b, c, d, e);
if (result.isPresent()) {
result = (IASTAppendable) QuarticSolver.sortASTArguments(result);
return result;
}
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTAppendable in project symja_android_library by axkr.
the class PredicateQ method isPossibeZero.
/**
* Test if <code>Complex(re, im)</code> inserted into the arguments of the function and evaluated
* approximates <code>0</code>.
*
* <ul>
* <li><code>IExpr.COMPARE_TERNARY.TRUE</code> if the result approximates <code>0</code>
* <li><code>IExpr.COMPARE_TERNARY.FALSE</code> if the result is a number and doesn't approximate
* <code>0</code>
* <li><code>IExpr.COMPARE_TERNARY.UNDECIDABLE</code> if the result isn't a number
* </ul>
*
* @param function the function which should be evaluate for the <code>variables</code>
* @param variables variables the symbols which will be replaced by <code>Complex(re, im)</code>
* to evaluate <code>function</code>
* @param engine
* @return
*/
private static IExpr.COMPARE_TERNARY isPossibeZero(IAST function, IAST variables, EvalEngine engine) {
IASTAppendable listOfRules = F.ListAlloc(variables.size());
ThreadLocalRandom tlr = ThreadLocalRandom.current();
for (int i = 1; i < variables.size(); i++) {
double re = tlr.nextDouble(-100, 100);
double im = tlr.nextDouble(-100, 100);
listOfRules.append(F.Rule(variables.get(i), F.complexNum(re, im)));
}
IExpr temp = function.replaceAll(listOfRules);
return isPossibleZeroApproximate(temp, engine);
}
Aggregations