package org.matheclipse.core.convert;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
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.INum;
import org.matheclipse.core.interfaces.ISignedNumber;
import org.matheclipse.core.interfaces.ISymbol;
import com.google.common.math.DoubleMath;
public class Expr2Object {
public static int MAX_POLYNOMIAL = 4;
public static double[] toDoubleVector(IAST ast) throws WrongArgumentType {
double[] result = new double[ast.size() - 1];
for (int i = 1; i < ast.size(); i++) {
if (ast.get(i).isSignedNumber()) {
result[i - 1] = ((ISignedNumber) ast.get(i)).doubleValue();
} else {
throw new WrongArgumentType(ast, ast.get(i), i, "Conversion into a vector of double values not possible!");
}
}
return result;
}
public static double[][] toDoubleMatrix(IAST ast) throws WrongArgumentType {
int[] dim = ast.isMatrix();
double[][] result = new double[dim[0]][dim[1]];
for (int i = 1; i <= dim[0]; i++) {
IAST row = (IAST) ast.get(i);
for (int j = 1; i <= dim[1]; j++) {
if (row.get(j).isSignedNumber()) {
result[i - 1][j - 1] = ((ISignedNumber) row.get(j)).doubleValue();
} else {
throw new WrongArgumentType(ast, ast.get(i), i, "Conversion into a matrix of double values not possible!");
}
}
}
return result;
}
public static double[] toPolynomial(IExpr expr, ISymbol sym) {
double[] array = new double[MAX_POLYNOMIAL];
Map map = toPolynomialMap(expr, sym);
if (map == null) {
return null;
}
int k;
for (Map.Entry entry : map.entrySet()) {
k = entry.getKey();
if (k <= 4) {
array[k] = entry.getValue();
} else {
return null;
}
}
return array;
}
/**
*
* @param expr
* @param sym
* @return null if the expression couldn't be converted to a
* polynomial.
*/
public static Map toPolynomialMap(IExpr expr, ISymbol sym) {
try {
Map map = new HashMap();
if (expr.isPlus()) {
IAST plus = (IAST) expr;
for (int i = 1; i < plus.size(); i++) {
if (plus.get(i).isTimes()) {
IAST times = (IAST) plus.get(i);
double coeff = 0;
int exp = -1;
for (int j = 1; j < times.size(); j++) {
if (times.get(j).isPower()) {
IAST power = (IAST) times.get(j);
if (power.get(1).equals(sym)) {
if (exp != (-1)) {
return null;
}
IExpr res = F.evaln(power.get(2));
if (!(res instanceof INum)) {
return null;
}
exp = DoubleMath.roundToInt(((INum) res).doubleValue(), RoundingMode.UNNECESSARY);
if (exp < 0) {
return null;
}
continue;
}
} else if (times.get(j).isSymbol()) {
if (times.get(j).equals(sym)) {
if (exp != (-1)) {
return null;
}
exp = 1;
continue;
}
}
if (times.get(j) instanceof INum) {
coeff += ((INum) times.get(j)).doubleValue();
continue;
}
IExpr res = F.evaln(times.get(j));
if (!(res instanceof INum)) {
return null;
}
coeff += ((INum) res).doubleValue();
}
if (exp == (-1)) {
exp = 0;
}
addCoefficient(map, coeff, exp);
continue;
} else if (plus.get(i).isPower()) {
IAST power = (IAST) plus.get(i);
if (power.get(1).equals(sym)) {
IExpr res = F.evaln(power.get(2));
if (!(res instanceof INum)) {
return null;
}
int exp = DoubleMath.roundToInt(((INum) res).doubleValue(), RoundingMode.UNNECESSARY);
if (exp < 0) {
return null;
}
addCoefficient(map, 1.0, exp);
continue;
}
return null;
} else if (plus.get(i).isSymbol()) {
if (plus.get(i).equals(sym)) {
addCoefficient(map, 1.0, 1);
continue;
}
return null;
}
if (plus.get(i) instanceof INum) {
addCoefficient(map, ((INum) plus.get(i)).doubleValue(), 0);
continue;
}
IExpr res = F.evaln(plus.get(i));
if (!(res instanceof INum)) {
return null;
}
addCoefficient(map, ((INum) res).doubleValue(), 0);
}
return map;
}
} catch (Exception ex) {
}
return null;
}
private static void addCoefficient(Map map, double v, int k) {
Integer key = Integer.valueOf(k);
Double value = map.get(key);
if (value == null) {
map.put(Integer.valueOf(k), Double.valueOf(v));
} else {
map.put(Integer.valueOf(k), Double.valueOf(value.doubleValue() + v));
}
}
}
Ads help maintain this website.