A lot of improvements bugfixes:

This commit is contained in:
Andrea Cavalli 2017-07-24 23:11:29 +02:00
parent 10bf7efaf8
commit df16972589
16 changed files with 205 additions and 95 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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;

View File

@ -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();

View File

@ -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;
} }
} }

View File

@ -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());
} }
} }

View File

@ -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

View File

@ -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;
}
} }

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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 {

View File

@ -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;
} }

View File

@ -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;

View File

@ -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;
} }
} }