mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-27 09:05:19 +00:00
Compare commits
7 Commits
live-reloa
...
inv-trig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e6cf08ec2 | ||
|
|
fee9f091fd | ||
|
|
4226df72f5 | ||
|
|
1f0e6a7ce4 | ||
|
|
efe76a6fdc | ||
|
|
ca6d8d2ba2 | ||
|
|
1d6957c4d9 |
@@ -255,7 +255,13 @@ public class AbacusController implements PluginListener {
|
|||||||
abacus = new Abacus(new Configuration(CONFIG_FILE));
|
abacus = new Abacus(new Configuration(CONFIG_FILE));
|
||||||
PluginManager abacusPluginManager = abacus.getPluginManager();
|
PluginManager abacusPluginManager = abacus.getPluginManager();
|
||||||
abacusPluginManager.addListener(this);
|
abacusPluginManager.addListener(this);
|
||||||
performScan();
|
abacusPluginManager.addInstantiated(new StandardPlugin(abacus.getPluginManager()));
|
||||||
|
try {
|
||||||
|
ClassFinder.loadJars("plugins").forEach(abacusPluginManager::addClass);
|
||||||
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
abacusPluginManager.reload();
|
||||||
|
|
||||||
computationLimitField.setText(Double.toString(abacus.getConfiguration().getComputationDelay()));
|
computationLimitField.setText(Double.toString(abacus.getConfiguration().getComputationDelay()));
|
||||||
computationLimitField.textProperty().addListener((observable, oldValue, newValue) -> {
|
computationLimitField.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
@@ -305,19 +311,6 @@ public class AbacusController implements PluginListener {
|
|||||||
reloadAlertShown = false;
|
reloadAlertShown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void performScan(){
|
|
||||||
PluginManager abacusPluginManager = abacus.getPluginManager();
|
|
||||||
abacusPluginManager.removeAll();
|
|
||||||
abacusPluginManager.addInstantiated(new StandardPlugin(abacus.getPluginManager()));
|
|
||||||
try {
|
|
||||||
ClassFinder.loadJars("plugins").forEach(abacusPluginManager::addClass);
|
|
||||||
} catch (IOException | ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
abacusPluginManager.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void performReload() {
|
public void performReload() {
|
||||||
alertIfApplyNeeded(true);
|
alertIfApplyNeeded(true);
|
||||||
|
|||||||
@@ -240,7 +240,6 @@ public abstract class NumberInterface {
|
|||||||
* @param toClass the class to promote to.
|
* @param toClass the class to promote to.
|
||||||
* @return the resulting new instance.
|
* @return the resulting new instance.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
protected abstract NumberInterface promoteToInternal(Class<? extends NumberInterface> toClass);
|
protected abstract NumberInterface promoteToInternal(Class<? extends NumberInterface> toClass);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -251,7 +250,6 @@ public abstract class NumberInterface {
|
|||||||
* @param toClass the class to promote to.
|
* @param toClass the class to promote to.
|
||||||
* @return the resulting new instance.
|
* @return the resulting new instance.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public final NumberInterface promoteTo(Class<? extends NumberInterface> toClass) {
|
public final NumberInterface promoteTo(Class<? extends NumberInterface> toClass) {
|
||||||
checkInterrupted();
|
checkInterrupted();
|
||||||
return promoteToInternal(toClass);
|
return promoteToInternal(toClass);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public abstract class NumberImplementation {
|
|||||||
/**
|
/**
|
||||||
* The list of paths through which this implementation can be promoted.
|
* The list of paths through which this implementation can be promoted.
|
||||||
*/
|
*/
|
||||||
private Map<Class<? extends NumberInterface>, Function<NumberInterface, NumberInterface>> promotionPaths;
|
protected Map<Class<? extends NumberInterface>, Function<NumberInterface, NumberInterface>> promotionPaths;
|
||||||
/**
|
/**
|
||||||
* The implementation class for this implementation.
|
* The implementation class for this implementation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -187,24 +187,6 @@ public class PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the plugin with the given class from the manager.
|
|
||||||
* @param toRemove the plugin to remove.
|
|
||||||
*/
|
|
||||||
public void removeClass(Class<? extends Plugin> toRemove){
|
|
||||||
if(!loadedPluginClasses.contains(toRemove)) return;
|
|
||||||
plugins.removeIf(plugin -> plugin.getClass() == toRemove);
|
|
||||||
loadedPluginClasses.remove(toRemove);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all plugins from this plugin manager.
|
|
||||||
*/
|
|
||||||
public void removeAll(){
|
|
||||||
loadedPluginClasses.clear();
|
|
||||||
plugins.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all the plugins in the PluginManager.
|
* Loads all the plugins in the PluginManager.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -451,6 +451,144 @@ public class StandardPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The arcsine function (return type in radians).
|
||||||
|
*/
|
||||||
|
public final Function functionArcsin = new Function() {
|
||||||
|
@Override
|
||||||
|
protected boolean matchesParams(NumberInterface[] params) {
|
||||||
|
return params.length == 1
|
||||||
|
&& FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
|
if(FUNCTION_ABS.apply(params[0]).compareTo(new NaiveNumber(0.8).promoteTo(params[0].getClass())) >= 0){
|
||||||
|
NumberInterface[] newParams = {FUNCTION_SQRT.apply(fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))};
|
||||||
|
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
||||||
|
.subtract(applyInternal(newParams)).multiply(fromInt(params[0].getClass(), params[0].signum()));
|
||||||
|
}
|
||||||
|
NumberInterface currentTerm = params[0], sum = currentTerm,
|
||||||
|
multiplier = currentTerm.multiply(currentTerm), summandBound = sum.getMaxError().multiply(fromInt(sum.getClass(), 1).subtract(multiplier)),
|
||||||
|
power = currentTerm, coefficient = fromInt(params[0].getClass(), 1);
|
||||||
|
int exponent = 1;
|
||||||
|
while(FUNCTION_ABS.apply(currentTerm).compareTo(summandBound) > 0){
|
||||||
|
exponent += 2;
|
||||||
|
power = power.multiply(multiplier);
|
||||||
|
coefficient = coefficient.multiply(fromInt(params[0].getClass(), exponent-2))
|
||||||
|
.divide(fromInt(params[0].getClass(), exponent - 1));
|
||||||
|
currentTerm = power.multiply(coefficient).divide(fromInt(power.getClass(), exponent));
|
||||||
|
sum = sum.add(currentTerm);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The arccosine function.
|
||||||
|
*/
|
||||||
|
public final Function functionArccos = new Function() {
|
||||||
|
@Override
|
||||||
|
protected boolean matchesParams(NumberInterface[] params) {
|
||||||
|
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
|
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
||||||
|
.subtract(functionArcsin.apply(params));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The arccosecant function.
|
||||||
|
*/
|
||||||
|
public final Function functionArccsc = new Function() {
|
||||||
|
@Override
|
||||||
|
protected boolean matchesParams(NumberInterface[] params) {
|
||||||
|
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
|
NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
||||||
|
return functionArcsin.apply(reciprocalParamArr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The arcsecant function.
|
||||||
|
*/
|
||||||
|
public final Function functionArcsec = new Function() {
|
||||||
|
@Override
|
||||||
|
protected boolean matchesParams(NumberInterface[] params) {
|
||||||
|
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
|
NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
||||||
|
return functionArccos.apply(reciprocalParamArr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The arctangent function.
|
||||||
|
*/
|
||||||
|
public final Function functionArctan = new Function() {
|
||||||
|
@Override
|
||||||
|
protected boolean matchesParams(NumberInterface[] params) {
|
||||||
|
return params.length == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
|
if(params[0].signum() == -1){
|
||||||
|
NumberInterface[] negatedParams = {params[0].negate()};
|
||||||
|
return applyInternal(negatedParams).negate();
|
||||||
|
}
|
||||||
|
if(params[0].compareTo(fromInt(params[0].getClass(), 1)) > 0){
|
||||||
|
NumberInterface[] reciprocalParams = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
||||||
|
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
||||||
|
.subtract(applyInternal(reciprocalParams));
|
||||||
|
}
|
||||||
|
if(params[0].compareTo(fromInt(params[0].getClass(), 1)) == 0){
|
||||||
|
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 4));
|
||||||
|
}
|
||||||
|
if(params[0].compareTo(new NaiveNumber(0.9).promoteTo(params[0].getClass())) >= 0){
|
||||||
|
NumberInterface[] newParams = {params[0].multiply(fromInt(params[0].getClass(),2 ))
|
||||||
|
.divide(fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))};
|
||||||
|
return applyInternal(newParams).divide(fromInt(params[0].getClass(), 2));
|
||||||
|
}
|
||||||
|
NumberInterface currentPower = params[0], currentTerm = currentPower, sum = currentTerm,
|
||||||
|
maxError = params[0].getMaxError(), multiplier = currentPower.multiply(currentPower).negate();
|
||||||
|
int n = 1;
|
||||||
|
while(FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0){
|
||||||
|
n += 2;
|
||||||
|
currentPower = currentPower.multiply(multiplier);
|
||||||
|
currentTerm = currentPower.divide(fromInt(currentPower.getClass(), n));
|
||||||
|
sum = sum.add(currentTerm);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The arccotangent function. Range: (0, pi).
|
||||||
|
*/
|
||||||
|
public final Function functionArccot = new Function() {
|
||||||
|
@Override
|
||||||
|
protected boolean matchesParams(NumberInterface[] params) {
|
||||||
|
return params.length == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
|
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
||||||
|
.subtract(functionArctan.apply(params));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public StandardPlugin(PluginManager manager) {
|
public StandardPlugin(PluginManager manager) {
|
||||||
super(manager);
|
super(manager);
|
||||||
}
|
}
|
||||||
@@ -568,6 +706,12 @@ public class StandardPlugin extends Plugin {
|
|||||||
registerFunction("sec", functionSec);
|
registerFunction("sec", functionSec);
|
||||||
registerFunction("csc", functionCsc);
|
registerFunction("csc", functionCsc);
|
||||||
registerFunction("cot", functionCot);
|
registerFunction("cot", functionCot);
|
||||||
|
registerFunction("arcsin", functionArcsin);
|
||||||
|
registerFunction("arccos", functionArccos);
|
||||||
|
registerFunction("arccsc", functionArccsc);
|
||||||
|
registerFunction("arcsec", functionArcsec);
|
||||||
|
registerFunction("arctan", functionArctan);
|
||||||
|
registerFunction("arccot", functionArccot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
19
src/main/java/org/nwapw/abacus/tree/Reducer.java
Normal file
19
src/main/java/org/nwapw/abacus/tree/Reducer.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package org.nwapw.abacus.tree;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface used to reduce a tree into a single value.
|
||||||
|
*
|
||||||
|
* @param <T> the value to reduce into.
|
||||||
|
*/
|
||||||
|
public interface Reducer<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduces the given tree into a single value of type T.
|
||||||
|
*
|
||||||
|
* @param node the node being passed in to be reduced.
|
||||||
|
* @param children the already-reduced children of this node.
|
||||||
|
* @return the resulting value from the reduce.
|
||||||
|
*/
|
||||||
|
public T reduceNode(TreeNode node, Object... children);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ data class FunctionNode(val function: String) : TreeNode() {
|
|||||||
val children: MutableList<TreeNode> = mutableListOf()
|
val children: MutableList<TreeNode> = mutableListOf()
|
||||||
|
|
||||||
override fun <T : Any> reduce(reducer: Reducer<T>): T? {
|
override fun <T : Any> reduce(reducer: Reducer<T>): T? {
|
||||||
val children = Array<Any>(children.size, { children[it].reduce(reducer) ?: return null; })
|
val children = Array<Any?>(children.size, { children[it].reduce(reducer) ?: return null; })
|
||||||
return reducer.reduceNode(this, *children)
|
return reducer.reduceNode(this, *children)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package org.nwapw.abacus.tree
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reducer interface that takes a tree and returns a single value.
|
|
||||||
*
|
|
||||||
* The reducer walks the tree, visiting the children first, converting them into
|
|
||||||
* a value, and then attempts to reduce the parent. Eventually, the single final value is returned.
|
|
||||||
*/
|
|
||||||
interface Reducer <out T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reduces the given tree node, given its already reduced children.
|
|
||||||
*
|
|
||||||
* @param treeNode the tree node to reduce.
|
|
||||||
* @param children the list of children, of type T.
|
|
||||||
*/
|
|
||||||
fun reduceNode(treeNode: TreeNode, vararg children: Any) : T?
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -57,7 +57,6 @@
|
|||||||
<Button text="Apply" onAction="#performSave"/>
|
<Button text="Apply" onAction="#performSave"/>
|
||||||
<Button text="Reload Plugins" onAction="#performReload"/>
|
<Button text="Reload Plugins" onAction="#performReload"/>
|
||||||
<Button text="Apply and Reload" onAction="#performSaveAndReload"/>
|
<Button text="Apply and Reload" onAction="#performSaveAndReload"/>
|
||||||
<Button text="Scan Plugins" onAction="#performScan"/>
|
|
||||||
</FlowPane>
|
</FlowPane>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</Tab>
|
</Tab>
|
||||||
|
|||||||
Reference in New Issue
Block a user