auto-sync
This commit is contained in:
parent
caf2171d96
commit
5486e53843
|
@ -1,8 +1,6 @@
|
||||||
<component name="libraryTable">
|
<component name="libraryTable">
|
||||||
<library name="commons-math3">
|
<library name="commons-math3">
|
||||||
<CLASSES>
|
<CLASSES />
|
||||||
<root url="jar://$PROJECT_DIR$/lib/commons-math3-3.3.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES />
|
<SOURCES />
|
||||||
</library>
|
</library>
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
<zipfileset src="lib/batik/batik-awt-util.jar" includes="**/*.class"/>
|
<zipfileset src="lib/batik/batik-awt-util.jar" includes="**/*.class"/>
|
||||||
<zipfileset src="lib/batik/batik-util.jar" includes="**/*.class"/>
|
<zipfileset src="lib/batik/batik-util.jar" includes="**/*.class"/>
|
||||||
|
|
||||||
|
|
||||||
<zipfileset dir="build/classes" includes="**/*.class"/>
|
<zipfileset dir="build/classes" includes="**/*.class"/>
|
||||||
</jar>
|
</jar>
|
||||||
</target>
|
</target>
|
||||||
|
|
Binary file not shown.
|
@ -20,7 +20,6 @@
|
||||||
<orderEntry type="library" name="junit" level="project" />
|
<orderEntry type="library" name="junit" level="project" />
|
||||||
<orderEntry type="library" name="SteelSeries" level="project" />
|
<orderEntry type="library" name="SteelSeries" level="project" />
|
||||||
<orderEntry type="module" module-name="io" />
|
<orderEntry type="module" module-name="io" />
|
||||||
<orderEntry type="library" name="commons-math3" level="project" />
|
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,6 @@ import java.util.Locale;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.apache.commons.math3.complex.Complex;
|
|
||||||
import org.apache.commons.math3.complex.ComplexFormat;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for parsing and evaluating math expressions
|
* Class for parsing and evaluating math expressions
|
||||||
*
|
*
|
||||||
|
@ -46,12 +43,8 @@ public class BracerParser {
|
||||||
private final String OPERATORS = "+-*/&|!";
|
private final String OPERATORS = "+-*/&|!";
|
||||||
/* separator of arguments */
|
/* separator of arguments */
|
||||||
private final String SEPARATOR = ",";
|
private final String SEPARATOR = ",";
|
||||||
/* imaginary symbol */
|
|
||||||
private final String IMAGINARY = "I";
|
|
||||||
/* variable token */
|
/* variable token */
|
||||||
private final String VARIABLE = "var";
|
private final String VARIABLE = "var";
|
||||||
/* settings for complex formatting */
|
|
||||||
private ComplexFormat complexFormat = new ComplexFormat(IMAGINARY);
|
|
||||||
/* settings for numbers formatting */
|
/* settings for numbers formatting */
|
||||||
private NumberFormat numberFormat = NumberFormat.getInstance(Locale.US);
|
private NumberFormat numberFormat = NumberFormat.getInstance(Locale.US);
|
||||||
/* temporary stack that holds operators, functions and brackets */
|
/* temporary stack that holds operators, functions and brackets */
|
||||||
|
@ -80,7 +73,6 @@ public class BracerParser {
|
||||||
public void setPrecision(int precision) {
|
public void setPrecision(int precision) {
|
||||||
numberFormat.setMinimumFractionDigits(precision);
|
numberFormat.setMinimumFractionDigits(precision);
|
||||||
numberFormat.setMaximumFractionDigits(precision);
|
numberFormat.setMaximumFractionDigits(precision);
|
||||||
complexFormat = new ComplexFormat(IMAGINARY, numberFormat, numberFormat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +103,6 @@ public class BracerParser {
|
||||||
* degree character
|
* degree character
|
||||||
*/
|
*/
|
||||||
expression = expression.replace(" ", "")
|
expression = expression.replace(" ", "")
|
||||||
.replace("°", "*" + Double.toString(Math.PI) + "/180")
|
|
||||||
.replace("(-", "(0-").replace(",-", ",0-").replace("(+", "(0+")
|
.replace("(-", "(0-").replace(",-", ",0-").replace("(+", "(0+")
|
||||||
.replace(",+", ",0+").replace("true", "1").replace("false", "0")
|
.replace(",+", ",0+").replace("true", "1").replace("false", "0")
|
||||||
.replace("or", "|").replace("and", "&");
|
.replace("or", "|").replace("and", "&");
|
||||||
|
@ -143,14 +134,7 @@ public class BracerParser {
|
||||||
stackRPN.push(stackOperations.pop());
|
stackRPN.push(stackOperations.pop());
|
||||||
}
|
}
|
||||||
} else if (isNumber(token)) {
|
} else if (isNumber(token)) {
|
||||||
if (token.equals(IMAGINARY)) {
|
|
||||||
stackRPN.push(complexFormat.format(new Complex(0, 1)));
|
|
||||||
} else if (token.contains(IMAGINARY)) {
|
|
||||||
stackRPN.push(complexFormat.format(complexFormat.parse("0+"
|
|
||||||
+ token)));
|
|
||||||
} else {
|
|
||||||
stackRPN.push(token);
|
stackRPN.push(token);
|
||||||
}
|
|
||||||
} else if (isOperator(token)) {
|
} else if (isOperator(token)) {
|
||||||
while (!stackOperations.empty()
|
while (!stackOperations.empty()
|
||||||
&& isOperator(stackOperations.lastElement())
|
&& isOperator(stackOperations.lastElement())
|
||||||
|
@ -220,22 +204,22 @@ public class BracerParser {
|
||||||
if (isNumber(token)) {
|
if (isNumber(token)) {
|
||||||
stackAnswer.push(token);
|
stackAnswer.push(token);
|
||||||
} else if (isOperator(token)) {
|
} else if (isOperator(token)) {
|
||||||
Complex a = complexFormat.parse(stackAnswer.pop());
|
Double a = Double.valueOf(stackAnswer.pop());
|
||||||
Complex b = complexFormat.parse(stackAnswer.pop());
|
Double b = Double.valueOf(stackAnswer.pop());
|
||||||
boolean aBoolean = a.getReal() == 1.0;
|
boolean aBoolean = a.doubleValue() == 1.0;
|
||||||
boolean bBoolean = b.getReal() == 1.0;
|
boolean bBoolean = b.doubleValue() == 1.0;
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case "+":
|
case "+":
|
||||||
stackAnswer.push(complexFormat.format(b.add(a)));
|
stackAnswer.push(Double.toString(b + a));
|
||||||
break;
|
break;
|
||||||
case "-":
|
case "-":
|
||||||
stackAnswer.push(complexFormat.format(b.subtract(a)));
|
stackAnswer.push(Double.toString(b - (a)));
|
||||||
break;
|
break;
|
||||||
case "*":
|
case "*":
|
||||||
stackAnswer.push(complexFormat.format(b.multiply(a)));
|
stackAnswer.push(Double.toString(b * (a)));
|
||||||
break;
|
break;
|
||||||
case "/":
|
case "/":
|
||||||
stackAnswer.push(complexFormat.format(b.divide(a)));
|
stackAnswer.push(Double.toString(b / (a)));
|
||||||
break;
|
break;
|
||||||
case "|":
|
case "|":
|
||||||
stackAnswer.push(String.valueOf(aBoolean || bBoolean ? "1" : "0"));
|
stackAnswer.push(String.valueOf(aBoolean || bBoolean ? "1" : "0"));
|
||||||
|
@ -245,70 +229,66 @@ public class BracerParser {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (isFunction(token)) {
|
} else if (isFunction(token)) {
|
||||||
Complex a = complexFormat.parse(stackAnswer.pop());
|
Double a = Double.valueOf(stackAnswer.pop());
|
||||||
boolean aBoolean = a.getReal() == 1.0;
|
boolean aBoolean = a.doubleValue() == 1.0;
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case "abs":
|
// case "abs":
|
||||||
stackAnswer.push(complexFormat.format(a.abs()));
|
// stackAnswer.push(Double.toString(a.abs()));
|
||||||
break;
|
// break;
|
||||||
case "acos":
|
// case "acos":
|
||||||
stackAnswer.push(complexFormat.format(a.acos()));
|
// stackAnswer.push(Double.toString(a.acos()));
|
||||||
break;
|
// break;
|
||||||
case "arg":
|
// case "arg":
|
||||||
stackAnswer.push(complexFormat.format(a.getArgument()));
|
// stackAnswer.push(complexFormat.format(a.getArgument()));
|
||||||
break;
|
// break;
|
||||||
case "asin":
|
// case "asin":
|
||||||
stackAnswer.push(complexFormat.format(a.asin()));
|
// stackAnswer.push(complexFormat.format(a.asin()));
|
||||||
break;
|
// break;
|
||||||
case "atan":
|
// case "atan":
|
||||||
stackAnswer.push(complexFormat.format(a.atan()));
|
// stackAnswer.push(complexFormat.format(a.atan()));
|
||||||
break;
|
// break;
|
||||||
case "conj":
|
// case "conj":
|
||||||
stackAnswer.push(complexFormat.format(a.conjugate()));
|
// stackAnswer.push(complexFormat.format(a.conjugate()));
|
||||||
break;
|
// break;
|
||||||
case "cos":
|
case "cos":
|
||||||
stackAnswer.push(complexFormat.format(a.cos()));
|
stackAnswer.push(Double.toString(Math.cos(a)));
|
||||||
break;
|
|
||||||
case "cosh":
|
|
||||||
stackAnswer.push(complexFormat.format(a.cosh()));
|
|
||||||
break;
|
break;
|
||||||
|
// case "cosh":
|
||||||
|
// stackAnswer.push(complexFormat.format(a.cosh()));
|
||||||
|
// break;
|
||||||
case "exp":
|
case "exp":
|
||||||
stackAnswer.push(complexFormat.format(a.exp()));
|
stackAnswer.push(Double.toString(Math.exp(a)));
|
||||||
break;
|
|
||||||
case "imag":
|
|
||||||
stackAnswer.push(complexFormat.format(a.getImaginary()));
|
|
||||||
break;
|
|
||||||
case "log":
|
|
||||||
stackAnswer.push(complexFormat.format(a.log()));
|
|
||||||
break;
|
|
||||||
case "neg":
|
|
||||||
stackAnswer.push(complexFormat.format(a.negate()));
|
|
||||||
break;
|
|
||||||
case "real":
|
|
||||||
stackAnswer.push(complexFormat.format(a.getReal()));
|
|
||||||
break;
|
break;
|
||||||
|
// case "imag":
|
||||||
|
// stackAnswer.push(complexFormat.format(a.getImaginary()));
|
||||||
|
// break;
|
||||||
|
// case "log":
|
||||||
|
// stackAnswer.push(complexFormat.format(a.log()));
|
||||||
|
// break;
|
||||||
|
// case "neg":
|
||||||
|
// stackAnswer.push(complexFormat.format(a.negate()));
|
||||||
|
// break;
|
||||||
case "sin":
|
case "sin":
|
||||||
stackAnswer.push(complexFormat.format(a.sin()));
|
stackAnswer.push(Double.toString(Math.sin(a)));
|
||||||
break;
|
|
||||||
case "sinh":
|
|
||||||
stackAnswer.push(complexFormat.format(a.sinh()));
|
|
||||||
break;
|
|
||||||
case "sqrt":
|
|
||||||
stackAnswer.push(complexFormat.format(a.sqrt()));
|
|
||||||
break;
|
|
||||||
case "tan":
|
|
||||||
stackAnswer.push(complexFormat.format(a.tan()));
|
|
||||||
break;
|
|
||||||
case "tanh":
|
|
||||||
stackAnswer.push(complexFormat.format(a.tanh()));
|
|
||||||
break;
|
break;
|
||||||
|
// case "sqrt":
|
||||||
|
// stackAnswer.push(Double.toString(a.sqrt()));
|
||||||
|
// break;
|
||||||
|
// case "tan":
|
||||||
|
// stackAnswer.push(Double.toString(a.tan()));
|
||||||
|
// break;
|
||||||
|
// case "tanh":
|
||||||
|
// stackAnswer.push(Double.toString(a.tanh()));
|
||||||
|
// break;
|
||||||
case "pow":
|
case "pow":
|
||||||
Complex b = complexFormat.parse(stackAnswer.pop());
|
Double b = Double.valueOf(stackAnswer.pop());
|
||||||
stackAnswer.push(complexFormat.format(b.pow(a)));
|
stackAnswer.push(Double.toString(Math.pow(a, b)));
|
||||||
break;
|
break;
|
||||||
case "not":
|
case "not":
|
||||||
stackAnswer.push(String.valueOf(!aBoolean ? "1" : "0"));
|
stackAnswer.push(String.valueOf(!aBoolean ? "1" : "0"));
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unexpected: " + token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,44 +300,6 @@ public class BracerParser {
|
||||||
return stackAnswer.pop();
|
return stackAnswer.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates non-variable expression and returns it's value as a Complex
|
|
||||||
* object
|
|
||||||
*
|
|
||||||
* @return <code>Complex</code> representation of complex number
|
|
||||||
* @throws <code>ParseException</code> if the input expression is not
|
|
||||||
* correct
|
|
||||||
* @since 4.0
|
|
||||||
*/
|
|
||||||
public Complex evaluateComplex() throws ParseException {
|
|
||||||
return complexFormat.parse(evaluate());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates variable expression and returns it's value as a Complex object
|
|
||||||
*
|
|
||||||
* @param variableValue User-specified <code>Double</code> value
|
|
||||||
* @return <code>Complex</code> representation of complex number
|
|
||||||
* @throws <code>ParseException</code> if the input expression is not
|
|
||||||
* correct
|
|
||||||
* @since 4.0
|
|
||||||
*/
|
|
||||||
public Complex evaluateComplex(double variableValue) throws ParseException {
|
|
||||||
return complexFormat.parse(evaluate(variableValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts <code>Complex</code> object to it's <code>String</code>
|
|
||||||
* representation
|
|
||||||
*
|
|
||||||
* @param number Input <code>Complex</code> number to convert
|
|
||||||
* @return <code>String</code> representation of complex number
|
|
||||||
* @since 5.0
|
|
||||||
*/
|
|
||||||
public String format(Complex number) {
|
|
||||||
return complexFormat.format(number);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get back an <b>unmodifiable copy</b> of the stack
|
* Get back an <b>unmodifiable copy</b> of the stack
|
||||||
*/
|
*/
|
||||||
|
@ -377,7 +319,7 @@ public class BracerParser {
|
||||||
try {
|
try {
|
||||||
Double.parseDouble(token);
|
Double.parseDouble(token);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return token.contains(IMAGINARY) || token.equals(VARIABLE);
|
return token.equals(VARIABLE);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Dmytro Titov
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.autsia.bracer.test;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.autsia.bracer.BracerParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class.
|
||||||
|
* User: Dmytro
|
||||||
|
* Date: 23.01.13
|
||||||
|
* Time: 12:52
|
||||||
|
*/
|
||||||
|
public class BracerParserTest {
|
||||||
|
private final String INPUT_NOVAR = "-sin(3+4+cos(6)/exp(10/pow(22,-1)))";
|
||||||
|
private final String INPUT_VAR = "-sin(3+var+cos(10)/exp(10/pow(22,-1)))";
|
||||||
|
private BracerParser bracerParser;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
bracerParser = new BracerParser(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetPrecision() throws Exception {
|
||||||
|
bracerParser.setPrecision(10);
|
||||||
|
Assert.assertEquals(10, bracerParser.getPrecision());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPrecision() throws Exception {
|
||||||
|
Assert.assertEquals(3, bracerParser.getPrecision());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEvaluateNoVar() throws Exception {
|
||||||
|
bracerParser.parse(INPUT_NOVAR);
|
||||||
|
Assert.assertEquals("-0.6570194619480038", bracerParser.evaluate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEvaluateVar() throws Exception {
|
||||||
|
bracerParser.parse(INPUT_VAR);
|
||||||
|
Assert.assertEquals("-0.6569578792490918", bracerParser.evaluate(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleBoolean() throws Exception {
|
||||||
|
bracerParser.parse("true or false");
|
||||||
|
Assert.assertEquals("1", bracerParser.evaluate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBoolean() throws Exception {
|
||||||
|
bracerParser.parse("( ( true and ( false or ( true and ( ( true ) or ( false ) ) ) ) ) and ( ( false ) ) )");
|
||||||
|
Assert.assertEquals("0", bracerParser.evaluate());
|
||||||
|
|
||||||
|
Collection<String> stackRPN = bracerParser.getStackRPN();
|
||||||
|
|
||||||
|
Assert.assertEquals("[&, 0, &, |, &, |, 0, 1, 1, 0, 1]", stackRPN.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBooleanNot1() throws Exception {
|
||||||
|
bracerParser.parse("not( ( true and ( false or ( true and ( not( true ) or ( false ) ) ) ) ) and ( ( false ) ) )");
|
||||||
|
Assert.assertEquals("1", bracerParser.evaluate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBooleanNot2() throws Exception {
|
||||||
|
bracerParser.parse("(((true | false) & not(false)) | (true | false))");
|
||||||
|
Assert.assertEquals("1", bracerParser.evaluate());
|
||||||
|
|
||||||
|
Collection<String> stackRPN = bracerParser.getStackRPN();
|
||||||
|
|
||||||
|
Assert.assertEquals("[|, |, 0, 1, &, not, 0, |, 0, 1]", stackRPN.toString());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue