WarpPI/core/src/main/java/it/cavallium/warppi/math/FunctionDynamic.java

145 lines
3.6 KiB
Java

package it.cavallium.warppi.math;
import java.util.Arrays;
import java.util.List;
import it.cavallium.warppi.math.rules.Rule;
import it.cavallium.warppi.util.Error;
import it.cavallium.warppi.util.Utils;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public abstract class FunctionDynamic implements Function {
private boolean simplified;
public FunctionDynamic(final MathContext root) {
this.root = root;
functions = new Function[] {};
}
public FunctionDynamic(final Function[] values) {
if (values.length > 0) {
root = values[0].getMathContext();
} else {
throw new NullPointerException("Nessun elemento nell'array. Impossibile ricavare il nodo root");
}
functions = values;
}
public FunctionDynamic(final MathContext root, final Function[] values) {
this.root = root;
functions = values;
}
protected final MathContext root;
protected Function[] functions;
public Function[] getParameters() {
return Arrays.copyOf(functions, functions.length);
}
public FunctionDynamic setParameters(final List<Function> value) {
final FunctionDynamic f = clone();
final int vsize = value.size();
final Function[] tmp = new Function[vsize];
for (int i = 0; i < vsize; i++) {
tmp[i] = value.get(i);
}
f.functions = tmp;
return f;
}
public FunctionDynamic setParameters(final Function[] value) {
final FunctionDynamic f = clone();
f.functions = value;
return f;
}
@Override
public Function getParameter(final int index) {
return functions[index];
}
@Override
public FunctionDynamic setParameter(final int index, final Function value) {
final FunctionDynamic f = clone();
f.functions[index] = value;
return f;
}
public FunctionDynamic appendParameter(final Function value) {
final FunctionDynamic f = clone();
f.functions = Arrays.copyOf(f.functions, f.functions.length + 1);
f.functions[f.functions.length - 1] = value;
return f;
}
/**
* Retrieve the current number of parameters.
*
* @return The number of parameters.
*/
public int getParametersLength() {
return functions.length;
}
public FunctionDynamic setParametersLength(final int length) {
final FunctionDynamic f = clone();
f.functions = Arrays.copyOf(functions, length);
return f;
}
@Override
public final ObjectArrayList<Function> simplify(final Rule rule) throws Error, InterruptedException {
final Function[] fncs = getParameters();
if (Thread.interrupted()) {
throw new InterruptedException();
}
final ObjectArrayList<Function> result = new ObjectArrayList<>();
final ObjectArrayList<ObjectArrayList<Function>> ln = new ObjectArrayList<>();
boolean alreadySolved = true;
for (final Function fnc : fncs) {
final ObjectArrayList<Function> l = new ObjectArrayList<>();
if (Thread.interrupted()) {
throw new InterruptedException();
}
final ObjectArrayList<Function> simplifiedFnc = fnc.simplify(rule);
if (simplifiedFnc == null) {
l.add(fnc);
} else {
l.addAll(simplifiedFnc);
alreadySolved = false;
}
ln.add(l);
}
if (alreadySolved) {
return rule.execute(this);
}
final Function[][] results = Utils.joinFunctionsResults(ln);
for (final Function[] f : results) {
result.add(this.setParameters(f));
}
return result;
}
@Override
public MathContext getMathContext() {
return root;
}
@Override
public abstract FunctionDynamic clone();
@Override
public int hashCode() {
return Arrays.hashCode(functions);
}
@Override
public abstract boolean equals(Object o);
}