mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-27 17:15:21 +00:00
Compare commits
6 Commits
inv-trig
...
live-reloa
| Author | SHA1 | Date | |
|---|---|---|---|
| 5e3daaed43 | |||
| b99ad5a09a | |||
| ff8701a7bf | |||
| 7dcc80fcae | |||
| d10536155b | |||
| 536cac7b23 |
@@ -255,13 +255,7 @@ 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);
|
||||||
abacusPluginManager.addInstantiated(new StandardPlugin(abacus.getPluginManager()));
|
performScan();
|
||||||
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) -> {
|
||||||
@@ -311,6 +305,19 @@ 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,6 +240,7 @@ 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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -250,6 +251,7 @@ 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.
|
||||||
*/
|
*/
|
||||||
protected Map<Class<? extends NumberInterface>, Function<NumberInterface, NumberInterface>> promotionPaths;
|
private Map<Class<? extends NumberInterface>, Function<NumberInterface, NumberInterface>> promotionPaths;
|
||||||
/**
|
/**
|
||||||
* The implementation class for this implementation.
|
* The implementation class for this implementation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -187,6 +187,24 @@ 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,144 +451,6 @@ 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);
|
||||||
}
|
}
|
||||||
@@ -706,12 +568,6 @@ 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
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
src/main/kotlin/org/nwapw/abacus/tree/Reducer.kt
Normal file
19
src/main/kotlin/org/nwapw/abacus/tree/Reducer.kt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
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,6 +57,7 @@
|
|||||||
<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