A lot of improvements bugfixes:
This commit is contained in:
parent
10bf7efaf8
commit
df16972589
@ -3,6 +3,7 @@ package org.warp.picalculator.gui.expression;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockVariable;
|
import org.warp.picalculator.gui.expression.blocks.BlockVariable;
|
||||||
|
import org.warp.picalculator.math.MathematicalSymbols;
|
||||||
import org.warp.picalculator.math.functions.Variable.V_TYPE;
|
import org.warp.picalculator.math.functions.Variable.V_TYPE;
|
||||||
|
|
||||||
public class InputContext {
|
public class InputContext {
|
||||||
@ -11,6 +12,7 @@ public class InputContext {
|
|||||||
|
|
||||||
public InputContext() {
|
public InputContext() {
|
||||||
this.variableTypes = new HashMap<>();
|
this.variableTypes = new HashMap<>();
|
||||||
|
this.variableTypes.put(MathematicalSymbols.PI, V_TYPE.CONSTANT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputContext(HashMap<Character, V_TYPE> variableTypes) {
|
public InputContext(HashMap<Character, V_TYPE> variableTypes) {
|
||||||
|
@ -23,22 +23,29 @@ public class BlockVariable extends Block {
|
|||||||
private int color;
|
private int color;
|
||||||
private boolean mustRefresh = true;
|
private boolean mustRefresh = true;
|
||||||
private BlockVariable typeDirtyID;
|
private BlockVariable typeDirtyID;
|
||||||
|
private final boolean typeLocked;
|
||||||
|
|
||||||
public BlockVariable(InputContext ic, char ch) {
|
public BlockVariable(InputContext ic, char ch) {
|
||||||
|
this(ic, ch, false);
|
||||||
|
}
|
||||||
|
public BlockVariable(InputContext ic, char ch, boolean typeLocked) {
|
||||||
this.ic = ic;
|
this.ic = ic;
|
||||||
this.ch = ch;
|
this.ch = ch;
|
||||||
this.menu = new VariableMenu(this);
|
this.type = V_TYPE.VARIABLE;
|
||||||
this.type = V_TYPE.UNKNOWN;
|
|
||||||
this.color = 0xFF304ffe;
|
this.color = 0xFF304ffe;
|
||||||
this.typeDirtyID = this;
|
this.typeDirtyID = this;
|
||||||
|
this.typeLocked = typeLocked;
|
||||||
|
this.menu = typeLocked ? null : new VariableMenu(this);
|
||||||
retrieveValue();
|
retrieveValue();
|
||||||
recomputeDimensions();
|
recomputeDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void retrieveValue() {
|
private void retrieveValue() {
|
||||||
type = ic.variableTypes.getOrDefault(ch, V_TYPE.UNKNOWN);
|
type = ic.variableTypes.getOrDefault(ch, V_TYPE.VARIABLE);
|
||||||
typeDirtyID = ic.variableTypeDirtyID;
|
typeDirtyID = ic.variableTypeDirtyID;
|
||||||
menu.mustRefreshMenu = true;
|
if (menu != null) {
|
||||||
|
menu.mustRefreshMenu = true;
|
||||||
|
}
|
||||||
mustRefresh = true;
|
mustRefresh = true;
|
||||||
System.out.println("retrieve:"+type.toString());
|
System.out.println("retrieve:"+type.toString());
|
||||||
}
|
}
|
||||||
@ -63,11 +70,11 @@ public class BlockVariable extends Block {
|
|||||||
if (mustRefresh) {
|
if (mustRefresh) {
|
||||||
mustRefresh = false;
|
mustRefresh = false;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case UNKNOWN:
|
case VARIABLE:
|
||||||
color = 0xFF304ffe;
|
color = 0xFF304ffe;
|
||||||
break;
|
break;
|
||||||
case COEFFICIENT:
|
case CONSTANT:
|
||||||
color = 0xFF35913F;
|
color = typeLocked ? 0xFF000000 : 0xFF35913F;
|
||||||
break;
|
break;
|
||||||
case SOLUTION:
|
case SOLUTION:
|
||||||
default:
|
default:
|
||||||
@ -149,15 +156,15 @@ public class BlockVariable extends Block {
|
|||||||
case LEFT:
|
case LEFT:
|
||||||
case UP:
|
case UP:
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
case UNKNOWN:
|
case VARIABLE:
|
||||||
block.type = V_TYPE.SOLUTION;
|
block.type = V_TYPE.SOLUTION;
|
||||||
break;
|
break;
|
||||||
case COEFFICIENT:
|
case CONSTANT:
|
||||||
block.type = V_TYPE.UNKNOWN;
|
block.type = V_TYPE.VARIABLE;
|
||||||
break;
|
break;
|
||||||
case SOLUTION:
|
case SOLUTION:
|
||||||
default:
|
default:
|
||||||
block.type = V_TYPE.COEFFICIENT;
|
block.type = V_TYPE.CONSTANT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -166,15 +173,15 @@ public class BlockVariable extends Block {
|
|||||||
case EQUAL:
|
case EQUAL:
|
||||||
case SIMPLIFY:
|
case SIMPLIFY:
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
case UNKNOWN:
|
case VARIABLE:
|
||||||
block.type = V_TYPE.COEFFICIENT;
|
block.type = V_TYPE.CONSTANT;
|
||||||
break;
|
break;
|
||||||
case COEFFICIENT:
|
case CONSTANT:
|
||||||
block.type = V_TYPE.SOLUTION;
|
block.type = V_TYPE.SOLUTION;
|
||||||
break;
|
break;
|
||||||
case SOLUTION:
|
case SOLUTION:
|
||||||
default:
|
default:
|
||||||
block.type = V_TYPE.UNKNOWN;
|
block.type = V_TYPE.VARIABLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -66,6 +66,8 @@ public class NormalInputContainer extends InputContainer {
|
|||||||
return new BlockChar(c);
|
return new BlockChar(c);
|
||||||
case MathematicalSymbols.SINE:
|
case MathematicalSymbols.SINE:
|
||||||
return new BlockSine();
|
return new BlockSine();
|
||||||
|
case MathematicalSymbols.PI:
|
||||||
|
return new BlockVariable(inputContext, c, true);
|
||||||
default:
|
default:
|
||||||
for (char v : MathematicalSymbols.variables) {
|
for (char v : MathematicalSymbols.variables) {
|
||||||
if (c == v) {
|
if (c == v) {
|
||||||
|
@ -658,7 +658,7 @@ public class MathInputScreen extends Screen {
|
|||||||
} else if (f instanceof FunctionSingle) {
|
} else if (f instanceof FunctionSingle) {
|
||||||
res.addAll(getKnownVariables(new Function[] { ((FunctionSingle) f).getParameter() }));
|
res.addAll(getKnownVariables(new Function[] { ((FunctionSingle) f).getParameter() }));
|
||||||
} else if (f instanceof Variable) {
|
} else if (f instanceof Variable) {
|
||||||
if (((Variable) f).getType() == Variable.V_TYPE.COEFFICIENT) {
|
if (((Variable) f).getType() == Variable.V_TYPE.CONSTANT) {
|
||||||
if (!res.contains(f)) {
|
if (!res.contains(f)) {
|
||||||
res.add(f);
|
res.add(f);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,9 @@ public class MathematicalSymbols {
|
|||||||
private static final char[] signumsWithoutMultiplication = new char[] { SUM, SUM_SUBTRACTION, SUBTRACTION, DIVISION };
|
private static final char[] signumsWithoutMultiplication = new char[] { SUM, SUM_SUBTRACTION, SUBTRACTION, DIVISION };
|
||||||
private static final char[] signumsWithMultiplication = Utils.add(signumsWithoutMultiplication, MULTIPLICATION);
|
private static final char[] signumsWithMultiplication = Utils.add(signumsWithoutMultiplication, MULTIPLICATION);
|
||||||
|
|
||||||
|
public static final char[] functionsNSNAndSignums = concat(functionsNSN, signumsWithMultiplication);
|
||||||
|
public static final char[] functionsAndSignums = concat(functions, signumsWithMultiplication);
|
||||||
|
|
||||||
public static final char[] signums(boolean withMultiplication) {
|
public static final char[] signums(boolean withMultiplication) {
|
||||||
if (withMultiplication) {
|
if (withMultiplication) {
|
||||||
return signumsWithMultiplication;
|
return signumsWithMultiplication;
|
||||||
|
@ -19,6 +19,7 @@ import org.warp.picalculator.math.rules.FractionsRule12;
|
|||||||
import org.warp.picalculator.math.rules.FractionsRule2;
|
import org.warp.picalculator.math.rules.FractionsRule2;
|
||||||
import org.warp.picalculator.math.rules.FractionsRule3;
|
import org.warp.picalculator.math.rules.FractionsRule3;
|
||||||
import org.warp.picalculator.math.rules.UndefinedRule2;
|
import org.warp.picalculator.math.rules.UndefinedRule2;
|
||||||
|
import org.warp.picalculator.math.rules.methods.DivisionRule1;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
|
||||||
@ -50,13 +51,16 @@ public class Division extends FunctionOperator {
|
|||||||
if (UndefinedRule2.compare(this)) {
|
if (UndefinedRule2.compare(this)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (DivisionRule1.compare(this)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (variable1 instanceof Number && variable2 instanceof Number) {
|
if (variable1 instanceof Number && variable2 instanceof Number) {
|
||||||
if (getMathContext().exactMode) {
|
if (getMathContext().exactMode) {
|
||||||
try {
|
try {
|
||||||
if (((Number) variable1).isInteger() && ((Number) variable2).isInteger()) {
|
if (((Number) variable1).isInteger() && ((Number) variable2).isInteger()) {
|
||||||
LinkedList<BigInteger> factors1 = ((Number) variable1).getFactors();
|
LinkedList<BigInteger> factors1 = ((Number) variable1).getFactors();
|
||||||
LinkedList<BigInteger> factors2 = ((Number) variable2).getFactors();
|
LinkedList<BigInteger> factors2 = ((Number) variable2).getFactors();
|
||||||
return factors1.retainAll(factors2); //True If something changed in the factors list by keeping only the intersection of the two factor lists.
|
return factors1.retainAll(factors2) /* True If something changed in the factors list by keeping only the intersection of the two factor lists */ && factors1.size() > 0 /* true if there is at least one common factor */;
|
||||||
} else if (((Number) variable1).divide((Number) variable2).isInteger()) {
|
} else if (((Number) variable1).divide((Number) variable2).isInteger()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -89,6 +93,8 @@ public class Division extends FunctionOperator {
|
|||||||
result = FractionsRule12.execute(this);
|
result = FractionsRule12.execute(this);
|
||||||
} else if (UndefinedRule2.compare(this)) {
|
} else if (UndefinedRule2.compare(this)) {
|
||||||
result = UndefinedRule2.execute(this);
|
result = UndefinedRule2.execute(this);
|
||||||
|
} else if (DivisionRule1.compare(this)) {
|
||||||
|
result = DivisionRule1.execute(this);
|
||||||
} else if (variable1 instanceof Number && variable2 instanceof Number) {
|
} else if (variable1 instanceof Number && variable2 instanceof Number) {
|
||||||
if (getMathContext().exactMode && (((Number) variable1).isInteger() && ((Number) variable2).isInteger())) {
|
if (getMathContext().exactMode && (((Number) variable1).isInteger() && ((Number) variable2).isInteger())) {
|
||||||
LinkedList<BigInteger> factors1 = ((Number) variable1).getFactors();
|
LinkedList<BigInteger> factors1 = ((Number) variable1).getFactors();
|
||||||
|
@ -3,6 +3,7 @@ package org.warp.picalculator.math.functions;
|
|||||||
import org.warp.picalculator.Error;
|
import org.warp.picalculator.Error;
|
||||||
import org.warp.picalculator.gui.expression.blocks.Block;
|
import org.warp.picalculator.gui.expression.blocks.Block;
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockChar;
|
import org.warp.picalculator.gui.expression.blocks.BlockChar;
|
||||||
|
import org.warp.picalculator.gui.expression.blocks.BlockParenthesis;
|
||||||
import org.warp.picalculator.math.Function;
|
import org.warp.picalculator.math.Function;
|
||||||
import org.warp.picalculator.math.FunctionOperator;
|
import org.warp.picalculator.math.FunctionOperator;
|
||||||
import org.warp.picalculator.math.MathContext;
|
import org.warp.picalculator.math.MathContext;
|
||||||
@ -108,18 +109,36 @@ public class Multiplication extends FunctionOperator {
|
|||||||
@Override
|
@Override
|
||||||
public ObjectArrayList<Block> toBlock(MathContext context) throws Error {
|
public ObjectArrayList<Block> toBlock(MathContext context) throws Error {
|
||||||
ObjectArrayList<Block> result = new ObjectArrayList<>();
|
ObjectArrayList<Block> result = new ObjectArrayList<>();
|
||||||
ObjectArrayList<Block> sub1 = getParameter1().toBlock(context);
|
Function par1 = getParameter1();
|
||||||
ObjectArrayList<Block> sub2 = getParameter2().toBlock(context);
|
Function par2 = getParameter2();
|
||||||
|
ObjectArrayList<Block> sub1 = par1.toBlock(context);
|
||||||
|
ObjectArrayList<Block> sub2 = par2.toBlock(context);
|
||||||
Block nearLeft = sub1.get(sub1.size()-1);
|
Block nearLeft = sub1.get(sub1.size()-1);
|
||||||
Block nearRight = sub2.get(0);
|
Block nearRight = sub2.get(0);
|
||||||
|
|
||||||
result.addAll(sub1);
|
if (par1 instanceof Number && ((Number)par1).equals(new Number(context, -1))) {
|
||||||
if (nearLeft instanceof BlockChar && nearRight instanceof BlockChar) {
|
result.add(new BlockChar(MathematicalSymbols.MINUS));
|
||||||
|
if (new Expression(context, par2).parenthesisNeeded()) {
|
||||||
|
BlockParenthesis par = new BlockParenthesis();
|
||||||
|
ObjectArrayList<Block> parBlocks = par2.toBlock(context);
|
||||||
|
for (Block b: parBlocks) {
|
||||||
|
par.getNumberContainer().appendBlockUnsafe(b); // Skips recomputeDimension
|
||||||
|
}
|
||||||
|
par.recomputeDimensions(); // Recompute dimensions after appendBlockUnsafe
|
||||||
|
result.add(par);
|
||||||
|
} else {
|
||||||
|
result.addAll(par2.toBlock(context));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
} else {
|
} else {
|
||||||
result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION));
|
result.addAll(sub1);
|
||||||
|
if ((nearLeft instanceof BlockChar && nearRight instanceof BlockChar) && !(par2 instanceof Negative)) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION));
|
||||||
|
}
|
||||||
|
result.addAll(sub2);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
result.addAll(sub2);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,9 +3,12 @@ package org.warp.picalculator.math.functions;
|
|||||||
import org.warp.picalculator.Error;
|
import org.warp.picalculator.Error;
|
||||||
import org.warp.picalculator.Errors;
|
import org.warp.picalculator.Errors;
|
||||||
import org.warp.picalculator.gui.expression.blocks.Block;
|
import org.warp.picalculator.gui.expression.blocks.Block;
|
||||||
|
import org.warp.picalculator.gui.expression.blocks.BlockChar;
|
||||||
|
import org.warp.picalculator.gui.expression.blocks.BlockParenthesis;
|
||||||
import org.warp.picalculator.math.Function;
|
import org.warp.picalculator.math.Function;
|
||||||
import org.warp.picalculator.math.FunctionSingle;
|
import org.warp.picalculator.math.FunctionSingle;
|
||||||
import org.warp.picalculator.math.MathContext;
|
import org.warp.picalculator.math.MathContext;
|
||||||
|
import org.warp.picalculator.math.MathematicalSymbols;
|
||||||
import org.warp.picalculator.math.rules.ExpandRule1;
|
import org.warp.picalculator.math.rules.ExpandRule1;
|
||||||
import org.warp.picalculator.math.rules.ExpandRule5;
|
import org.warp.picalculator.math.rules.ExpandRule5;
|
||||||
|
|
||||||
@ -19,16 +22,16 @@ public class Negative extends FunctionSingle {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isSolvable() {
|
protected boolean isSolvable() {
|
||||||
if (parameter instanceof Number) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ExpandRule1.compare(this)) {
|
if (ExpandRule1.compare(this)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (ExpandRule5.compare(this)) {
|
if (ExpandRule5.compare(this)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
if (parameter instanceof Number) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -41,10 +44,10 @@ public class Negative extends FunctionSingle {
|
|||||||
result = ExpandRule1.execute(this);
|
result = ExpandRule1.execute(this);
|
||||||
} else if (ExpandRule5.compare(this)) {
|
} else if (ExpandRule5.compare(this)) {
|
||||||
result = ExpandRule5.execute(this);
|
result = ExpandRule5.execute(this);
|
||||||
} else if (parameter.isSimplified()) {
|
} else if (parameter instanceof Number) {
|
||||||
try {
|
try {
|
||||||
final Number var = (Number) getParameter();
|
final Number var = (Number) getParameter();
|
||||||
result.add(var.multiply(new Number(mathContext, "-1")));
|
result.add(var.multiply(new Number(mathContext, -1)));
|
||||||
} catch (final NullPointerException ex) {
|
} catch (final NullPointerException ex) {
|
||||||
throw new Error(Errors.ERROR);
|
throw new Error(Errors.ERROR);
|
||||||
} catch (final NumberFormatException ex) {
|
} catch (final NumberFormatException ex) {
|
||||||
@ -53,16 +56,7 @@ public class Negative extends FunctionSingle {
|
|||||||
throw new Error(Errors.NUMBER_TOO_SMALL);
|
throw new Error(Errors.NUMBER_TOO_SMALL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final ObjectArrayList<Function> l1 = new ObjectArrayList<>();
|
result.add(new Multiplication(parameter.getMathContext(), new Number(parameter.getMathContext(), -1), parameter));
|
||||||
if (parameter.isSimplified()) {
|
|
||||||
l1.add(parameter);
|
|
||||||
} else {
|
|
||||||
l1.addAll(parameter.simplify());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Function f : l1) {
|
|
||||||
result.add(new Negative(mathContext, f));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -82,7 +76,20 @@ public class Negative extends FunctionSingle {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectArrayList<Block> toBlock(MathContext context) throws Error {
|
public ObjectArrayList<Block> toBlock(MathContext context) throws Error {
|
||||||
// TODO Auto-generated method stub
|
ObjectArrayList<Block> blocks = new ObjectArrayList<Block>();
|
||||||
throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + getClass().getSimpleName());
|
blocks.add(new BlockChar(MathematicalSymbols.MINUS));
|
||||||
|
if (new Expression(context, getParameter()).parenthesisNeeded()) {
|
||||||
|
BlockParenthesis par = new BlockParenthesis();
|
||||||
|
ObjectArrayList<Block> parBlocks = getParameter().toBlock(context);
|
||||||
|
for (Block b: parBlocks) {
|
||||||
|
par.getNumberContainer().appendBlockUnsafe(b); // Skips recomputeDimension
|
||||||
|
}
|
||||||
|
par.recomputeDimensions(); // Recompute dimensions after appendBlockUnsafe
|
||||||
|
blocks.add(par);
|
||||||
|
} else {
|
||||||
|
blocks.addAll(getParameter().toBlock(context));
|
||||||
|
}
|
||||||
|
return blocks;
|
||||||
|
// throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ public class Variable implements Function {
|
|||||||
|
|
||||||
protected char var;
|
protected char var;
|
||||||
protected final MathContext root;
|
protected final MathContext root;
|
||||||
protected V_TYPE type = V_TYPE.COEFFICIENT;
|
protected V_TYPE type = V_TYPE.CONSTANT;
|
||||||
|
|
||||||
public Variable(MathContext root, char val, V_TYPE type) {
|
public Variable(MathContext root, char val, V_TYPE type) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@ -93,7 +93,7 @@ public class Variable implements Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static enum V_TYPE {
|
public static enum V_TYPE {
|
||||||
COEFFICIENT, UNKNOWN, SOLUTION
|
CONSTANT, VARIABLE, SOLUTION
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,7 +15,11 @@ import org.warp.picalculator.math.parser.features.FeatureChar;
|
|||||||
import org.warp.picalculator.math.parser.features.FeatureDivision;
|
import org.warp.picalculator.math.parser.features.FeatureDivision;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureMultiplication;
|
import org.warp.picalculator.math.parser.features.FeatureMultiplication;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureNumber;
|
import org.warp.picalculator.math.parser.features.FeatureNumber;
|
||||||
|
import org.warp.picalculator.math.parser.features.FeaturePower;
|
||||||
|
import org.warp.picalculator.math.parser.features.FeaturePowerChar;
|
||||||
|
import org.warp.picalculator.math.parser.features.FeatureSubtraction;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureSum;
|
import org.warp.picalculator.math.parser.features.FeatureSum;
|
||||||
|
import org.warp.picalculator.math.parser.features.FeatureSumSubtraction;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureVariable;
|
import org.warp.picalculator.math.parser.features.FeatureVariable;
|
||||||
import org.warp.picalculator.math.parser.features.interfaces.Feature;
|
import org.warp.picalculator.math.parser.features.interfaces.Feature;
|
||||||
import org.warp.picalculator.math.parser.steps.JoinNumberAndVariables;
|
import org.warp.picalculator.math.parser.steps.JoinNumberAndVariables;
|
||||||
@ -92,14 +96,15 @@ public class MathParser {
|
|||||||
lastElement = null;
|
lastElement = null;
|
||||||
IntegerObj curIndex = new IntegerObj(initialIndex);
|
IntegerObj curIndex = new IntegerObj(initialIndex);
|
||||||
while(curIndex.i >= 0 && curIndex.i < functionsList.size()) {
|
while(curIndex.i >= 0 && curIndex.i < functionsList.size()) {
|
||||||
final Function f = functionsList.get(curIndex.i);
|
final int i = curIndex.i;
|
||||||
|
final Function f = functionsList.get(i);
|
||||||
|
|
||||||
if (step.eval(curIndex, lastElement, f, functionsList)) {
|
if (step.eval(curIndex, lastElement, f, functionsList)) {
|
||||||
lastLoopDidSomething = true;
|
lastLoopDidSomething = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastElement=f;
|
lastElement = (i >= functionsList.size()) ? null : functionsList.get(i);
|
||||||
curIndex.i+=stepQty;
|
curIndex.i += stepQty;
|
||||||
}
|
}
|
||||||
} while (lastLoopDidSomething);
|
} while (lastLoopDidSomething);
|
||||||
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: ");
|
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: ");
|
||||||
@ -132,6 +137,8 @@ public class MathParser {
|
|||||||
|
|
||||||
features = makeNumbers(context, features);
|
features = makeNumbers(context, features);
|
||||||
|
|
||||||
|
features = makePowers(context, features);
|
||||||
|
|
||||||
features = convertFunctionChars(context, features);
|
features = convertFunctionChars(context, features);
|
||||||
|
|
||||||
return features;
|
return features;
|
||||||
@ -172,7 +179,7 @@ public class MathParser {
|
|||||||
|
|
||||||
for (char var : MathematicalSymbols.variables) {
|
for (char var : MathematicalSymbols.variables) {
|
||||||
if (featureChar == var) {
|
if (featureChar == var) {
|
||||||
result = new FeatureVariable(featureChar, V_TYPE.UNKNOWN);
|
result = new FeatureVariable(featureChar, V_TYPE.VARIABLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,7 +219,7 @@ public class MathParser {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bcf.ch == '-' || bcf.ch == '.') {
|
if (bcf.ch == MathematicalSymbols.MINUS || bcf.ch == '.') {
|
||||||
isNumber = true;
|
isNumber = true;
|
||||||
}
|
}
|
||||||
if (isNumber) {
|
if (isNumber) {
|
||||||
@ -249,13 +256,13 @@ public class MathParser {
|
|||||||
final ObjectArrayList<Feature> process = new ObjectArrayList<>();
|
final ObjectArrayList<Feature> process = new ObjectArrayList<>();
|
||||||
Feature lastFeature = null;
|
Feature lastFeature = null;
|
||||||
for (final Feature f : features) {
|
for (final Feature f : features) {
|
||||||
if (f instanceof FeatureChar && ((FeatureChar) f).ch == MathematicalSymbols.SUBTRACTION) {
|
if (f instanceof FeatureChar && (((FeatureChar) f).ch == MathematicalSymbols.SUBTRACTION || ((FeatureChar) f).ch == MathematicalSymbols.MINUS)) {
|
||||||
boolean isNegativeOfNumber = false;
|
boolean isNegativeOfNumber = false;
|
||||||
if (lastFeature == null) {
|
if (lastFeature == null) {
|
||||||
isNegativeOfNumber = true;
|
isNegativeOfNumber = true;
|
||||||
} else if (lastFeature instanceof FeatureChar) {
|
} else if (lastFeature instanceof FeatureChar) {
|
||||||
final FeatureChar lcf = (FeatureChar) lastFeature;
|
final FeatureChar lcf = (FeatureChar) lastFeature;
|
||||||
final char[] operators = MathematicalSymbols.functionsNSN;
|
final char[] operators = MathematicalSymbols.functionsAndSignums;
|
||||||
for (final char operator : operators) {
|
for (final char operator : operators) {
|
||||||
if (lcf.ch == operator) {
|
if (lcf.ch == operator) {
|
||||||
isNegativeOfNumber = true;
|
isNegativeOfNumber = true;
|
||||||
@ -275,4 +282,32 @@ public class MathParser {
|
|||||||
}
|
}
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make powers [12][^[15]] => [[12]^[15]]
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param features
|
||||||
|
* @return
|
||||||
|
* @throws Error
|
||||||
|
*/
|
||||||
|
private static ObjectArrayList<Feature> makePowers(MathContext context, ObjectArrayList<Feature> features) throws Error {
|
||||||
|
final ObjectArrayList<Feature> process = new ObjectArrayList<>();
|
||||||
|
|
||||||
|
Feature lastFeature = null;
|
||||||
|
for (final Feature f : features) {
|
||||||
|
if (f instanceof FeaturePowerChar) {
|
||||||
|
if (lastFeature != null) {
|
||||||
|
process.set(process.size() - 1, new FeaturePower(lastFeature.toFunction(context), ((FeaturePowerChar) f).getChild()));
|
||||||
|
} else {
|
||||||
|
process.add(f);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
process.add(f);
|
||||||
|
}
|
||||||
|
lastFeature = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return process;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package org.warp.picalculator.math.parser.features;
|
|||||||
import org.warp.picalculator.Error;
|
import org.warp.picalculator.Error;
|
||||||
import org.warp.picalculator.math.Function;
|
import org.warp.picalculator.math.Function;
|
||||||
import org.warp.picalculator.math.MathContext;
|
import org.warp.picalculator.math.MathContext;
|
||||||
|
import org.warp.picalculator.math.MathematicalSymbols;
|
||||||
import org.warp.picalculator.math.functions.Number;
|
import org.warp.picalculator.math.functions.Number;
|
||||||
import org.warp.picalculator.math.parser.features.interfaces.FeatureBasic;
|
import org.warp.picalculator.math.parser.features.interfaces.FeatureBasic;
|
||||||
|
|
||||||
@ -31,6 +32,16 @@ public class FeatureNumber implements FeatureBasic {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Number toFunction(MathContext context) throws Error {
|
public Number toFunction(MathContext context) throws Error {
|
||||||
return new Number(context, getNumberString());
|
String nmbstr = getNumberString();
|
||||||
|
if (nmbstr.charAt(0) == '.') {
|
||||||
|
nmbstr = '0' + nmbstr;
|
||||||
|
} else if (nmbstr.charAt(nmbstr.length() - 1) == '.') {
|
||||||
|
nmbstr += "0";
|
||||||
|
} else if (nmbstr.charAt(0) == MathematicalSymbols.MINUS) {
|
||||||
|
nmbstr += "1";
|
||||||
|
} else if (nmbstr.charAt(0) == MathematicalSymbols.SUBTRACTION) {
|
||||||
|
nmbstr += "1";
|
||||||
|
}
|
||||||
|
return new Number(context, nmbstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package org.warp.picalculator.math.parser;
|
package org.warp.picalculator.math.parser.features;
|
||||||
|
|
||||||
import org.warp.picalculator.Error;
|
import org.warp.picalculator.Error;
|
||||||
import org.warp.picalculator.math.Function;
|
import org.warp.picalculator.math.Function;
|
||||||
import org.warp.picalculator.math.MathContext;
|
import org.warp.picalculator.math.MathContext;
|
||||||
import org.warp.picalculator.math.functions.Subtraction;
|
import org.warp.picalculator.math.functions.Subtraction;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureDoubleImpl;
|
|
||||||
import org.warp.picalculator.math.parser.features.interfaces.Feature;
|
import org.warp.picalculator.math.parser.features.interfaces.Feature;
|
||||||
import org.warp.picalculator.math.parser.features.interfaces.FeatureDouble;
|
import org.warp.picalculator.math.parser.features.interfaces.FeatureDouble;
|
||||||
|
|
@ -1,10 +1,9 @@
|
|||||||
package org.warp.picalculator.math.parser;
|
package org.warp.picalculator.math.parser.features;
|
||||||
|
|
||||||
import org.warp.picalculator.Error;
|
import org.warp.picalculator.Error;
|
||||||
import org.warp.picalculator.math.Function;
|
import org.warp.picalculator.math.Function;
|
||||||
import org.warp.picalculator.math.MathContext;
|
import org.warp.picalculator.math.MathContext;
|
||||||
import org.warp.picalculator.math.functions.SumSubtraction;
|
import org.warp.picalculator.math.functions.SumSubtraction;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureDoubleImpl;
|
|
||||||
import org.warp.picalculator.math.parser.features.interfaces.Feature;
|
import org.warp.picalculator.math.parser.features.interfaces.Feature;
|
||||||
|
|
||||||
public class FeatureSumSubtraction extends FeatureDoubleImpl {
|
public class FeatureSumSubtraction extends FeatureDoubleImpl {
|
@ -1,8 +1,10 @@
|
|||||||
package org.warp.picalculator.math.parser.steps;
|
package org.warp.picalculator.math.parser.steps;
|
||||||
|
|
||||||
import org.warp.picalculator.IntegerObj;
|
import org.warp.picalculator.IntegerObj;
|
||||||
|
import org.warp.picalculator.Utils;
|
||||||
import org.warp.picalculator.math.Function;
|
import org.warp.picalculator.math.Function;
|
||||||
import org.warp.picalculator.math.MathContext;
|
import org.warp.picalculator.math.MathContext;
|
||||||
|
import org.warp.picalculator.math.functions.Division;
|
||||||
import org.warp.picalculator.math.functions.Multiplication;
|
import org.warp.picalculator.math.functions.Multiplication;
|
||||||
import org.warp.picalculator.math.functions.Number;
|
import org.warp.picalculator.math.functions.Number;
|
||||||
import org.warp.picalculator.math.functions.Variable;
|
import org.warp.picalculator.math.functions.Variable;
|
||||||
@ -20,11 +22,11 @@ public class JoinNumberAndVariables implements MathParserStep {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList<Function> functionsList) {
|
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList<Function> functionsList) {
|
||||||
if (currentFunction instanceof Number | currentFunction instanceof Variable) {
|
if (currentFunction instanceof Number | currentFunction instanceof Variable | currentFunction instanceof Division) {
|
||||||
if (lastFunction instanceof Variable | lastFunction instanceof Number | (lastFunction instanceof Multiplication && ((Multiplication)lastFunction).getParameter2() != null)) {
|
if (lastFunction instanceof Variable | lastFunction instanceof Number | (lastFunction instanceof Multiplication && ((Multiplication)lastFunction).getParameter2() != null)) {
|
||||||
final Function var = lastFunction;
|
final Function a = currentFunction;
|
||||||
final Function numb = currentFunction;
|
final Function b = lastFunction;
|
||||||
functionsList.set(curIndex.i, new Multiplication(context, numb, var));
|
functionsList.set(curIndex.i, new Multiplication(context, a, b));
|
||||||
functionsList.remove(curIndex.i + 1);
|
functionsList.remove(curIndex.i + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package org.warp.picalculator.math.rules;
|
|||||||
import org.warp.picalculator.Error;
|
import org.warp.picalculator.Error;
|
||||||
import org.warp.picalculator.math.Function;
|
import org.warp.picalculator.math.Function;
|
||||||
import org.warp.picalculator.math.functions.Division;
|
import org.warp.picalculator.math.functions.Division;
|
||||||
import org.warp.picalculator.math.functions.Expression;
|
|
||||||
import org.warp.picalculator.math.functions.Multiplication;
|
import org.warp.picalculator.math.functions.Multiplication;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
@ -62,21 +61,21 @@ public class FractionsRule14 {
|
|||||||
b = div1.getParameter2();
|
b = div1.getParameter2();
|
||||||
c = div2.getParameter1();
|
c = div2.getParameter1();
|
||||||
d = div2.getParameter2();
|
d = div2.getParameter2();
|
||||||
final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), b), new Expression(fnc.getMathContext(), d)));
|
final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), new Multiplication(fnc.getMathContext(), b, d));
|
||||||
result.add(div);
|
result.add(div);
|
||||||
} else if (fnc.getParameter1() instanceof Division) {
|
} else if (fnc.getParameter1() instanceof Division) {
|
||||||
final Division div1 = (Division) fnc.getParameter1();
|
final Division div1 = (Division) fnc.getParameter1();
|
||||||
a = div1.getParameter1();
|
a = div1.getParameter1();
|
||||||
b = div1.getParameter2();
|
b = div1.getParameter2();
|
||||||
c = fnc.getParameter2();
|
c = fnc.getParameter2();
|
||||||
final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), b);
|
final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), b);
|
||||||
result.add(div);
|
result.add(div);
|
||||||
} else if (fnc.getParameter2() instanceof Division) {
|
} else if (fnc.getParameter2() instanceof Division) {
|
||||||
final Division div2 = (Division) fnc.getParameter2();
|
final Division div2 = (Division) fnc.getParameter2();
|
||||||
a = fnc.getParameter1();
|
a = fnc.getParameter1();
|
||||||
c = div2.getParameter1();
|
c = div2.getParameter1();
|
||||||
d = div2.getParameter2();
|
d = div2.getParameter2();
|
||||||
final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), d);
|
final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), d);
|
||||||
result.add(div);
|
result.add(div);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -11,7 +11,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Division method<br>
|
* Division method<br>
|
||||||
* <b>Example: (XY)/(YZ) = X/Z</b>
|
* <b>Example: (XY)/(YZ) = Y/Y * X/Z</b>
|
||||||
*
|
*
|
||||||
* @author Andrea Cavalli
|
* @author Andrea Cavalli
|
||||||
*
|
*
|
||||||
@ -19,18 +19,19 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|||||||
public class DivisionRule1 {
|
public class DivisionRule1 {
|
||||||
|
|
||||||
public static boolean compare(Division f) {
|
public static boolean compare(Division f) {
|
||||||
return f.getParameter1().isSimplified() && f.getParameter2().isSimplified() && !(f.getParameter1() instanceof Number && f.getParameter2() instanceof Number) && getFirstWorkingDivisionCouple(getDivisionElements(f)) != null;
|
return f.getParameter1().isSimplified() && f.getParameter2().isSimplified() && (f.getParameter1() instanceof Multiplication || f.getParameter2() instanceof Multiplication) && getFirstWorkingDivisionCouple(getDivisionElements(f)) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectArrayList<Function> execute(Division f) throws Error {
|
public static ObjectArrayList<Function> execute(Division f) throws Error {
|
||||||
|
System.out.println(f);
|
||||||
final MathContext root = f.getMathContext();
|
final MathContext root = f.getMathContext();
|
||||||
Function result;
|
Function result;
|
||||||
final ObjectArrayList<Function> elements = getDivisionElements(f);
|
final ObjectArrayList<Function>[] elements = getDivisionElements(f);
|
||||||
final int[] workingElementCouple = getFirstWorkingDivisionCouple(elements);
|
final int[] workingElementCouple = getFirstWorkingDivisionCouple(elements);
|
||||||
final Function elem1 = elements.get(workingElementCouple[0]);
|
final Function elem1 = elements[0].get(workingElementCouple[0]);
|
||||||
final Function elem2 = elements.get(workingElementCouple[1]);
|
final Function elem2 = elements[1].get(workingElementCouple[1]);
|
||||||
|
|
||||||
final int size = elements.size();
|
/*final int size = elements.size();
|
||||||
Function prec = new Multiplication(root, elem1, elem2);
|
Function prec = new Multiplication(root, elem1, elem2);
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
if (i != workingElementCouple[0] & i != workingElementCouple[1]) {
|
if (i != workingElementCouple[0] & i != workingElementCouple[1]) {
|
||||||
@ -38,17 +39,42 @@ public class DivisionRule1 {
|
|||||||
final Function b = elements.get(i);
|
final Function b = elements.get(i);
|
||||||
prec = new Multiplication(root, a, b);
|
prec = new Multiplication(root, a, b);
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
final int[] size = new int[] {elements[0].size(), elements[1].size()};
|
||||||
|
Function separatedDivision = new Division(root, elem1, elem2);
|
||||||
|
|
||||||
|
Function[] resultDivisionArray = new Function[2];
|
||||||
|
Function prec;
|
||||||
|
for (int part = 0; part < 2; part++) {
|
||||||
|
prec = null;
|
||||||
|
for (int i = size[part] - 1; i >= 0; i--) {
|
||||||
|
if (i != workingElementCouple[part]) {
|
||||||
|
if (prec == null) {
|
||||||
|
prec = elements[part].get(i);
|
||||||
|
} else {
|
||||||
|
final Function a = elements[part].get(i);
|
||||||
|
final Function b = prec;
|
||||||
|
prec = new Multiplication(root, a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (prec == null) {
|
||||||
|
prec = new Number(root, 1);
|
||||||
|
}
|
||||||
|
resultDivisionArray[part] = prec;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = prec;
|
result = new Multiplication(root, separatedDivision, new Division(root, resultDivisionArray[0], resultDivisionArray[1]));
|
||||||
|
|
||||||
final ObjectArrayList<Function> results = new ObjectArrayList<>();
|
final ObjectArrayList<Function> results = new ObjectArrayList<>();
|
||||||
results.add(result);
|
results.add(result);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ObjectArrayList<Function> getDivisionElements(Division division) {
|
@SuppressWarnings("unchecked")
|
||||||
/*
|
private static ObjectArrayList<Function>[] getDivisionElements(Division division) {
|
||||||
final ObjectArrayList<Function> elementsNumerator = new ObjectArrayList<>();
|
final ObjectArrayList<Function> elementsNumerator = new ObjectArrayList<>();
|
||||||
Function numMult = division.getParameter1();
|
Function numMult = division.getParameter1();
|
||||||
while (numMult instanceof Multiplication) {
|
while (numMult instanceof Multiplication) {
|
||||||
@ -58,42 +84,35 @@ public class DivisionRule1 {
|
|||||||
elementsNumerator.add(numMult);
|
elementsNumerator.add(numMult);
|
||||||
|
|
||||||
final ObjectArrayList<Function> elementsDenominator = new ObjectArrayList<>();
|
final ObjectArrayList<Function> elementsDenominator = new ObjectArrayList<>();
|
||||||
Function denomMult = division.getParameter1();
|
Function denomMult = division.getParameter2();
|
||||||
while (denomMult instanceof Multiplication) {
|
while (denomMult instanceof Multiplication) {
|
||||||
elementsDenominator.add(((Multiplication) denomMult).getParameter1());
|
elementsDenominator.add(((Multiplication) denomMult).getParameter1());
|
||||||
denomMult = ((Multiplication) denomMult).getParameter2();
|
denomMult = ((Multiplication) denomMult).getParameter2();
|
||||||
}
|
}
|
||||||
elementsDenominator.add(denomMult);
|
elementsDenominator.add(denomMult);
|
||||||
|
|
||||||
return elements;
|
return new ObjectArrayList[] {elementsNumerator, elementsDenominator};
|
||||||
*/
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] getFirstWorkingDivisionCouple(ObjectArrayList<Function> elements) {
|
private static int[] getFirstWorkingDivisionCouple(ObjectArrayList<Function>[] elements) {
|
||||||
/*
|
final int[] size = new int[] {elements[0].size(), elements[1].size()};
|
||||||
final int size = elements.size();
|
|
||||||
Function a;
|
Function a;
|
||||||
Function b;
|
Function b;
|
||||||
if (elements.size() == 2) {
|
if (elements[0].size() + elements[1].size() <= 2) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size[0]; i++) {
|
||||||
a = elements.get(i);
|
a = elements[0].get(i);
|
||||||
for (int j = 0; j < size; j++) {
|
for (int j = 0; j < size[1]; j++) {
|
||||||
b = elements.get(j);
|
b = elements[1].get(j);
|
||||||
if (i != j) {
|
Function testFunc;
|
||||||
Function testFunc;
|
testFunc = new Division(a.getMathContext(), a, b);
|
||||||
testFunc = new Multiplication(root, a, b);
|
if (!testFunc.isSimplified()) {
|
||||||
if (!testFunc.isSimplified()) {
|
return new int[] { i, j };
|
||||||
return new int[] { i, j };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
*/
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user