
jscl.math.polynomial.TreePolynomial Maven / Gradle / Ivy
package jscl.math.polynomial;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import jscl.math.Expression;
import jscl.math.Generic;
import jscl.math.JsclInteger;
import jscl.math.Literal;
import javax.annotation.Nonnull;
final class TreePolynomial extends Polynomial {
final SortedMap content;
int degree;
boolean mutable = true;
TreePolynomial(Monomial monomialFactory, Generic coefFactory) {
super(monomialFactory, coefFactory);
content = new TreeMap(ordering);
}
public int size() {
return content.size();
}
public Iterator iterator(boolean direction, Monomial current) {
return new ContentIterator(direction, current);
}
class ContentIterator implements Iterator {
final boolean direction;
final Iterator iterator;
SortedMap map;
ContentIterator(boolean direction, Monomial current) {
this.direction = direction;
if (direction) {
iterator = null;
map = subContent(current, true);
} else {
iterator = (subContent(current, false)).entrySet().iterator();
if (current != null && content.containsKey(current)) iterator.next();
}
}
public boolean hasNext() {
return direction ? map.size() > 0 : iterator.hasNext();
}
public Object next() {
if (direction) {
Monomial m = (Monomial) map.lastKey();
map = content.headMap(m);
return term(m);
} else {
return term((Map.Entry) iterator.next());
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Term term(Map.Entry entry) {
return new Term((Monomial) entry.getKey(), (Generic) entry.getValue());
}
Term term(Monomial monomial) {
return new Term(monomial, null) {
public Generic coef() {
return coef == null ? coefficient(monomial) : coef;
}
};
}
SortedMap subContent(Monomial monomial, boolean direction) {
if (monomial == null) return content;
return direction ? content.headMap(monomial) : content.tailMap(monomial);
}
@Nonnull
public Polynomial subtract(@Nonnull Polynomial that) {
if (that.signum() == 0) return this;
if (mutable) {
TreePolynomial q = (TreePolynomial) that;
Iterator it = q.content.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
Monomial m = (Monomial) e.getKey();
Generic a = (Generic) e.getValue();
Generic s = coefficient(m).subtract(a);
if (s.signum() == 0) content.remove(m);
else content.put(m, s);
}
degree = degree(this);
sugar = Math.max(sugar, q.sugar);
normalized = false;
return this;
} else return copy().subtract(that);
}
public Polynomial multiplyAndSubtract(Generic generic, Polynomial polynomial) {
if (generic.signum() == 0) return this;
if (generic.compareTo(JsclInteger.valueOf(1)) == 0) return subtract(polynomial);
if (mutable) {
TreePolynomial q = (TreePolynomial) polynomial;
Iterator it = q.content.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
Monomial m = (Monomial) e.getKey();
Generic a = ((Generic) e.getValue()).multiply(generic);
Generic s = coefficient(m).subtract(a);
if (s.signum() == 0) content.remove(m);
else content.put(m, s);
}
degree = degree(this);
sugar = Math.max(sugar, q.sugar);
normalized = false;
return this;
} else return copy().multiplyAndSubtract(generic, polynomial);
}
public Polynomial multiplyAndSubtract(Monomial monomial, Generic generic, Polynomial polynomial) {
if (generic.signum() == 0) return this;
if (monomial.degree() == 0) return multiplyAndSubtract(generic, polynomial);
if (mutable) {
TreePolynomial q = (TreePolynomial) polynomial;
Iterator it = q.content.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
Monomial m = ((Monomial) e.getKey()).multiply(monomial);
Generic a = ((Generic) e.getValue()).multiply(generic);
Generic s = coefficient(m).subtract(a);
if (s.signum() == 0) content.remove(m);
else content.put(m, s);
}
degree = degree(this);
sugar = Math.max(sugar, q.sugar + monomial.degree());
normalized = false;
return this;
} else return copy().multiplyAndSubtract(monomial, generic, polynomial);
}
public Polynomial multiply(Generic generic) {
if (generic.signum() == 0) return valueOf(JsclInteger.valueOf(0));
if (generic.compareTo(JsclInteger.valueOf(1)) == 0) return this;
if (mutable) {
Iterator it = content.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
e.setValue(((Generic) e.getValue()).multiply(generic));
}
normalized = false;
return this;
} else return copy().multiply(generic);
}
public Polynomial multiply(Monomial monomial) {
if (defined) {
TreePolynomial p = newinstance();
Iterator it = content.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
Monomial m = ((Monomial) e.getKey()).multiply(monomial);
Generic a = (Generic) e.getValue();
Generic s = p.coefficient(m).add(a);
if (s.signum() == 0) p.content.remove(m);
else p.content.put(m, s);
}
p.degree = degree(p);
p.sugar = sugar + monomial.degree();
return p;
} else {
if (monomial.degree() == 0) return this;
TreePolynomial p = newinstance();
Iterator it = content.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
p.content.put(((Monomial) e.getKey()).multiply(monomial), (Generic) e.getValue());
}
p.degree = degree + monomial.degree();
p.sugar = sugar + monomial.degree();
return p;
}
}
public Polynomial divide(Generic generic) throws ArithmeticException {
if (generic.compareTo(JsclInteger.valueOf(1)) == 0) return this;
if (mutable) {
Iterator it = content.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
e.setValue(((Generic) e.getValue()).divide(generic));
}
normalized = false;
return this;
} else return copy().divide(generic);
}
public Polynomial divide(Monomial monomial) throws ArithmeticException {
if (monomial.degree() == 0) return this;
TreePolynomial p = newinstance();
Iterator it = content.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry) it.next();
p.content.put(((Monomial) e.getKey()).divide(monomial), (Generic) e.getValue());
}
p.degree = degree + monomial.degree();
p.sugar = sugar + monomial.degree();
return p;
}
public Polynomial gcd(Polynomial polynomial) {
throw new UnsupportedOperationException();
}
public int degree() {
return degree;
}
public Polynomial valueOf(Polynomial polynomial) {
TreePolynomial p = newinstance();
p.init(polynomial);
return p;
}
public Polynomial valueOf(Generic generic) {
TreePolynomial p = newinstance();
p.init(generic);
return p;
}
public Polynomial valueOf(Monomial monomial) {
TreePolynomial p = newinstance();
p.init(monomial);
return p;
}
public Polynomial freeze() {
mutable = false;
return this;
}
public Term head() {
return content.size() > 0 ? term((Monomial) content.lastKey()) : null;
}
public Term tail() {
return content.size() > 0 ? term((Monomial) content.firstKey()) : null;
}
public Generic coefficient(Monomial monomial) {
Generic a = (Generic) content.get(monomial);
return a == null ? coefficient(JsclInteger.valueOf(0)) : a;
}
void init(Polynomial polynomial) {
TreePolynomial q = (TreePolynomial) polynomial;
content.putAll(q.content);
degree = q.degree;
sugar = q.sugar;
}
void init(Expression expression) {
int sugar = 0;
int n = expression.size();
for (int i = 0; i < n; i++) {
Literal l = expression.literal(i);
JsclInteger en = expression.coef(i);
Monomial m = monomial(l);
l = l.divide(m.literalValue());
Generic a2 = coefficient(l.degree() > 0 ? en.multiply(Expression.valueOf(l)) : en);
Generic a1 = coefficient(m);
Generic a = a1.add(a2);
if (a.signum() == 0) content.remove(m);
else content.put(m, a);
sugar = Math.max(sugar, m.degree());
}
degree = degree(this);
this.sugar = sugar;
}
void init(Generic generic) {
if (generic instanceof Expression) {
init((Expression) generic);
} else {
Generic a = coefficient(generic);
if (a.signum() != 0) content.put(monomial(Literal.newInstance()), a);
degree = 0;
sugar = 0;
}
}
void init(Monomial monomial) {
content.put(monomial, coefficient(JsclInteger.valueOf(1)));
degree = monomial.degree();
sugar = monomial.degree();
}
protected TreePolynomial newinstance() {
return new TreePolynomial(monomialFactory, coefFactory);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy