use of org.matheclipse.core.interfaces.IASTMutable 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.IASTMutable in project symja_android_library by axkr.
the class RootsFunctions method rootsOfExprPolynomial.
public static IASTMutable rootsOfExprPolynomial(final IExpr expr, IAST varList, boolean rootsOfQuartic) {
IASTMutable result = F.NIL;
try {
// try to generate a common expression polynomial
ExprPolynomialRing ring = new ExprPolynomialRing(ExprRingFactory.CONST, varList);
ExprPolynomial ePoly = ring.create(expr, false, false, false);
ePoly = ePoly.multiplyByMinimumNegativeExponents();
if (ePoly.degree(0) >= Integer.MAX_VALUE) {
return F.NIL;
}
if (ePoly.degree(0) >= 3) {
result = unitPolynomial((int) ePoly.degree(0), ePoly);
if (result.isPresent()) {
result = QuarticSolver.sortASTArguments(result);
return result;
}
}
if (!rootsOfQuartic && ePoly.degree(0) > 2) {
return F.NIL;
}
result = rootsOfQuarticPolynomial(ePoly);
if (result.isPresent()) {
if (expr.isNumericMode()) {
for (int i = 1; i < result.size(); i++) {
result.set(i, F.chopExpr(result.get(i), Config.DEFAULT_ROOTS_CHOP_DELTA));
}
}
result = QuarticSolver.sortASTArguments(result);
return result;
}
} catch (JASConversionException e2) {
LOGGER.debug("RootsFunctions.rootsOfExprPolynomial() failed", e2);
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class NumericArrayExpr method normalRecursive.
private static void normalRecursive(byte[] byteArray, boolean unsigned, IASTMutable list, int[] dimension, int position, int[] index) {
int size = dimension[position];
if (dimension.length - 1 == position) {
for (int i = 1; i <= size; i++) {
IInteger intValue = unsigned ? F.ZZ(Byte.toUnsignedInt(byteArray[index[0]++])) : F.ZZ(byteArray[index[0]++]);
list.set(i, intValue);
}
return;
}
int size2 = dimension[position + 1];
for (int i = 1; i <= size; i++) {
IASTMutable currentList = F.astMutable(S.List, size2);
list.set(i, currentList);
normalRecursive(byteArray, unsigned, currentList, dimension, position + 1, index);
}
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class NumericArrayExpr method normalAppendable.
private IASTMutable normalAppendable(IExpr head, int[] dims) {
IASTMutable list = F.astMutable(head, dims[0]);
int[] index = new int[1];
switch(fType) {
case Integer8:
normalRecursive((byte[]) fData, false, list, dims, 0, index);
break;
case Integer16:
normalRecursive((short[]) fData, false, list, dims, 0, index);
break;
case Integer32:
normalRecursive((int[]) fData, false, list, dims, 0, index);
break;
case Integer64:
normalRecursive((long[]) fData, false, list, dims, 0, index);
break;
case UnsignedInteger8:
normalRecursive((byte[]) fData, true, list, dims, 0, index);
break;
case UnsignedInteger16:
normalRecursive((short[]) fData, true, list, dims, 0, index);
break;
case UnsignedInteger32:
normalRecursive((int[]) fData, true, list, dims, 0, index);
break;
case UnsignedInteger64:
normalRecursive((long[]) fData, true, list, dims, 0, index);
break;
case Real32:
normalRecursive((float[]) fData, list, dims, 0, index);
break;
case Real64:
normalRecursive((double[]) fData, list, dims, 0, index);
break;
case ComplexReal32:
normalRecursiveComplex((float[]) fData, list, dims, 0, index);
break;
case ComplexReal64:
normalRecursiveComplex((double[]) fData, list, dims, 0, index);
break;
}
return list;
}
use of org.matheclipse.core.interfaces.IASTMutable in project symja_android_library by axkr.
the class SparseArrayExpr method arrayRules.
/**
* Create array rules from the nested lists. From array rules a sparse array can be created.
*
* @param nestedListsOfValues
* @return
*/
public static IAST arrayRules(IAST nestedListsOfValues, IExpr defaultValue) {
int depth = SparseArrayExpr.depth(nestedListsOfValues, 1);
if (depth < 0) {
return F.NIL;
}
// default value rule is additionally appended at the end!
IASTAppendable result = F.ListAlloc(F.allocMin32(F.allocLevel1(nestedListsOfValues, x -> x.isList()) + 2));
IASTMutable positions = F.constantArray(F.C1, depth);
if (SparseArrayExpr.arrayRulesRecursive(nestedListsOfValues, depth + 1, depth, positions, defaultValue, result)) {
result.append(F.Rule(F.constantArray(F.$b(), depth), defaultValue));
return result;
}
return F.NIL;
}
Aggregations