jscl.math.Simplification Maven / Gradle / Ivy
package jscl.math;
import jscl.math.function.*;
import jscl.math.polynomial.Basis;
import jscl.math.polynomial.Monomial;
import jscl.math.polynomial.Polynomial;
import jscl.math.polynomial.UnivariatePolynomial;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public final class Simplification {
private final Map cache = new TreeMap();
Generic result;
private final List constraints = new ArrayList();
boolean linear;
private Simplification() {
}
public static Generic compute(@Nonnull Generic generic) {
final Simplification s = new Simplification();
s.computeValue(generic);
return s.getValue();
}
void computeValue(Generic generic) {
Debug.println("simplification");
Debug.increment();
final Variable t = new TechnicalVariable("t");
linear = false;
process(new Constraint(t, t.expressionValue().subtract(generic), false));
UnivariatePolynomial p = polynomial(t);
switch (p.degree()) {
case 0:
result = generic;
break;
case 1:
result = new Root(p, 0).selfSimplify();
break;
// case 2:
// int n=branch(generic,p);
// if(n 1);
}
} catch (NotRootException e) {
result = linearConstraint(v);
}
} else if (v instanceof Root) {
try {
Root r = (Root) v;
int d = r.degree();
int n = r.subscript().integerValue().intValue();
if (linear) {
result = linearConstraint(v);
}
if (result == null) {
final Generic parameters[] = r.getParameters();
result = new Constraint(v, Root.sigma(parameters, d - n).multiply(JsclInteger.valueOf(-1).pow(d - n)).multiply(parameters[d]).subtract(parameters[n]), d > 1);
}
} catch (NotIntegerException e) {
result = linearConstraint(v);
}
} else {
result = linearConstraint(v);
}
if (result != null) {
constraints.add(result);
}
}
}
@Nullable
private Constraint linearConstraint(@Nonnull Variable v) {
Generic s = cache.get(v);
if (s == null) {
s = v.simplify();
cache.put(v, s);
}
Generic a = v.expressionValue().subtract(s);
if (a.signum() != 0) {
return new Constraint(v, a, false);
} else {
return null;
}
}
Generic getValue() {
return result;
}
}
class Constraint {
Variable unknown;
Generic generic;
boolean reduce;
Constraint(Variable unknown, Generic generic, boolean reduce) {
this.unknown = unknown;
this.generic = generic;
this.reduce = reduce;
}
Constraint(Variable unknown) {
this(unknown, null, false);
}
public boolean equals(Object obj) {
return unknown.compareTo(((Constraint) obj).unknown) == 0;
}
}