diff --git a/README.md b/README.md index e8802b3..2007bd6 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,114 @@ # java.math.expression.parser -java.math.expression.parser is a maven project that let you parse math expressions. +java math expression parser is a maven project that lets you parse or evaluate math expressions. -This algorithm does not use a decision tree. It is a recursive algorithm. +This algorithm does not use a decision tree. It is a kind of Recursive Descent Parser (https://en.wikipedia.org/wiki/Recursive_descent_parser). In fact, it is LR parser (Left-Right Parser) without backtracking. -This algorithm is faster than JEP math expresion parser!!! If you compare java.math.expression.parse and JEP, this algorithm only need 25% of the time to parse the same expression as JEP. +This algorithm is faster than JEP math expresion parser!!! If you compare java.math.expression.parse and JEP, this algorithm only needs 25% of the time to parse the same expression as JEP. With other algorithms that use trees like: -Here you can see an example: + --------- + | + | + --------- + | + --------------- + | | + --------- --------- + | 1 | | * | + --------- --------- + + It is even faster than them. This library is 10 times faster and **it is tested using matlab**. The python version of this library is pymep. You can find pymep in my github repository. + +## Features +### math functions + +- sin, cos, sinh, cosh, tan, tanh, asin, acos, atan +- pi, e +- ln (natural logarithm), log (decimal logarithm) +- sqrt, cbrt +- radians or degrees +- complex or real numbers + +### parentheses + + - (...) + + ### variables: + + - Expressions in vars + + String f_xs = "x+5*y+(3 -y)"; + final Point xo = new Point("x", "1+1"); + final Point yo = new Point("y", "0+2*0+1*5-5 +1^4") + + +## Examples: + + In the test package you can see more examples with different constructors + +### Real numbers + + Parser.simpleEval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4"); --> for real functions + + String f_x = "+3 +5*5*(+1)"; + + ParserResult result = Parser.eval(f_x); --> for real or complex functions + assertTrue(result.getValue() == 28.0); + + final Point xo = new Point("x", new Double(2)); + f_x = "2.35*e^(-3)*x"; + + result = Parser.eval(f_x, xo); --> for real or complex functions with real or complex vars + assertTrue(result.getValue() == 0.2339992213289606); - String f_xs = " 2*(-(((z*3)*sqrt(x^(2)))+3))"; - final Point xo = new Point("x", new Double(2)); final Point zo = new Point("z", new Double(1)); + String f_xs = " 2*(-(((z*3)*sqrt(x^(2)))+3))"; + + Parser.eval(f_xs, xo, zo); --> multiple vars + + String f_xs = "x+5*y+(3 -y)"; + final Point xo = new Point("x", "1+1"); + final Point yo = new Point("y", "0+2*0+1*5-5 +1^4"); //math expression in vars - double result = Parser.Eval(f_xs, xo, zo); + ParserResult result = Parser.eval(f_xs, xo, yo); + + + +### Complex numbers + + String f_x = " e^(1*x*acos((3/2-2j)^(pi)))"; + + Point xo = new Point("x", new Complex(1, 2)); --> complex var: 1+ 2j + ParserResult result = Parser.eval(f_x, xo); + String f_x = "1+j +x"; + final Point xo = new Point("x", "2 +j"); //complex math expression in vars + + ParserResult result = Parser.eval(f_x, xo); + +### Execution time + + These are the results for the version 3.0 (master). You can check the speedTests in the project + + Parser.simpleEval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 + -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4"); + + CPU: i7-6500U + + test 1: one execution: 3ms + test 2: 100000 executions : 2100 ms --> mean time 0.021 ms per execution + (with graalvm-jdk-17.0.8+9.1 the total time is 754ms --> 0.00754 per execution) + test 3: one million executions: 16500 ms --> mean time 0.0165 ms per execution + (with graalvm-jdk-17.0.8+9.1 the total time is 7980ms --> 0,00798 per execution) -In the test package you can see more examples. This version is compiled for Java 1.6 - -Enjoy it!! +If you are interested in maths, you can visit my java numerical library in my github repository which uses java.math.expression.parser to evaluate functions. + +## Professional Services +If you are interested in logical parsers or any task related to parsers, you can consult my professional services page https://github.com/sbesada/professional.services + +## Donation +If you think that my work deserves a donation, you can do it: https://sbesada.github.io/ diff --git a/pom.xml b/pom.xml index 02607c3..7fd17c3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.expression.parser com.expression.parser jar - 1.0.0 + 3.3.0 com.expression.parser @@ -29,7 +29,7 @@ junit junit - 4.12 + 4.13.1 diff --git a/src/main/java/com/expression/parser/Parser.java b/src/main/java/com/expression/parser/Parser.java index 643cc87..6c22dd7 100644 --- a/src/main/java/com/expression/parser/Parser.java +++ b/src/main/java/com/expression/parser/Parser.java @@ -13,216 +13,262 @@ import com.expression.parser.util.Point; /** - * - * - * @author Sergio Besada - * + * The Class Parser. */ public class Parser { - /** - * - * Eval - * - * @param function - * @return - */ - public static ParserResult eval(final String function) { - - ParserResult result = new ParserResult(); - FunctionX f_x = null; - final ComplexFunction complexFunction = null; - - if ((function != null) && !function.equals("")) { - try { - - if ((function.toLowerCase().contains("j") || function.toLowerCase().contains("i")) - && !function.toLowerCase().contains("x")) { - // TODO:this if can be more accurate - result = eval(function, new Point("x", new Complex(1, 0))); - } else if (!function.toLowerCase().contains("x")) { - f_x = new FunctionX(function); - result.setValue(f_x.getF_xo(0)); - - } else { - throw new CalculatorException("function is not well defined"); - } - - } catch (final CalculatorException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - return result; - - } - - /** - * - * Eval - * - * @param function - * @param vars - * @param values - * @return - */ - public static double eval(final String function, final String[] vars, final Double[] values) { - - double result = 0; - FunctionX f_x = null; - FunctionXs f_xs = null; - if ((function != null) && !function.equals("")) { - try { - if ((((vars == null) || (vars.length < 1)) && (values == null)) || (values.length < 1)) { - f_x = new FunctionX(function); - result = f_x.getF_xo(0); - } else if ((values != null) && (values.length == 1)) { - f_x = new FunctionX(function); - result = f_x.getF_xo(values[0]); - } else if ((vars != null) && (vars.length > 1) && (values != null) && (values.length > 1)) { - f_xs = new FunctionXs(function); - final List valuesList = Arrays.asList(values); - final List varsList = Arrays.asList(vars); - result = f_xs.getValue(valuesList, varsList); - } - - } catch (final CalculatorException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - return result; - - } - - /** - * - * Eval - * - * @param function - * @param values - * @return - */ - public static ParserResult eval(final String function, final Point... values) { - - final ParserResult result = new ParserResult(); - FunctionX f_x = null; - FunctionXs f_xs = null; - ComplexFunction complexFunction = null; - - if ((function != null) && !function.equals("")) { - - if (function.toLowerCase().contains("i") || function.toLowerCase().contains("j") || pointIsComplex(values)) { // Complex - // TODO:this if can be more accurate - - complexFunction = new ComplexFunction(function); - final List valuesList = pointToComplexValue(values); - final List varsList = pointToVar(values); - try { - result.setComplexValue(complexFunction.getValue(valuesList, varsList)); - } catch (final CalculatorException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } else { - - try { - - if (values != null) { - if (values.length == 1) { - f_x = new FunctionX(function); - result.setValue(f_x.getF_xo(values[0].getValue())); - } else if (values.length > 1) { - f_xs = new FunctionXs(function); - final List valuesList = pointToValue(values); - final List varsList = pointToVar(values); - result.setValue(f_xs.getValue(valuesList, varsList)); - } - - } else { - f_x = new FunctionX(function); - result.setValue(f_x.getF_xo(0)); - } - } - - catch (final CalculatorException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - return result; - } - - /** - * - * PointToValue - * - * @param values - * @return - */ - private static List pointToValue(final Point... values) { - final List result = new ArrayList(); - for (int i = 0; i < values.length; i++) { - result.add(values[i].getValue()); - } - return result; - } - - /** - * - * PointToComplexValue - * - * @param values - * @return - */ - private static List pointToComplexValue(final Point... values) { - final List result = new ArrayList(); - for (int i = 0; i < values.length; i++) { - if (values[i].isComplex()) { - result.add(values[i].getComplexValue()); - } else { - result.add(new Complex(values[i].getValue(), 0)); - } - - } - return result; - } - - /** - * - * pointIsComplex - * - * @param values - * @return - */ - private static boolean pointIsComplex(final Point... values) { - - boolean result = false; - for (int i = 0; i < values.length; i++) { - if (values[i].isComplex()) { - result = true; - break; - } - } - return result; - } - - /** - * - * PointToVar - * - * @param values - * @return - */ - private static List pointToVar(final Point... values) { - final List result = new ArrayList(); - for (int i = 0; i < values.length; i++) { - result.add(values[i].getVar()); - } - return result; - } + /** + * Simple eval. + * + * function(fx) = 1 +2+ cos(0.5) + * + * @param function the function + * @return the double + */ + public static double simpleEval(final String function) { + + double result = 0; + FunctionX f_x = null; + + if ((function != null) && !function.isEmpty()) { + f_x = new FunctionX(function); + try { + result = f_x.getF_xo(0); + } catch (final CalculatorException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + return result; + + } + + /** + * Eval. + * + * fx = 1 +2+ cos(0.5) --> real functions or fx = 1+j +cos(0.5) --> complex functions + * + * @param function the function + * @return the parser result + */ + public static ParserResult eval(final String function) { + + ParserResult result = new ParserResult(); + FunctionX f_x = null; + + if ((function != null) && !function.isEmpty()) { + try { + + if ((function.toLowerCase().contains("j")) && !function.toLowerCase().contains("x")) { + + result = eval(function, new Point("x", new Complex(1, 0))); + } else if (!function.toLowerCase().contains("x")) { + f_x = new FunctionX(function); + result.setValue(f_x.getF_xo(0)); + + } else { + throw new CalculatorException("function is not well defined"); + } + + } catch (final CalculatorException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + return result; + + } + + /** + * Eval + * + * fx = 1 + 2*x +y ; x = 2, y = 1+j --> real functions or complex functions with real or complex vars + * + * + * @return the parser result: complex or real value + */ + public static ParserResult eval(final String function, final Point... values) { + + final ParserResult result = new ParserResult(); + FunctionX f_x = null; + FunctionXs f_xs = null; + ComplexFunction complexFunction = null; + + if ((function != null) && !function.isEmpty()) { + + if (Parser.pointIsComplex(values) || function.toLowerCase().contains("j")) { // Complex + + complexFunction = new ComplexFunction(function); + final List valuesList = pointToComplexValue(values); + final List varsList = pointToVar(values); + try { + result.setComplexValue(complexFunction.getValue(valuesList, varsList)); + } catch (final CalculatorException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } else { + + try { + + if (values != null) { + if (values.length == 1) { + + f_x = new FunctionX(function); + + if ((values[0].getStringValue() != null && !values[0].getStringValue().isEmpty())) { + final ParserResult evaluatedValue = Parser.eval(values[0].getStringValue()); + result.setValue(f_x.getF_xo(evaluatedValue.getValue())); + + } else { + result.setValue(f_x.getF_xo(values[0].getValue())); + } + + } else if (values.length > 1) { + f_xs = new FunctionXs(function); + final List valuesList = pointToValue(values); + final List varsList = pointToVar(values); + result.setValue(f_xs.getValue(valuesList, varsList)); + } + + } else { + f_x = new FunctionX(function); + result.setValue(f_x.getF_xo(0)); + } + } + + catch (final CalculatorException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return result; + } + + /** + * Eval. + * + * Simple Eval for real functions with real vars fx = 1 + 2*x+y; x = 2 and y= 5 + */ + public static double eval(final String function, final String[] vars, final Double[] values) { + + double result = 0; + FunctionX f_x = null; + FunctionXs f_xs = null; + if ((function != null) && !function.isEmpty()) { + try { + if ((((vars == null) || (vars.length < 1)) && (values == null)) || (values.length < 1)) { + f_x = new FunctionX(function); + result = f_x.getF_xo(0); + } else if ((values != null) && (values.length == 1)) { + f_x = new FunctionX(function); + result = f_x.getF_xo(values[0]); + } else if ((vars != null) && (vars.length > 1) && (values != null) && (values.length > 1)) { + f_xs = new FunctionXs(function); + final List valuesList = Arrays.asList(values); + final List varsList = Arrays.asList(vars); + result = f_xs.getValue(valuesList, varsList); + } + + } catch (final CalculatorException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + return result; + + } + + /** + * PointToValue. + * + * @param values the values + * @return the list + */ + private static List pointToValue(final Point... values) { + final List result = new ArrayList(); + for (int i = 0; i < values.length; i++) { + if ((values[i].getStringValue() != null && !values[i].getStringValue().isEmpty())) { + final ParserResult evaluatedValue = Parser.eval(values[i].getStringValue()); + result.add(evaluatedValue.getValue()); + } else { + result.add(values[i].getValue()); + } + } + return result; + } + + /** + * PointToComplexValue. + * + * @param values the values + * @return the list + */ + private static List pointToComplexValue(final Point... values) { + final List result = new ArrayList(); + for (int i = 0; i < values.length; i++) { + if (values[i].isComplex() && (values[i].getStringValue() == null || values[i].getStringValue().isEmpty())) { + result.add(values[i].getComplexValue()); + } else if ((values[i].getStringValue() != null && !values[i].getStringValue().isEmpty())) { + final ParserResult evaluatedValue = Parser.eval(values[i].getStringValue()); + if (evaluatedValue.isComplex()) { + result.add(evaluatedValue.getComplexValue()); + } else { + result.add(new Complex(evaluatedValue.getValue(), 0)); + } + } else { + result.add(new Complex(values[i].getValue(), 0)); + } + + } + return result; + } + + /** + * pointIsComplex. + * + * @param values the values + * @return true, if successful + */ + private static boolean pointIsComplex(final Point... values) { + + boolean result = false; + for (int i = 0; i < values.length; i++) { + if (values[i].isComplex() && (values[i].getStringValue() == null || values[i].getStringValue().isEmpty())) { + result = true; + break; + } else { + if (values[i].getStringValue() != null && !values[i].getStringValue().isEmpty()) { + final ParserResult evaluatedValue = Parser.eval(values[i].getStringValue()); + if (evaluatedValue.isComplex()) { + result = true; + break; + + } + + } + } + + } + return result; + } + + /** + * PointToVar. + * + * @param values the values + * @return the list + */ + private static List pointToVar(final Point... values) { + final List result = new ArrayList(); + for (int i = 0; i < values.length; i++) { + result.add(values[i].getVar()); + } + return result; + } } diff --git a/src/main/java/com/expression/parser/ParserManager.java b/src/main/java/com/expression/parser/ParserManager.java index cb3bf8b..f8cecec 100644 --- a/src/main/java/com/expression/parser/ParserManager.java +++ b/src/main/java/com/expression/parser/ParserManager.java @@ -1,54 +1,53 @@ package com.expression.parser; /** - * - * - * @author Sergio Besada - * + * The Class ParserManager. */ public class ParserManager { - private boolean deegre = false; - - // ..... Other configuration values // - - private static ParserManager instance = null; - - protected ParserManager() { - - } - - /** - * - * getInstance - * - * @return - */ - public static ParserManager getInstance() { - if (instance == null) { - instance = new ParserManager(); - } - return instance; - } - - /** - * - * isDeegre - * - * @return - */ - public boolean isDeegre() { - return this.deegre; - } - - /** - * - * setDeegre - * - * @param deegre - */ - public void setDeegre(final boolean deegre) { - this.deegre = deegre; - } + /** The deegre. */ + private boolean deegre = false; + + // ..... Other configuration values // + + /** The instance. */ + private static ParserManager instance = null; + + /** + * Instantiates a new parser manager. + */ + protected ParserManager() { + + } + + /** + * getInstance. + * + * @return single instance of ParserManager + */ + public static ParserManager getInstance() { + if (instance == null) { + instance = new ParserManager(); + } + return instance; + } + + /** + * isDeegre. + * + * @return true, if is deegre + */ + public boolean isDeegre() { + return deegre; + } + + /** + * setDeegre. + * + * @param deegre the new deegre + */ + public void setDeegre(final boolean deegre) { + this.deegre = deegre; + } } diff --git a/src/main/java/com/expression/parser/exception/CalculatorException.java b/src/main/java/com/expression/parser/exception/CalculatorException.java index 731f376..3b53ab0 100644 --- a/src/main/java/com/expression/parser/exception/CalculatorException.java +++ b/src/main/java/com/expression/parser/exception/CalculatorException.java @@ -1,26 +1,25 @@ package com.expression.parser.exception; /** - * - * - * @author Sergio Besada - * + * The Class CalculatorException. */ public class CalculatorException extends Exception { - /** - * CalculatorException - */ - public CalculatorException() { - super(); - } + private static final long serialVersionUID = 6235428117353457356L; - /** - * CalculatorException - * - * @param message - */ - public CalculatorException(final String message) { - super(message); - } + /** + * CalculatorException. + */ + public CalculatorException() { + super(); + } + + /** + * CalculatorException. + * + * @param message the message + */ + public CalculatorException(final String message) { + super(message); + } } diff --git a/src/main/java/com/expression/parser/function/Complex.java b/src/main/java/com/expression/parser/function/Complex.java index 7f2d54e..572f46a 100644 --- a/src/main/java/com/expression/parser/function/Complex.java +++ b/src/main/java/com/expression/parser/function/Complex.java @@ -3,555 +3,546 @@ import com.expression.parser.exception.CalculatorException; /** - * - * - * @author Sergio Besada - * + * The Class Complex. */ public class Complex { - /** - * real - */ - private double r; - - /** - * imaginary - */ - private double i; - - /** - * Complex - * - * @param r - * @param i - */ - public Complex(final double r, final double i) { - this.r = r; - this.i = i; - } - - /** - * Complex - */ - public Complex() { - this.r = 0.0; - this.i = 0.0; - } - - public double getR() { - return this.r; - } - - public void setR(final double r) { - this.r = r; - } - - public double getI() { - - return this.i; - } - - public void setI(final double i) { - this.i = i; - } - - /** - * - * add - * - * @param a - * @param b - * @return - */ - public static Complex add(final Complex a, final Complex b) { - final double real = a.r + b.r; - final double imag = a.i + b.i; - return new Complex(real, imag); - } - - /** - * - * add - * - * @param real - * @param c - * @return - */ - public static Complex add(final double real, final Complex c) { - return new Complex(c.r + real, c.i); - } - - /** - * - * sub - * - * @param a - * @param b - * @return - */ - public static Complex sub(final Complex a, final Complex b) { - final double real = a.r - b.r; - final double imag = a.i - b.i; - return new Complex(real, imag); - } - - public static Complex sub(final double real, final Complex c) { - return new Complex(c.r - real, c.i); - } - - /** - * - * multiply - * - * @param a - * @param b - * @return - */ - public static Complex mul(final Complex a, final Complex b) { - final double real = (a.r * b.r) - (a.i * b.i); - final double imag = (a.i * b.r) + (a.r * b.i); - return new Complex(real, imag); - } - - /** - * - * conjugate - * - * @param c - * @return - */ - public static Complex conjugate(final Complex c) { - return new Complex(c.r, -c.i); - } - - /** - * - * div - * - * @param a - * @param b - * @return - * @throws CalculatorException - */ - public static Complex div(final Complex a, final Complex b) throws CalculatorException { - - if ((b.r == 0) && (b.i == 0)) { - throw new CalculatorException("The complex number b is 0"); - } - - final double c = Math.pow(b.r, 2); - final double d = Math.pow(b.i, 2); - - double real; - double imag; - real = (a.r * b.r) + (a.i * b.i); - real /= (c + d); - imag = (a.i * b.r) - (a.r * b.i); - imag /= (c + d); - - return new Complex(real, imag); - } - - /** - * - * abs - * - * @param z - * @return - */ - public static double abs(final Complex z) { - double x, y, ans, temp; - x = Math.abs(z.r); - y = Math.abs(z.i); - if (x == 0.0) { - ans = y; - } else if (y == 0.0) { - ans = x; - } else if (x > y) { - temp = y / x; - ans = x * Math.sqrt(1.0 + (temp * temp)); - } else { - temp = x / y; - ans = y * Math.sqrt(1.0 + (temp * temp)); - } - return ans; - } - - /** - * - * sqrt - * - * @param c - * @return - */ - public static Complex sqrt(final Complex c) { - double real, imag; - double x, y, w, r; - - Complex result = null; - - if ((c.r == 0.0) && (c.i == 0.0)) { - result = new Complex(); - } else { - x = Math.abs(c.r); - y = Math.abs(c.i); - if (x >= y) { - r = y / x; - w = Math.sqrt(x) * Math.sqrt(0.5 * (1.0 + Math.sqrt(1.0 + (r * r)))); - } else { - r = x / y; - w = Math.sqrt(y) * Math.sqrt(0.5 * (r + Math.sqrt(1.0 + (r * r)))); - } - if (c.r >= 0.0) { - real = w; - imag = c.i / (2.0 * w); - } else { - imag = (c.i >= 0) ? w : -w; - real = c.i / (2.0 * imag); - } - result = new Complex(real, imag); - } - - return result; - } - - /** - * - * Complex - * - * @param x - * @param c - * @return - */ - public static Complex mul(final double x, final Complex c) { - final Complex result = new Complex(); - result.r = c.r * x; - result.i = c.i * x; - return result; - } - - /** - * - * div - * - * @param x - * @param c - * @return - * @throws CalculatorException - */ - public static Complex div(final double x, final Complex c) throws CalculatorException { - if (x == 0) { - throw new CalculatorException("scalar is 0"); - } - final Complex result = new Complex(); - result.r = c.r / x; - result.i = c.i / x; - return result; - } - - /** - * - * inverse - * - * @return - */ - public Complex inverse() { - final Complex result = new Complex(); - final double a = this.r * this.r; - final double b = this.i * this.i; - if ((a == 0) && (b == 0)) { - result.r = 0; - result.i = 0; - } else { - result.r = this.r / (a + b); - result.i = this.i / (a + b); - } - return result; - - } - - /** - * - * pow - * - * @param c - * @param exp - * @return - * @throws CalculatorException - */ - /* - * public static Complex pow(final Complex c, final int exp) throws CalculatorException { double x = 0.0, y = 0.0; - * int sign; for (int i = 0; i <= exp; i++) { sign = ((i % 2) == 0) ? 1 : -1; // real x += Combination.calc(exp, 2 * - * i) * Math.pow(c.r, exp - (2 * i)) * Math.pow(c.i, 2 * i) * sign; if (exp == (2 * i)) { break; } // imaginary y += - * Combination.calc(exp, (2 * i) + 1) * Math.pow(c.r, exp - ((2 * i) + 1)) * Math.pow(c.i, (2 * i) + 1) sign; } - * return new Complex(x, y); } - */ - /** - * - * pow - * - * @param c - * @param exp - * @return - */ - public static Complex pow(final Complex c, final Double exp) { - return c.pow(exp); - } - - /** - * - * power - * - * @param c - * @param exp - * @return - */ - public static Complex pow(final Complex c, final Complex exp) { - return c.pow(exp); - } - - /** - * - * module - * - * @return - */ - public double module() { - return Math.sqrt((this.r * this.r) + (this.i * this.i)); - } - - /** - * - * arg - * - * @return - */ - public double arg() { - - double angle = Math.atan2(this.i, this.r); - if (angle < 0) { - angle = (2 * Math.PI) + angle; - } - return (angle * 180) / Math.PI; - - } - - /** - * - * negate - * - * @return - */ - public Complex negate() { - return new Complex(-this.r, -this.i); - } - - /** - * - * exp - * - * @return - */ - // E^c - public Complex exp() { - final double exp_x = Math.exp(this.r); - return new Complex(exp_x * Math.cos(this.i), exp_x * Math.sin(this.i)); - } - - /** - * - * log10() - * - * @return - */ - public Complex log10() { - - final double rpart = Math.sqrt((this.r * this.r) + (this.i * this.i)); - double ipart = Math.atan2(this.i, - this.r); - if (ipart > Math.PI) { - ipart = ipart - (2.0 * Math.PI); - } - return new Complex(Math.log10(rpart), (1 / - Math.log(10)) * ipart); - - } - - /** - * - * log natural log - * - * @return - */ - public Complex log() { - return new Complex(Math.log(abs(this)), Math.atan2(this.i, this.r)); - - } - - /** - * - * sqrt - * - * @return - */ - public Complex sqrt() { - final double r = Math.sqrt((this.r * this.r) + (this.i * this.i)); - final double rpart = Math.sqrt(0.5 * (r + this.r)); - double ipart = Math.sqrt(0.5 * (r - this.r)); - if (this.i < 0.0) { - ipart = -ipart; - } - return new Complex(rpart, ipart); - } - - public static Complex cbrt(final Complex a) { - Complex z = new Complex(); - if (a.i != 0.0) { - z.r = Math.cbrt(abs(a)) * Math.cos(a.arg() / 3.0); - z.i = Math.cbrt(abs(a)) * Math.sin(a.arg() / 3.0); - } else { - z = new Complex(Math.cbrt(a.r), 0); - } - return z; - } - - /** - * - * pow - * - * @param z - * @return - */ - public Complex pow(final Complex exp) { - Complex a = this.log(); - a = mul(exp, a); - return a.exp(); - } - - /** - * - * pow - * - * @param d - * @return - */ - public Complex pow(final double exp) { - Complex a = this.log(); - a = mul(exp, a); - return a.exp(); - } - - /** - * - * sin - * - * @return - */ - public Complex sin() { - return new Complex(Math.sin(this.r) * Math.cosh(this.i), Math.cos(this.r) * Math.sinh(this.i)); - } - - /** - * - * cos - * - * @return - */ - public Complex cos() { - return new Complex(Math.cos(this.r) * Math.cosh(this.i), -StrictMath.sin(this.r) * Math.sinh(this.i)); - } - - /** - * - * tan - * - * @return - * @throws CalculatorException - */ - public Complex tan() throws CalculatorException { - return div(this.sin(), this.cos()); - } - - /** - * - * asin - * - * @return - */ - public Complex asin() { - final Complex IM = new Complex(0.0, -1.0); - final Complex ZP = mul(this, IM); - final Complex ZM = add((sub(new Complex(1.0, 0.0), mul(this, this))).sqrt(), ZP); - return mul(ZM.log(), new Complex(0.0, 1.0)); - } - - /** - * - * acos - * - * @return - */ - public Complex acos() { - final Complex IM = new Complex(0.0, -1.0); - final Complex ZM = add(mul((sub(new Complex(1.0, 0.0), mul(this, this))).sqrt(), IM), this); - return mul(ZM.log(), new Complex(0.0, 1.0)); - } - - /** - * - * atan - * - * @return - * @throws CalculatorException - */ - public Complex atan() throws CalculatorException { - final Complex IM = new Complex(0.0, -1.0); - final Complex ZP = new Complex(this.r, this.i - 1.0); - final Complex ZM = new Complex(-this.r, -this.i - 1.0); - return div(2.0, mul(IM, (div(ZP, ZM).log()))); - } - - /** - * - * sinh - * - * @return - */ - public Complex sinh() { - return new Complex(Math.sinh(this.r) * Math.cos(this.i), Math.cosh(this.r) * Math.sin(this.i)); - } - - /** - * - * cosh - * - * @return - */ - public Complex cosh() { - return new Complex(Math.cosh(this.r) * Math.cos(this.i), Math.sinh(this.r) * Math.sin(this.i)); - } - - /** - * - * tanh - * - * @return - * @throws CalculatorException - */ - public Complex tanh() throws CalculatorException { - return div(this.sinh(), this.cosh()); - } - - /** - * - * atanh - * - * @return - * @throws CalculatorException - */ - public Complex atanh() throws CalculatorException { - return sub((add(1.0, this)).log(), div(2.0, ((sub(1.0, this)).negate()).log())); - } + /** real. */ + private double r; + + /** imaginary. */ + private double i; + + /** + * Complex. + * + * @param r the r + * @param i the i + */ + public Complex(final double r, final double i) { + this.r = r; + this.i = i; + } + + /** + * Complex. + */ + public Complex() { + r = 0.0; + i = 0.0; + } + + /** + * Gets the r. + * + * @return the r + */ + public double getR() { + return r; + } + + /** + * Sets the r. + * + * @param r the new r + */ + public void setR(final double r) { + this.r = r; + } + + /** + * Gets the i. + * + * @return the i + */ + public double getI() { + + return i; + } + + /** + * Sets the i. + * + * @param i the new i + */ + public void setI(final double i) { + this.i = i; + } + + /** + * add. + * + * @param a the a + * @param b the b + * @return the complex + */ + public static Complex add(final Complex a, final Complex b) { + final double real = a.r + b.r; + final double imag = a.i + b.i; + return new Complex(real, imag); + } + + /** + * add. + * + * @param real the real + * @param c the c + * @return the complex + */ + public static Complex add(final double real, final Complex c) { + return new Complex(c.r + real, c.i); + } + + /** + * sub. + * + * @param a the a + * @param b the b + * @return the complex + */ + public static Complex sub(final Complex a, final Complex b) { + final double real = a.r - b.r; + final double imag = a.i - b.i; + return new Complex(real, imag); + } + + /** + * Sub. + * + * @param real the real + * @param c the c + * @return the complex + */ + public static Complex sub(final double real, final Complex c) { + return new Complex(c.r - real, c.i); + } + + /** + * multiply. + * + * @param a the a + * @param b the b + * @return the complex + */ + public static Complex mul(final Complex a, final Complex b) { + final double real = (a.r * b.r) - (a.i * b.i); + final double imag = (a.i * b.r) + (a.r * b.i); + return new Complex(real, imag); + } + + /** + * conjugate. + * + * @param c the c + * @return the complex + */ + public static Complex conjugate(final Complex c) { + return new Complex(c.r, -c.i); + } + + /** + * div. + * + * @param a the a + * @param b the b + * @return the complex + * @throws CalculatorException the calculator exception + */ + public static Complex div(final Complex a, final Complex b) throws CalculatorException { + + if ((b.r == 0) && (b.i == 0)) { + throw new CalculatorException("The complex number b is 0"); + } + + final double c = Math.pow(b.r, 2); + final double d = Math.pow(b.i, 2); + + double real; + double imag; + real = (a.r * b.r) + (a.i * b.i); + real /= (c + d); + imag = (a.i * b.r) - (a.r * b.i); + imag /= (c + d); + + return new Complex(real, imag); + } + + /** + * abs. + * + * @param z the z + * @return the double + */ + public static double abs(final Complex z) { + double x, y, ans, temp; + x = Math.abs(z.r); + y = Math.abs(z.i); + if (x == 0.0) { + ans = y; + } else if (y == 0.0) { + ans = x; + } else if (x > y) { + temp = y / x; + ans = x * Math.sqrt(1.0 + (temp * temp)); + } else { + temp = x / y; + ans = y * Math.sqrt(1.0 + (temp * temp)); + } + return ans; + } + + /** + * sqrt. + * + * @param c the c + * @return the complex + */ + public static Complex sqrt(final Complex c) { + double real, imag; + double x, y, w, r; + + Complex result = null; + + if ((c.r == 0.0) && (c.i == 0.0)) { + result = new Complex(); + } else { + x = Math.abs(c.r); + y = Math.abs(c.i); + if (x >= y) { + r = y / x; + w = Math.sqrt(x) * Math.sqrt(0.5 * (1.0 + Math.sqrt(1.0 + (r * r)))); + } else { + r = x / y; + w = Math.sqrt(y) * Math.sqrt(0.5 * (r + Math.sqrt(1.0 + (r * r)))); + } + if (c.r >= 0.0) { + real = w; + imag = c.i / (2.0 * w); + } else { + imag = (c.i >= 0) ? w : -w; + real = c.i / (2.0 * imag); + } + result = new Complex(real, imag); + } + + return result; + } + + /** + * Complex. + * + * @param x the x + * @param c the c + * @return the complex + */ + public static Complex mul(final double x, final Complex c) { + final Complex result = new Complex(); + result.r = c.r * x; + result.i = c.i * x; + return result; + } + + /** + * div. + * + * @param x the x + * @param c the c + * @return the complex + * @throws CalculatorException the calculator exception + */ + public static Complex div(final double x, final Complex c) throws CalculatorException { + if (x == 0) { + throw new CalculatorException("scalar is 0"); + } + final Complex result = new Complex(); + result.r = c.r / x; + result.i = c.i / x; + return result; + } + + /** + * inverse. + * + * @return the complex + */ + public Complex inverse() { + final Complex result = new Complex(); + final double a = r * r; + final double b = i * i; + if ((a == 0) && (b == 0)) { + result.r = 0; + result.i = 0; + } else { + result.r = r / (a + b); + result.i = i / (a + b); + } + return result; + + } + + /** + * pow. + * + * @param c the c + * @param exp the exp + * @return the complex + */ + /* + * public static Complex pow(final Complex c, final int exp) throws CalculatorException { double x = 0.0, y = 0.0; + * int sign; for (int i = 0; i <= exp; i++) { sign = ((i % 2) == 0) ? 1 : -1; // real x += Combination.calc(exp, 2 * + * i) * Math.pow(c.r, exp - (2 * i)) * Math.pow(c.i, 2 * i) * sign; if (exp == (2 * i)) { break; } // imaginary y += + * Combination.calc(exp, (2 * i) + 1) * Math.pow(c.r, exp - ((2 * i) + 1)) * Math.pow(c.i, (2 * i) + 1) sign; } + * return new Complex(x, y); } + */ + /** + * + * pow + * + * @param c + * @param exp + * @return + */ + public static Complex pow(final Complex c, final Double exp) { + return c.pow(exp); + } + + /** + * power. + * + * @param c the c + * @param exp the exp + * @return the complex + */ + public static Complex pow(final Complex c, final Complex exp) { + return c.pow(exp); + } + + /** + * module. + * + * @return the double + */ + public double module() { + return Math.sqrt((r * r) + (i * i)); + } + + /** + * arg. + * + * @return the double + */ + public double arg() { + + double angle = Math.atan2(i, r); + if (angle < 0) { + angle = (2 * Math.PI) + angle; + } + return (angle * 180) / Math.PI; + + } + + /** + * negate. + * + * @return the complex + */ + public Complex negate() { + return new Complex(-r, -i); + } + + /** + * exp. + * + * @return the complex + */ + // E^c + public Complex exp() { + final double exp_x = Math.exp(r); + return new Complex(exp_x * Math.cos(i), exp_x * Math.sin(i)); + } + + /** + * log10(). + * + * @return the complex + */ + public Complex log10() { + + final double rpart = Math.sqrt((r * r) + (i * i)); + double ipart = Math.atan2(i, r); + if (ipart > Math.PI) { + ipart = ipart - (2.0 * Math.PI); + } + return new Complex(Math.log10(rpart), (1 / Math.log(10)) * ipart); + + } + + /** + * log natural log. + * + * @return the complex + */ + public Complex log() { + return new Complex(Math.log(abs(this)), Math.atan2(i, r)); + + } + + /** + * sqrt. + * + * @return the complex + */ + public Complex sqrt() { + final double r = Math.sqrt((this.r * this.r) + (i * i)); + final double rpart = Math.sqrt(0.5 * (r + this.r)); + double ipart = Math.sqrt(0.5 * (r - this.r)); + if (i < 0.0) { + ipart = -ipart; + } + return new Complex(rpart, ipart); + } + + /** + * Cbrt. + * + * @param a the a + * @return the complex + */ + public static Complex cbrt(final Complex a) { + Complex z = new Complex(); + if (a.i != 0.0) { + z.r = Math.cbrt(abs(a)) * Math.cos(a.arg() / 3.0); + z.i = Math.cbrt(abs(a)) * Math.sin(a.arg() / 3.0); + } else { + z = new Complex(Math.cbrt(a.r), 0); + } + return z; + } + + /** + * pow. + * + * @param exp the exp + * @return the complex + */ + public Complex pow(final Complex exp) { + Complex a = this.log(); + a = mul(exp, a); + return a.exp(); + } + + /** + * pow. + * + * @param exp the exp + * @return the complex + */ + public Complex pow(final double exp) { + Complex a = this.log(); + a = mul(exp, a); + return a.exp(); + } + + /** + * sin. + * + * @return the complex + */ + public Complex sin() { + return new Complex(Math.sin(r) * Math.cosh(i), Math.cos(r) * Math.sinh(i)); + } + + /** + * cos. + * + * @return the complex + */ + public Complex cos() { + return new Complex(Math.cos(r) * Math.cosh(i), -StrictMath.sin(r) * Math.sinh(i)); + } + + /** + * tan. + * + * @return the complex + * @throws CalculatorException the calculator exception + */ + public Complex tan() throws CalculatorException { + return div(this.sin(), this.cos()); + } + + /** + * asin. + * + * @return the complex + */ + public Complex asin() { + final Complex IM = new Complex(0.0, -1.0); + final Complex ZP = mul(this, IM); + final Complex ZM = add((sub(new Complex(1.0, 0.0), mul(this, this))).sqrt(), ZP); + return mul(ZM.log(), new Complex(0.0, 1.0)); + } + + /** + * acos. + * + * @return the complex + */ + public Complex acos() { + final Complex IM = new Complex(0.0, -1.0); + final Complex ZM = add(mul((sub(new Complex(1.0, 0.0), mul(this, this))).sqrt(), IM), this); + return mul(ZM.log(), new Complex(0.0, 1.0)); + } + + /** + * atan. + * + * @return the complex + * @throws CalculatorException the calculator exception + */ + public Complex atan() throws CalculatorException { + final Complex IM = new Complex(0.0, -1.0); + final Complex ZP = new Complex(r, i - 1.0); + final Complex ZM = new Complex(-r, -i - 1.0); + return div(2.0, mul(IM, (div(ZP, ZM).log()))); + } + + /** + * sinh. + * + * @return the complex + */ + public Complex sinh() { + return new Complex(Math.sinh(r) * Math.cos(i), Math.cosh(r) * Math.sin(i)); + } + + /** + * cosh. + * + * @return the complex + */ + public Complex cosh() { + return new Complex(Math.cosh(r) * Math.cos(i), Math.sinh(r) * Math.sin(i)); + } + + /** + * tanh. + * + * @return the complex + * @throws CalculatorException the calculator exception + */ + public Complex tanh() throws CalculatorException { + return div(this.sinh(), this.cosh()); + } + + /** + * atanh. + * + * @return the complex + * @throws CalculatorException the calculator exception + */ + public Complex atanh() throws CalculatorException { + return sub((add(1.0, this)).log(), div(2.0, ((sub(1.0, this)).negate()).log())); + } } diff --git a/src/main/java/com/expression/parser/function/ComplexFunction.java b/src/main/java/com/expression/parser/function/ComplexFunction.java index cc13ab8..739b0cb 100644 --- a/src/main/java/com/expression/parser/function/ComplexFunction.java +++ b/src/main/java/com/expression/parser/function/ComplexFunction.java @@ -7,929 +7,549 @@ import com.expression.parser.exception.CalculatorException; /** - * - * - * @author Sergio Besada - * + * The Class ComplexFunction. */ public class ComplexFunction { - public static final String SIN = "sin"; - public static final String COS = "cos"; - public static final String SINH = "sinh"; - public static final String COSH = "cosh"; - public static final String TAN = "tan"; - public static final String TANH = "tanh"; - public static final String ASIN = "asin"; - public static final String ACOS = "acos"; - public static final String ATAN = "atan"; - public static final String E = "e"; - public static final String PI = "pi"; - public static final String LN = "ln"; - public static final String LOG = "log"; - public static final String SQRT = "sqrt"; - public static final String CBRT = "cbrt"; - - /** - * setup - */ - public boolean degree = false; - - /** - * f(x,y,z,...) - */ - private String f; - - /** - * FunctionXs - * - * @param f - */ - public ComplexFunction(final String f) { - this.f = f.trim().replaceAll(" ", ""); - this.degree = ParserManager.getInstance().isDeegre(); - - } - - /** - * getter f(x,y,z,...) - * - * - * @return - */ - public String getF() { - return this.f; - } - - /** - * - * setter f(x,y,z,...) - * - * @param f - */ - public void setF(final String f) { - this.f = f; - } - - /** - * - * getValue f(x0,y0,z0...) - * - * @param values - * (sort the values taking into account the variables) - * @param variables - * x,y,z etc - * @return - * @throws CalculatorException - */ - public Complex getValue(final List values, final List variables) throws CalculatorException { - final List vars = new ArrayList(); - for (final String string : variables) { - vars.add(string.toLowerCase()); - } - - return eval(this.f, values, vars); - } - - /** - * - * eval - * - * @param f - * @param values - * @param variables - * @return - * @throws CalculatorException - */ - private Complex eval(String f, final List values, final List variables) throws CalculatorException { - f = f.trim().toLowerCase(); - Complex value = new Complex(0, 0); - String number = ""; - String function = ""; - - boolean hasNumber = false; - boolean hasFunction = false; - boolean isImaginary = false; - - for (int i = 0; i < f.length(); i++) { - final char character = f.charAt(i); - switch (character) { - case '*': - if (hasNumber && !isImaginary) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.mul(new Complex(numb, 0), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - number = ""; - - } else if (hasNumber && isImaginary) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.mul(new Complex(0, numb), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - isImaginary = false; - number = ""; - } else if (hasFunction) { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.mul(eval(function, values, variables), eval(new_f, values, variables)); - i = i + new_f.length(); - hasFunction = false; - function = ""; - } else { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.mul(value, eval(new_f, values, variables)); - i = i + new_f.length(); - } - break; - case '+': - - if (hasNumber && !isImaginary) { - final Double numb = new Double(number); - final String new_f = f.substring(i + 1, f.length()); - value = Complex.add(new Complex(numb, 0), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasNumber && isImaginary) { - final Double numb = new Double(number); - final String new_f = f.substring(i + 1, f.length()); - value = Complex.add(new Complex(0, numb), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - isImaginary = false; - number = ""; - } else if (hasFunction) { - final String new_f = f.substring(i + 1, f.length()); - value = Complex.add(eval(function, values, variables), eval(new_f, values, variables)); - i = i + new_f.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f = f.substring(i + 1, f.length()); - value = Complex.add(value, eval(new_f, values, variables)); - i = i + new_f.length(); - } - break; - - case '-': - - if (hasNumber && !isImaginary) { - final Double numb = new Double(number); - final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); - value = Complex.sub(new Complex(numb, 0), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasNumber && isImaginary) { - final Double numb = new Double(number); - final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); - value = Complex.sub(new Complex(0, numb), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - isImaginary = false; - number = ""; - - } else if (hasFunction) { - final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); - value = Complex.sub(eval(function, values, variables), eval(new_f, values, variables)); - i = i + new_f.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); - value = Complex.sub(value, eval(new_f, values, variables)); - i = i + new_f.length(); - } - break; - case '/': - - if (hasNumber && !isImaginary) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.div(new Complex(numb, 0), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasNumber && isImaginary) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.div(new Complex(0, numb), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - isImaginary = false; - number = ""; - - } else if (hasFunction) { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.div(eval(function, values, variables), eval(new_f, values, variables)); - i = i + new_f.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.div(value, eval(new_f, values, variables)); - i = i + new_f.length(); - } - break; - case '^': - - if (hasNumber && !isImaginary) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.pow(eval(new_f, values, variables), numb); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasNumber && isImaginary) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.pow(eval(new_f, values, variables), new Complex(0, numb)); - i = i + new_f.length(); - hasNumber = false; - isImaginary = false; - number = ""; - - } else if (hasFunction) { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.pow(eval(function, values, variables), eval(new_f, values, variables)); - i = i + new_f.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Complex.pow(value, eval(new_f, values, variables)); - i = i + new_f.length(); - } - - break; - case '0': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - - break; - case '1': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - break; - case '2': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - break; - case '3': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - - break; - case '4': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - break; - case '5': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - break; - case '6': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - break; - case '7': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - - break; - case '8': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - break; - case '9': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Complex(new Double(number), 0); - number = ""; - hasNumber = false; - } - - break; - case '.': - if (i == (f.length() - 1)) { - throw new CalculatorException("The function is not well-formed"); - } - if (hasNumber && (number.length() > 0)) { - number = number + character; - } - break; - case '(': - if (i == (f.length() - 1)) { - throw new CalculatorException("The function is not well-formed"); - } - - final String new_f = f.substring(i + 1, nextBracket(f)); - if (hasFunction) { - if (function.equals(SIN)) { - value = eval(new_f, values, variables).sin(); - - } else if (function.equals(COS)) { - value = eval(new_f, values, variables).cos(); - - } else if (function.equals(TAN)) { - value = eval(new_f, values, variables).tan(); - - } else if (function.equals(SINH)) { - value = eval(new_f, values, variables).sinh(); - - } else if (function.equals(COSH)) { - value = eval(new_f, values, variables).cosh(); - - } else if (function.equals(TANH)) { - value = eval(new_f, values, variables).tanh(); - - } else if (function.equals(ASIN)) { - value = eval(new_f, values, variables).asin(); - - } else if (function.equals(ACOS)) { - value = eval(new_f, values, variables).acos(); - - } else if (function.equals(ATAN)) { - value = eval(new_f, values, variables).atan(); - } else if (function.equals(LN)) { - value = eval(new_f, values, variables).log(); - } else if (function.equals(LOG)) { - value = eval(new_f, values, variables).log10(); - } else if (function.equals(SQRT)) { - value = eval(new_f, values, variables).sqrt(); - } else if (function.equals(CBRT)) { - value = Complex.cbrt(eval(new_f, values, variables)); - } else { - throw new CalculatorException("The function is not well-formed"); - } - - hasFunction = false; - function = ""; - - } else { - value = eval(new_f, values, variables); - } - i = i + new_f.length() + 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - break; - - case 'i': - if (!hasFunction) { - if (hasNumber) { - - value = new Complex(0, new Double(number)); - number = ""; - isImaginary = true; - } else { - value = new Complex(0, 1); - isImaginary = true; - } - } else { - - function = function + character; - hasFunction = true; - - if (i == (f.length() - 1)) { - - if (function.equals(E)) { - value = new Complex(Math.E, 0); - - } else if (function.equals(PI)) { - value = new Complex(Math.PI, 0); - } else { - if (function.length() == 1) { - final int n = variables.indexOf(function); - if (n >= 0) { - value = values.get(n); - } else { - throw new CalculatorException("function is not well defined"); - } - - } else { - throw new CalculatorException("function is not well defined"); - } - } - - } - - break; - } - break; - - case 'j': - if (!hasFunction) { - if (hasNumber) { - value = new Complex(0, new Double(number)); - isImaginary = true; - } else { - value = new Complex(0, 1); - isImaginary = true; - } - } else { - function = function + character; - hasFunction = true; - - if (i == (f.length() - 1)) { - - if (function.equals(E)) { - value = new Complex(Math.E, 0); - - } else if (function.equals(PI)) { - value = new Complex(Math.PI, 0); - } else { - if (function.length() == 1) { - final int n = variables.indexOf(function); - if (n >= 0) { - value = values.get(n); - } else { - throw new CalculatorException("function is not well defined"); - } - - } else { - throw new CalculatorException("function is not well defined"); - } - } - - } - - break; - } - break; - default: - if (isValidCharacter(character)) { - function = function + character; - hasFunction = true; - - if (i == (f.length() - 1)) { - - if (function.equals(E)) { - value = new Complex(Math.E, 0); - - } else if (function.equals(PI)) { - value = new Complex(Math.PI, 0); - } else { - if (function.length() == 1) { - final int n = variables.indexOf(function); - if (n >= 0) { - value = values.get(n); - } else { - throw new CalculatorException("function is not well defined"); - } - - } else { - throw new CalculatorException("function is not well defined"); - } - } - - } - - } else { - throw new CalculatorException("Invalid character"); - } - - break; - } - - } - return value; - } - - /** - * - * nextFunction - * - * @param f - * @return - * @throws CalculatorException - */ - private String nextFunction(String f) throws CalculatorException { - String result = ""; - f = f.trim().toLowerCase(); - - for (int i = 0; i < f.length(); i++) { - final char character = f.charAt(i); - - switch (character) { - case '*': - i = f.length(); - break; - case '/': - i = f.length(); - break; - case '+': - i = f.length(); - break; - case '-': - i = f.length(); - break; - case '^': - result = result + character; - break; - case '.': - result = result + character; - break; - case '(': - - final String new_f = f.substring(i, nextBracket(f) + 1); - result = result + new_f; - i = (i + new_f.length()) - 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; - } - } - return result; - } - - /** - * - * nextMinusFunction - * - * @param f - * @return - * @throws CalculatorException - */ - private String nextMinusFunction(String f) throws CalculatorException { - String result = ""; - f = f.trim().toLowerCase(); - - for (int i = 0; i < f.length(); i++) { - final char character = f.charAt(i); - - switch (character) { - case '*': - result = result + character; - break; - case '/': - result = result + character; - break; - case '+': - i = f.length(); - break; - case '-': - i = f.length(); - break; - case '^': - result = result + character; - break; - case '.': - result = result + character; - break; - case '(': - - final String new_f = f.substring(i, nextBracket(f) + 1); - result = result + new_f; - i = (i + new_f.length()) - 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; - } - } - return result; - } - - /** - * - * isValidCharacter - * - * @param character - * @return - */ - private boolean isValidCharacter(final char character) { - boolean result = false; - switch (character) { - case 'a': - result = true; - break; - case 'b': - result = true; - break; - case 'c': - result = true; - break; - case 'd': - result = true; - break; - case 'e': - result = true; - break; - case 'f': - result = true; - break; - case 'g': - result = true; - break; - case 'h': - result = true; - break; - // case 'i': - // result = true; - // break; - // case 'j': - // result = true; - // break; - case 'k': - result = true; - break; - - case 'l': - result = true; - break; - case 'm': - result = true; - break; - case 'n': - result = true; - break; - case 'o': - result = true; - break; - case 'p': - result = true; - break; - case 'q': - result = true; - break; - case 'r': - result = true; - break; - case 's': - result = true; - break; - case 't': - result = true; - break; - case 'u': - result = true; - break; - case 'v': - result = true; - break; - case 'w': - result = true; - break; - case 'x': - result = true; - break; - case 'y': - result = true; - break; - case 'z': - result = true; - break; - default: - result = false; - break; - } - - return result; - } - - /** - * isValidNumericAndCharacter - * - * - * @param character - * @return - */ - private boolean isValidNumericAndCharacter(final char character) { - boolean result = false; - switch (character) { - case 'a': - result = true; - break; - case 'b': - result = true; - break; - case 'c': - result = true; - break; - case 'd': - result = true; - break; - case 'e': - result = true; - break; - case 'f': - result = true; - break; - case 'g': - result = true; - break; - case 'h': - result = true; - break; - case 'i': - result = true; - break; - case 'j': - result = true; - break; - case 'k': - result = true; - break; - - case 'l': - result = true; - break; - case 'm': - result = true; - break; - case 'n': - result = true; - break; - case 'o': - result = true; - break; - case 'p': - result = true; - break; - case 'q': - result = true; - break; - case 'r': - result = true; - break; - case 's': - result = true; - break; - case 't': - result = true; - break; - case 'u': - result = true; - break; - case 'v': - result = true; - break; - case 'w': - result = true; - break; - case 'x': - result = true; - break; - case 'y': - result = true; - break; - case 'z': - result = true; - break; - case '0': - result = true; - break; - case '1': - result = true; - break; - case '2': - result = true; - break; - case '3': - result = true; - break; - case '4': - result = true; - break; - case '5': - result = true; - break; - case '6': - result = true; - break; - case '7': - result = true; - break; - case '8': - result = true; - break; - case '9': - result = true; - break; - default: - result = false; - break; - } - - return result; - } - - /** - * - * nextBracket - * - * @param f - * @return - * @throws CalculatorException - */ - private int nextBracket(final String f) throws CalculatorException { - int result = 0; - int count = 0; - for (int i = 0; i < f.length(); i++) { - final char character = f.charAt(i); - switch (character) { - case '(': - result = i; - count++; - break; - case ')': - result = i; - count--; - if (count == 0) { - return i; - } - break; - default: - result = i; - break; - } - } - - if (count != 0) { - throw new CalculatorException("( is not finished"); - } - return result; - } + /** setup. */ + public boolean degree = false; + + /** + * f(x,y,z,...) + */ + private String f; + + /** + * FunctionXs. + * + * @param f the f + */ + public ComplexFunction(final String f) { + this.f = f.trim().replaceAll(" ", "").toLowerCase(); + degree = ParserManager.getInstance().isDeegre(); + + } + + /** + * getter f(x,y,z,...) + * + * @return the f + */ + public String getF() { + return f; + } + + /** + * setter f(x,y,z,...) + * + * @param f the new f + */ + public void setF(final String f) { + this.f = f; + } + + /** + * getValue f(x0,y0,z0...) + * + * @param values (sort the values taking into account the variables) + * @param variables x,y,z etc + * @return the value + * @throws CalculatorException the calculator exception + */ + public Complex getValue(final List values, final List variables) throws CalculatorException { + final List vars = new ArrayList(); + for (final String string : variables) { + vars.add(string.trim().replaceAll(" ", "").toLowerCase()); + } + return eval(f, values, vars); + } + + /** + * eval. + * + * @param f the f + * @param values the values + * @param variables the variables + * @return the complex + * @throws CalculatorException the calculator exception + */ + private Complex eval(final String f, final List values, final List variables) + throws CalculatorException { + Complex value = new Complex(0, 0); + String number = ""; + String function = ""; + + boolean hasNumber = false; + boolean hasFunction = false; + boolean isImaginary = false; + + for (int i = 0; i < f.length(); i++) { + final char character = f.charAt(i); + + if (character >= '0' && character <= '9') { + + hasNumber = true; + number += character; + if (i == (f.length() - 1)) { + value = new Complex(new Double(number), 0); + number = ""; + hasNumber = false; + } + + } else if (character == '+') { + + if (hasNumber && !isImaginary) { + final Double numb = new Double(number); + final String new_f = f.substring(i + 1, f.length()); + value = Complex.add(new Complex(numb, 0), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasNumber && isImaginary) { + final Double numb = new Double(number); + final String new_f = f.substring(i + 1, f.length()); + value = Complex.add(new Complex(0, numb), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + isImaginary = false; + number = ""; + } else if (hasFunction) { + final String new_f = f.substring(i + 1, f.length()); + value = Complex.add(eval(function, values, variables), eval(new_f, values, variables)); + i += new_f.length(); + hasFunction = false; + function = ""; + + } else { + final String new_f = f.substring(i + 1, f.length()); + value = Complex.add(value, eval(new_f, values, variables)); + i += new_f.length(); + } + + } else if (character == '*') { + + if (hasNumber && !isImaginary) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.mul(new Complex(numb, 0), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + number = ""; + + } else if (hasNumber && isImaginary) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.mul(new Complex(0, numb), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + isImaginary = false; + number = ""; + } else if (hasFunction) { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.mul(eval(function, values, variables), eval(new_f, values, variables)); + i += new_f.length(); + hasFunction = false; + function = ""; + } else { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.mul(value, eval(new_f, values, variables)); + i += new_f.length(); + } + + } else if (character == '-') { + + if (hasNumber && !isImaginary) { + final Double numb = new Double(number); + final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); + value = Complex.sub(new Complex(numb, 0), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasNumber && isImaginary) { + final Double numb = new Double(number); + final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); + value = Complex.sub(new Complex(0, numb), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + isImaginary = false; + number = ""; + + } else if (hasFunction) { + final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); + value = Complex.sub(eval(function, values, variables), eval(new_f, values, variables)); + i += new_f.length(); + hasFunction = false; + function = ""; + + } else { + final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); + value = Complex.sub(value, eval(new_f, values, variables)); + i += new_f.length(); + } + + } else if (character == '/') { + + if (hasNumber && !isImaginary) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.div(new Complex(numb, 0), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasNumber && isImaginary) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.div(new Complex(0, numb), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + isImaginary = false; + number = ""; + + } else if (hasFunction) { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.div(eval(function, values, variables), eval(new_f, values, variables)); + i += new_f.length(); + hasFunction = false; + function = ""; + + } else { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.div(value, eval(new_f, values, variables)); + i += new_f.length(); + } + + } else if (character == '^') { + + if (hasNumber && !isImaginary) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.pow(eval(new_f, values, variables), numb); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasNumber && isImaginary) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.pow(eval(new_f, values, variables), new Complex(0, numb)); + i += new_f.length(); + hasNumber = false; + isImaginary = false; + number = ""; + + } else if (hasFunction) { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.pow(eval(function, values, variables), eval(new_f, values, variables)); + i += new_f.length(); + hasFunction = false; + function = ""; + + } else { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = Complex.pow(value, eval(new_f, values, variables)); + i += new_f.length(); + } + + } else if (character == '.') { + if (i == (f.length() - 1)) { + throw new CalculatorException("The function is not well-formed"); + } + if (hasNumber && (number.length() > 0)) { + number += character; + } + + } else if (character == '(') { + if (i == (f.length() - 1)) { + throw new CalculatorException("The function is not well-formed"); + } + + final String new_f = f.substring(i + 1, nextBracket(f)); + if (hasFunction) { + if (Constants.SIN.equals(function)) { + value = eval(new_f, values, variables).sin(); + + } else if (Constants.COS.equals(function)) { + value = eval(new_f, values, variables).cos(); + + } else if (Constants.TAN.equals(function)) { + value = eval(new_f, values, variables).tan(); + + } else if (Constants.SINH.equals(function)) { + value = eval(new_f, values, variables).sinh(); + + } else if (Constants.COSH.equals(function)) { + value = eval(new_f, values, variables).cosh(); + + } else if (Constants.TANH.equals(function)) { + value = eval(new_f, values, variables).tanh(); + + } else if (Constants.ASIN.equals(function)) { + value = eval(new_f, values, variables).asin(); + + } else if (Constants.ACOS.equals(function)) { + value = eval(new_f, values, variables).acos(); + + } else if (Constants.ATAN.equals(function)) { + value = eval(new_f, values, variables).atan(); + } else if (Constants.LN.equals(function)) { + value = eval(new_f, values, variables).log(); + } else if (Constants.LOG.equals(function)) { + value = eval(new_f, values, variables).log10(); + } else if (Constants.SQRT.equals(function)) { + value = eval(new_f, values, variables).sqrt(); + } else if (Constants.CBRT.equals(function)) { + value = Complex.cbrt(eval(new_f, values, variables)); + } else { + throw new CalculatorException("The function is not well-formed"); + } + + hasFunction = false; + function = ""; + + } else { + value = eval(new_f, values, variables); + } + i += new_f.length() + 1; + + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + + } else if (character == ' ') { + + } else if (character == 'i') { + if (!hasFunction) { + if (hasNumber) { + + value = new Complex(0, new Double(number)); + number = ""; + isImaginary = true; + } else { + value = new Complex(0, 1); + isImaginary = true; + } + } else { + + function = function + character; + hasFunction = true; + + if (i == (f.length() - 1)) { + + if (Constants.E.equals(function)) { + value = new Complex(StrictMath.E, 0); + } else if (Constants.PI.equals(function)) { + value = new Complex(StrictMath.PI, 0); + } else { + if (function.length() == 1) { + final int n = variables.indexOf(function); + if (n >= 0) { + value = values.get(n); + } else { + throw new CalculatorException("function is not well defined"); + } + + } else { + throw new CalculatorException("function is not well defined"); + } + } + } + } + + } else if (character == 'j') { + if (!hasFunction) { + if (hasNumber) { + value = new Complex(0, new Double(number)); + isImaginary = true; + } else { + value = new Complex(0, 1); + isImaginary = true; + } + } else { + function = function + character; + hasFunction = true; + + if (i == (f.length() - 1)) { + + if (function.equals(Constants.E)) { + value = new Complex(StrictMath.E, 0); + } else if (function.equals(Constants.PI)) { + value = new Complex(StrictMath.PI, 0); + } else { + if (function.length() == 1) { + final int n = variables.indexOf(function); + if (n >= 0) { + value = values.get(n); + } else { + throw new CalculatorException("function is not well defined"); + } + + } else { + throw new CalculatorException("function is not well defined"); + } + } + + } + } + + } else if (isValidCharacter(character)) { + function = function + character; + hasFunction = true; + + if (i == (f.length() - 1)) { + + if (Constants.E.equals(function)) { + value = new Complex(StrictMath.E, 0); + + } else if (Constants.PI.equals(function)) { + value = new Complex(StrictMath.PI, 0); + } else { + if (function.length() == 1) { + final int n = variables.indexOf(function); + if (n >= 0) { + value = values.get(n); + } else { + throw new CalculatorException("function is not well defined"); + } + + } else { + throw new CalculatorException("function is not well defined"); + } + } + } + } else { + throw new CalculatorException("Invalid character:" + character); + } + } + return value; + + } + + /** + * nextFunction. + * + * @param f the f + * @return the string + * @throws CalculatorException the calculator exception + */ + private String nextFunction(final String f) throws CalculatorException { + String result = ""; + + for (int i = 0; i < f.length(); i++) { + final char character = f.charAt(i); + + if (isValidNumericAndCharacter(character)) { + result += character; + } else if (character == '+' || character == '*' || character == '-' || character == '/') { + i = f.length(); + } else if (character == '.' || character == '^') { + result += character; + } else if (character == '(') { + final String new_f = f.substring(i, nextBracket(f) + 1); + result += new_f; + i = (i + new_f.length()) - 1; + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + } else if (character == ' ') { + result += character; + } else { + throw new CalculatorException("Invalid character:" + character); + } + } + return result; + + } + + /** + * nextMinusFunction. + * + * @param f the f + * @return the string + * @throws CalculatorException the calculator exception + */ + private String nextMinusFunction(final String f) throws CalculatorException { + String result = ""; + + for (int i = 0; i < f.length(); i++) { + final char character = f.charAt(i); + + if (isValidNumericAndCharacter(character)) { + result += character; + } else if (character == '+' || character == '-') { + i = f.length(); + } else if (character == '*' || character == '/' || character == '.' || character == '^') { + result += character; + } else if (character == '(') { + final String new_f = f.substring(i, nextBracket(f) + 1); + result += new_f; + i = (i + new_f.length()) - 1; + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + } else if (character == ' ') { + result += character; + } else { + throw new CalculatorException("Invalid character:" + character); + } + + } + return result; + } + + /** + * isValidCharacter. + * + * @param character the character + * @return true, if is valid character + */ + private boolean isValidCharacter(final char character) { + boolean result = false; + if ((character >= 'a' && character <= 'z')) { + result = true; + } + return result; + } + + /** + * isValidNumericAndCharacter. + * + * @param character the character + * @return true, if is valid numeric and character + */ + private boolean isValidNumericAndCharacter(final char character) { + boolean result = false; + if ((character >= 'a' && character <= 'z') || (character >= '0' && character <= '9')) { + result = true; + } + return result; + } + + /** + * nextBracket. + * + * @param f the f + * @return the int + * @throws CalculatorException the calculator exception + */ + private int nextBracket(final String f) throws CalculatorException { + int result = 0; + int count = 0; + for (int i = 0; i < f.length(); i++) { + final char character = f.charAt(i); + if (character == '(') { + result = i; + count++; + } else if (character == ')') { + result = i; + count--; + if (count == 0) { + return i; + } + } else { + result = i; + } + } + + if (count != 0) { + throw new CalculatorException("( is not finished"); + } + return result; + } } diff --git a/src/main/java/com/expression/parser/function/Constants.java b/src/main/java/com/expression/parser/function/Constants.java new file mode 100644 index 0000000..70e0d1a --- /dev/null +++ b/src/main/java/com/expression/parser/function/Constants.java @@ -0,0 +1,48 @@ +package com.expression.parser.function; + +public class Constants { + /** The Constant SIN. */ + public static final String SIN = "sin"; + + /** The Constant COS. */ + public static final String COS = "cos"; + + /** The Constant SINH. */ + public static final String SINH = "sinh"; + + /** The Constant COSH. */ + public static final String COSH = "cosh"; + + /** The Constant TAN. */ + public static final String TAN = "tan"; + + /** The Constant TANH. */ + public static final String TANH = "tanh"; + + /** The Constant ASIN. */ + public static final String ASIN = "asin"; + + /** The Constant ACOS. */ + public static final String ACOS = "acos"; + + /** The Constant ATAN. */ + public static final String ATAN = "atan"; + + /** The Constant E. */ + public static final String E = "e"; + + /** The Constant PI. */ + public static final String PI = "pi"; + + /** The Constant LN. */ + public static final String LN = "ln"; + + /** The Constant LOG. */ + public static final String LOG = "log"; + + /** The Constant SQRT. */ + public static final String SQRT = "sqrt"; + + /** The Constant CBRT. */ + public static final String CBRT = "cbrt"; +} diff --git a/src/main/java/com/expression/parser/function/FunctionX.java b/src/main/java/com/expression/parser/function/FunctionX.java index cc68d6b..f57ba25 100644 --- a/src/main/java/com/expression/parser/function/FunctionX.java +++ b/src/main/java/com/expression/parser/function/FunctionX.java @@ -3,788 +3,429 @@ import com.expression.parser.ParserManager; import com.expression.parser.exception.CalculatorException; +/** + * The Class FunctionX. + */ public class FunctionX { - public static final String SIN = "sin"; - public static final String COS = "cos"; - public static final String SINH = "sinh"; - public static final String COSH = "cosh"; - public static final String TAN = "tan"; - public static final String TANH = "tanh"; - public static final String ASIN = "asin"; - public static final String ACOS = "acos"; - public static final String ATAN = "atan"; - public static final String E = "e"; - public static final String PI = "pi"; - public static final String LN = "ln"; - public static final String LOG = "log"; - public static final String SQRT = "sqrt"; - public static final String CBRT = "cbrt"; - - /** - * setup - */ - private boolean degree = false; - - /** - * f(x) - */ - private String f_x; - - /** - * FunctionX - * - * @param f_x - * f(x) - */ - public FunctionX(final String f_x) { - this.f_x = f_x.trim().replaceAll(" ", ""); - this.degree = ParserManager.getInstance().isDeegre(); - } - - /** - * - * getter f(x) - * - * @return - */ - public String getF_x() { - return this.f_x; - } - - /** - * setter f(x) - * - * - * @param f_x - */ - public void setF_x(final String f_x) { - this.f_x = f_x; - } - - /** - * - * get f(x0) - * - * @param xo - * point - * @return - * @throws CalculatorException - */ - public double getF_xo(final double xo) throws CalculatorException { - - return eval(this.f_x, xo); - } - - /** - * - * eval - * - * @param f_x - * @param xi - * @return - * @throws CalculatorException - */ - private double eval(String f_x, final double xi) throws CalculatorException { - f_x = f_x.trim().toLowerCase(); - double value = 0; - String number = ""; - String function = ""; - boolean hasNumber = false; - boolean hasFunction = false; - - for (int i = 0; i < f_x.length(); i++) { - final char character = f_x.charAt(i); - switch (character) { - case '*': - if (hasNumber) { - final Double numb = new Double(number); - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = numb * eval(new_f_x, xi); - i = i + new_f_x.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = eval(function, xi) * eval(new_f_x, xi); - i = i + new_f_x.length(); - hasFunction = false; - function = ""; - } else { - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = value * eval(new_f_x, xi); - i = i + new_f_x.length(); - } - break; - case '+': - - if (hasNumber) { - final Double numb = new Double(number); - final String new_f_x = f_x.substring(i + 1, f_x.length()); - value = numb + eval(new_f_x, xi); - i = i + new_f_x.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f_x = f_x.substring(i + 1, f_x.length()); - value = eval(function, xi) + eval(new_f_x, xi); - i = i + new_f_x.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f_x = f_x.substring(i + 1, f_x.length()); - value = value + eval(new_f_x, xi); - i = i + new_f_x.length(); - } - break; - - case '-': - - if (hasNumber) { - final Double numb = new Double(number); - final String new_f_x = nextMinusFunction(f_x.substring(i + 1, f_x.length())); - value = numb - eval(new_f_x, xi); - i = i + new_f_x.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f_x = nextMinusFunction(f_x.substring(i + 1, f_x.length())); - value = eval(function, xi) - eval(new_f_x, xi); - i = i + new_f_x.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f_x = nextMinusFunction(f_x.substring(i + 1, f_x.length())); - value = value - eval(new_f_x, xi); - i = i + new_f_x.length(); - } - break; - case '/': - - if (hasNumber) { - final Double numb = new Double(number); - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = numb / eval(new_f_x, xi); - i = i + new_f_x.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = eval(function, xi) / eval(new_f_x, xi); - i = i + new_f_x.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = value / eval(new_f_x, xi); - i = i + new_f_x.length(); - } - break; - case '^': - - if (hasNumber) { - final Double numb = new Double(number); - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = Math.pow(numb.doubleValue(), eval(new_f_x, xi)); - i = i + new_f_x.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = Math.pow(eval(function, xi), eval(new_f_x, xi)); - i = i + new_f_x.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); - value = Math.pow(value, eval(new_f_x, xi)); - i = i + new_f_x.length(); - } - - break; - case '0': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - - break; - case '1': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '2': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '3': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - - break; - case '4': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '5': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '6': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '7': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - - break; - case '8': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '9': - hasNumber = true; - number = number + character; - if (i == (f_x.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - - break; - case '.': - if (i == (f_x.length() - 1)) { - throw new CalculatorException("The function is not well-formed"); - } - if (hasNumber && (number.length() > 0)) { - number = number + character; - } - break; - case '(': - if (i == (f_x.length() - 1)) { - throw new CalculatorException("The function is not well-formed"); - } - - final String new_f_x = f_x.substring(i + 1, nextBracket(f_x)); - if (hasFunction) { - if (function.equals(SIN)) { - if (this.degree) { - value = Math.sin(Math.toRadians(eval(new_f_x, xi))); - } else { - value = Math.sin(eval(new_f_x, xi)); - } - - } else if (function.equals(COS)) { - if (this.degree) { - value = Math.cos(Math.toRadians(eval(new_f_x, xi))); - } else { - value = Math.cos(eval(new_f_x, xi)); - } - } else if (function.equals(TAN)) { - if (this.degree) { - value = Math.tan(Math.toRadians(eval(new_f_x, xi))); - } else { - value = Math.tan(eval(new_f_x, xi)); - } - - } else if (function.equals(SINH)) { - value = Math.sinh(eval(new_f_x, xi)); - - } else if (function.equals(COSH)) { - value = Math.cosh(eval(new_f_x, xi)); - - } else if (function.equals(TANH)) { - value = Math.tanh(eval(new_f_x, xi)); - - } else if (function.equals(ASIN)) { - if (this.degree) { - value = Math.asin(eval(new_f_x, xi)) * (180 / Math.PI); - } else { - value = Math.asin(eval(new_f_x, xi)); - } - } else if (function.equals(ACOS)) { - if (this.degree) { - value = Math.acos(eval(new_f_x, xi)) * (180 / Math.PI); - } else { - value = Math.acos(eval(new_f_x, xi)); - } - } else if (function.equals(ATAN)) { - if (this.degree) { - value = Math.atan(eval(new_f_x, xi)) * (180 / Math.PI); - } else { - value = Math.atan(eval(new_f_x, xi)); - } - } else if (function.equals(LN)) { - value = Math.log(eval(new_f_x, xi)); - } else if (function.equals(LOG)) { - value = Math.log10(eval(new_f_x, xi)); - } else if (function.equals(SQRT)) { - value = Math.sqrt(eval(new_f_x, xi)); - } else if (function.equals(CBRT)) { - value = Math.cbrt(eval(new_f_x, xi)); - } else { - throw new CalculatorException("The function is not well-formed"); - } - - hasFunction = false; - function = ""; - - } else { - value = eval(new_f_x, xi); - } - i = i + new_f_x.length() + 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - break; - default: - if (isValidCharacter(character)) { - function = function + character; - hasFunction = true; - - if (i == (f_x.length() - 1)) { - - if (function.equals(E)) { - value = Math.E; - - } else if (function.equals(PI)) { - value = Math.PI; - } else { - if (function.length() == 1) { - value = xi; - } else { - throw new CalculatorException("function is not well defined"); - } - } - - } - - } else { - throw new CalculatorException("Invalid character"); - } - - break; - } - - } - return value; - } - - private String nextFunction(String f_x) throws CalculatorException { - String result = ""; - f_x = f_x.trim().toLowerCase(); - - for (int i = 0; i < f_x.length(); i++) { - final char character = f_x.charAt(i); - - switch (character) { - case '*': - i = f_x.length(); - break; - case '/': - i = f_x.length(); - break; - case '+': - i = f_x.length(); - break; - case '-': - i = f_x.length(); - break; - case '^': - result = result + character; - break; - case '.': - result = result + character; - break; - case '(': - - final String new_f_x = f_x.substring(i, nextBracket(f_x) + 1); - result = result + new_f_x; - i = (i + new_f_x.length()) - 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; - } - } - return result; - } - - private String nextMinusFunction(String f_x) throws CalculatorException { - String result = ""; - f_x = f_x.trim().toLowerCase(); - - for (int i = 0; i < f_x.length(); i++) { - final char character = f_x.charAt(i); - - switch (character) { - case '*': - result = result + character; - break; - case '/': - result = result + character; - break; - case '+': - i = f_x.length(); - break; - case '-': - i = f_x.length(); - break; - case '^': - result = result + character; - break; - case '.': - result = result + character; - break; - case '(': - - final String new_f_x = f_x.substring(i, nextBracket(f_x) + 1); - result = result + new_f_x; - i = (i + new_f_x.length()) - 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; - } - } - return result; - } - - /** - * - * isValidCharacter - * - * @param character - * @return - */ - private boolean isValidCharacter(final char character) { - boolean result = false; - switch (character) { - case 'a': - result = true; - break; - case 'b': - result = true; - break; - case 'c': - result = true; - break; - case 'd': - result = true; - break; - case 'e': - result = true; - break; - case 'f': - result = true; - break; - case 'g': - result = true; - break; - case 'h': - result = true; - break; - case 'i': - result = true; - break; - case 'j': - result = true; - break; - case 'k': - result = true; - break; - - case 'l': - result = true; - break; - case 'm': - result = true; - break; - case 'n': - result = true; - break; - case 'o': - result = true; - break; - case 'p': - result = true; - break; - case 'q': - result = true; - break; - case 'r': - result = true; - break; - case 's': - result = true; - break; - case 't': - result = true; - break; - case 'u': - result = true; - break; - case 'v': - result = true; - break; - case 'w': - result = true; - break; - case 'x': - result = true; - break; - case 'y': - result = true; - break; - case 'z': - result = true; - break; - default: - result = false; - break; - } - - return result; - } - - /** - * - * isValidNumericAndCharacter - * - * @param character - * @return - */ - private boolean isValidNumericAndCharacter(final char character) { - boolean result = false; - switch (character) { - case 'a': - result = true; - break; - case 'b': - result = true; - break; - case 'c': - result = true; - break; - case 'd': - result = true; - break; - case 'e': - result = true; - break; - case 'f': - result = true; - break; - case 'g': - result = true; - break; - case 'h': - result = true; - break; - case 'i': - result = true; - break; - case 'j': - result = true; - break; - case 'k': - result = true; - break; - - case 'l': - result = true; - break; - case 'm': - result = true; - break; - case 'n': - result = true; - break; - case 'o': - result = true; - break; - case 'p': - result = true; - break; - case 'q': - result = true; - break; - case 'r': - result = true; - break; - case 's': - result = true; - break; - case 't': - result = true; - break; - case 'u': - result = true; - break; - case 'v': - result = true; - break; - case 'w': - result = true; - break; - case 'x': - result = true; - break; - case 'y': - result = true; - break; - case 'z': - result = true; - break; - case '0': - result = true; - break; - case '1': - result = true; - break; - case '2': - result = true; - break; - case '3': - result = true; - break; - case '4': - result = true; - break; - case '5': - result = true; - break; - case '6': - result = true; - break; - case '7': - result = true; - break; - case '8': - result = true; - break; - case '9': - result = true; - break; - default: - result = false; - break; - } - - return result; - } - - /** - * - * nextBracket - * - * @param f_x - * f(x) - * @return - * @throws CalculatorException - */ - private int nextBracket(final String f_x) throws CalculatorException { - int result = 0; - int count = 0; - for (int i = 0; i < f_x.length(); i++) { - final char character = f_x.charAt(i); - switch (character) { - case '(': - result = i; - count++; - break; - case ')': - result = i; - count--; - if (count == 0) { - return i; - } - break; - default: - result = i; - break; - } - } - - if (count != 0) { - throw new CalculatorException("( is not finished"); - } - return result; - } + /** setup. */ + private boolean degree = false; + + /** f(x). */ + private String f_x; + + /** + * FunctionX. + * + * @param f_x f(x) + */ + public FunctionX(final String f_x) { + this.f_x = f_x.trim().replaceAll(" ", "").toLowerCase(); + degree = ParserManager.getInstance().isDeegre(); + } + + /** + * getter f(x). + * + * @return the f x + */ + public String getF_x() { + return f_x; + } + + /** + * setter f(x). + * + * @param f_x the new f x + */ + public void setF_x(final String f_x) { + this.f_x = f_x; + } + + /** + * get f(x0). + * + * @param xo point + * @return the f xo + * @throws CalculatorException the calculator exception + */ + public double getF_xo(final double xo) throws CalculatorException { + return eval(f_x, xo); + } + + /** + * eval. + * + * @param f_x the f x + * @param xi the xi + * @return the double + * @throws CalculatorException the calculator exception + */ + private double eval(final String f_x, final double xi) throws CalculatorException { + double value = 0; + String number = ""; + String function = ""; + boolean hasNumber = false; + boolean hasFunction = false; + + for (int i = 0; i < f_x.length(); i++) { + final char character = f_x.charAt(i); + + if (character >= '0' && character <= '9') { + + hasNumber = true; + number += character; + if (i == (f_x.length() - 1)) { + value = new Double(number).doubleValue(); + number = ""; + hasNumber = false; + } + + } else if (character == '+') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f_x = f_x.substring(i + 1, f_x.length()); + value = numb + eval(new_f_x, xi); + i += new_f_x.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f_x = f_x.substring(i + 1, f_x.length()); + value = eval(function, xi) + eval(new_f_x, xi); + i += new_f_x.length(); + hasFunction = false; + function = ""; + } else { + final String new_f_x = f_x.substring(i + 1, f_x.length()); + value = value + eval(new_f_x, xi); + i += new_f_x.length(); + } + + } else if (character == '*') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = numb * eval(new_f_x, xi); + i += new_f_x.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = eval(function, xi) * eval(new_f_x, xi); + i += new_f_x.length(); + hasFunction = false; + function = ""; + } else { + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = value * eval(new_f_x, xi); + i += new_f_x.length(); + } + + } else if (character == '-') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f_x = nextMinusFunction(f_x.substring(i + 1, f_x.length())); + value = numb - eval(new_f_x, xi); + i += new_f_x.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f_x = nextMinusFunction(f_x.substring(i + 1, f_x.length())); + value = eval(function, xi) - eval(new_f_x, xi); + i += new_f_x.length(); + hasFunction = false; + function = ""; + } else { + final String new_f_x = nextMinusFunction(f_x.substring(i + 1, f_x.length())); + value = value - eval(new_f_x, xi); + i += new_f_x.length(); + } + + } else if (character == '/') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = numb / eval(new_f_x, xi); + i += new_f_x.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = eval(function, xi) / eval(new_f_x, xi); + i += new_f_x.length(); + hasFunction = false; + function = ""; + } else { + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = value / eval(new_f_x, xi); + i += new_f_x.length(); + } + + } else if (character == '^') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = StrictMath.pow(numb.doubleValue(), eval(new_f_x, xi)); + i += new_f_x.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = StrictMath.pow(eval(function, xi), eval(new_f_x, xi)); + i += new_f_x.length(); + hasFunction = false; + function = ""; + } else { + final String new_f_x = nextFunction(f_x.substring(i + 1, f_x.length())); + value = StrictMath.pow(value, eval(new_f_x, xi)); + i += new_f_x.length(); + } + + } else if (character == '.') { + + if (i == (f_x.length() - 1)) { + throw new CalculatorException("The function is not well-formed"); + } + if (hasNumber && (number.length() > 0)) { + number += character; + } + + } else if (character == '(') { + if (i == (f_x.length() - 1)) { + throw new CalculatorException("The function is not well-formed"); + } + + final String new_f_x = f_x.substring(i + 1, nextBracket(f_x)); + if (hasFunction) { + if (Constants.SIN.equals(function)) { + + if (degree) { + value = StrictMath.sin(StrictMath.toRadians(eval(new_f_x, xi))); + } else { + value = StrictMath.sin(eval(new_f_x, xi)); + } + + } else if (Constants.COS.equals(function)) { + + if (degree) { + value = StrictMath.cos(StrictMath.toRadians(eval(new_f_x, xi))); + } else { + value = StrictMath.cos(eval(new_f_x, xi)); + } + + } else if (Constants.TAN.equals(function)) { + + if (degree) { + value = StrictMath.tan(StrictMath.toRadians(eval(new_f_x, xi))); + } else { + value = StrictMath.tan(eval(new_f_x, xi)); + } + + } else if (Constants.SINH.equals(function)) { + value = StrictMath.sinh(eval(new_f_x, xi)); + + } else if (Constants.COSH.equals(function)) { + value = StrictMath.cosh(eval(new_f_x, xi)); + + } else if (Constants.TANH.equals(function)) { + value = StrictMath.tanh(eval(new_f_x, xi)); + + } else if (Constants.ASIN.equals(function)) { + if (degree) { + value = StrictMath.asin(eval(new_f_x, xi)) * (180 / StrictMath.PI); + } else { + value = StrictMath.asin(eval(new_f_x, xi)); + } + } else if (Constants.ACOS.equals(function)) { + if (degree) { + value = StrictMath.acos(eval(new_f_x, xi)) * (180 / StrictMath.PI); + } else { + value = StrictMath.acos(eval(new_f_x, xi)); + } + } else if (Constants.ATAN.equals(function)) { + if (degree) { + value = StrictMath.atan(eval(new_f_x, xi)) * (180 / StrictMath.PI); + } else { + value = StrictMath.atan(eval(new_f_x, xi)); + } + } else if (Constants.LN.equals(function)) { + value = StrictMath.log(eval(new_f_x, xi)); + } else if (Constants.LOG.equals(function)) { + value = StrictMath.log10(eval(new_f_x, xi)); + } else if (Constants.SQRT.equals(function)) { + value = StrictMath.sqrt(eval(new_f_x, xi)); + } else if (Constants.CBRT.equals(function)) { + value = StrictMath.cbrt(eval(new_f_x, xi)); + } else { + throw new CalculatorException("The function is not well-formed"); + } + + hasFunction = false; + function = ""; + + } else { + value = eval(new_f_x, xi); + } + i += new_f_x.length() + 1; + + } else if (isValidCharacter(character)) { + function = function + character; + hasFunction = true; + + if (i == (f_x.length() - 1)) { + if (Constants.E.equals(function)) { + value = StrictMath.E; + } else if (Constants.PI.equals(function)) { + value = StrictMath.PI; + } else if (function.length() == 1) { + value = xi; + } else { + throw new CalculatorException("function is not well defined"); + } + } + + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + + } else if (character == ' ') { + + } else { + throw new CalculatorException("Invalid character:" + character); + } + } + return value; + } + + /** + * Next function. + * + * @param f_x the f x + * @return the string + * @throws CalculatorException the calculator exception + */ + private String nextFunction(final String f_x) throws CalculatorException { + String result = ""; + + for (int i = 0; i < f_x.length(); i++) { + final char character = f_x.charAt(i); + + if (isValidNumericAndCharacter(character)) { + result += character; + } else if (character == '+' || character == '*' || character == '-' || character == '/') { + i = f_x.length(); + } else if (character == '.' || character == '^') { + result += character; + } else if (character == '(') { + final String new_f_x = f_x.substring(i, nextBracket(f_x) + 1); + result += new_f_x; + i = (i + new_f_x.length()) - 1; + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + } else if (character == ' ') { + result += character; + } else { + throw new CalculatorException("Invalid character:" + character); + } + } + return result; + } + + /** + * Next minus function. + * + * @param f_x the f x + * @return the string + * @throws CalculatorException the calculator exception + */ + private String nextMinusFunction(final String f_x) throws CalculatorException { + String result = ""; + for (int i = 0; i < f_x.length(); i++) { + final char character = f_x.charAt(i); + + if (isValidNumericAndCharacter(character)) { + result += character; + } else if (character == '+' || character == '-') { + i = f_x.length(); + } else if (character == '*' || character == '/' || character == '.' || character == '^') { + result += character; + } else if (character == '(') { + final String new_f_x = f_x.substring(i, nextBracket(f_x) + 1); + result += new_f_x; + i = (i + new_f_x.length()) - 1; + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + } else if (character == ' ') { + result += character; + } else { + throw new CalculatorException("Invalid character:" + character); + } + } + return result; + } + + /** + * isValidCharacter. + * + * @param character the character + * @return true, if is valid character + */ + private boolean isValidCharacter(final char character) { + boolean result = false; + if ((character >= 'a' && character <= 'z')) { + result = true; + } + return result; + } + + /** + * isValidNumericAndCharacter. + * + * @param character the character + * @return true, if is valid numeric and character + */ + private boolean isValidNumericAndCharacter(final char character) { + boolean result = false; + if ((character >= 'a' && character <= 'z') || (character >= '0' && character <= '9')) { + result = true; + } + return result; + } + + /** + * nextBracket. + * + * @param f_x f(x) + * @return the int + * @throws CalculatorException the calculator exception + */ + private int nextBracket(final String f_x) throws CalculatorException { + int result = 0; + int count = 0; + for (int i = 0; i < f_x.length(); i++) { + final char character = f_x.charAt(i); + if (character == '(') { + result = i; + count++; + } else if (character == ')') { + result = i; + count--; + if (count == 0) { + return i; + } + } else { + result = i; + } + } + + if (count != 0) { + throw new CalculatorException("( is not finished"); + } + return result; + } } diff --git a/src/main/java/com/expression/parser/function/FunctionXs.java b/src/main/java/com/expression/parser/function/FunctionXs.java index b77acf8..0322cfa 100644 --- a/src/main/java/com/expression/parser/function/FunctionXs.java +++ b/src/main/java/com/expression/parser/function/FunctionXs.java @@ -7,822 +7,447 @@ import com.expression.parser.exception.CalculatorException; /** - * - * - * @author Sergio Besada - * + * The Class FunctionXs. */ public class FunctionXs { - public static final String SIN = "sin"; - public static final String COS = "cos"; - public static final String SINH = "sinh"; - public static final String COSH = "cosh"; - public static final String TAN = "tan"; - public static final String TANH = "tanh"; - public static final String ASIN = "asin"; - public static final String ACOS = "acos"; - public static final String ATAN = "atan"; - public static final String E = "e"; - public static final String PI = "pi"; - public static final String LN = "ln"; - public static final String LOG = "log"; - public static final String SQRT = "sqrt"; - public static final String CBRT = "cbrt"; - - /** - * setup - */ - public boolean degree = false; - - /** - * f(x,y,z,...) - */ - private String f; - - /** - * FunctionXs - * - * @param f - */ - public FunctionXs(final String f) { - this.f = f.trim().replaceAll(" ", ""); - this.degree = ParserManager.getInstance().isDeegre(); - - } - - /** - * getter f(x,y,z,...) - * - * - * @return - */ - public String getF() { - return this.f; - } - - /** - * - * setter f(x,y,z,...) - * - * @param f - */ - public void setF(final String f) { - this.f = f; - } - - /** - * - * getValue f(x0,y0,z0...) - * - * @param values - * (sort the values taking into account the variables) - * @param variables - * x,y,z etc - * @return - * @throws CalculatorException - */ - public double getValue(final List values, final List variables) throws CalculatorException { - final List vars = new ArrayList(); - for (final String string : variables) { - vars.add(string.toLowerCase()); - } - - return eval(this.f, values, vars); - } - - /** - * - * eval - * - * @param f - * @param values - * @param variables - * @return - * @throws CalculatorException - */ - private double eval(String f, final List values, final List variables) throws CalculatorException { - f = f.trim().toLowerCase(); - double value = 0; - String number = ""; - String function = ""; - boolean hasNumber = false; - boolean hasFunction = false; - - for (int i = 0; i < f.length(); i++) { - final char character = f.charAt(i); - switch (character) { - case '*': - if (hasNumber) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = numb * eval(new_f, values, variables); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = eval(function, values, variables) * eval(new_f, values, variables); - i = i + new_f.length(); - hasFunction = false; - function = ""; - } else { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = value * eval(new_f, values, variables); - i = i + new_f.length(); - } - break; - case '+': - - if (hasNumber) { - final Double numb = new Double(number); - final String new_f = f.substring(i + 1, f.length()); - value = numb + eval(new_f, values, variables); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f = f.substring(i + 1, f.length()); - value = eval(function, values, variables) + eval(new_f, values, variables); - i = i + new_f.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f = f.substring(i + 1, f.length()); - value = value + eval(new_f, values, variables); - i = i + new_f.length(); - } - break; - - case '-': - - if (hasNumber) { - final Double numb = new Double(number); - final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); - value = numb - eval(new_f, values, variables); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); - value = eval(function, values, variables) - eval(new_f, values, variables); - i = i + new_f.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); - value = value - eval(new_f, values, variables); - i = i + new_f.length(); - } - break; - case '/': - - if (hasNumber) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = numb / eval(new_f, values, variables); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = eval(function, values, variables) / eval(new_f, values, variables); - i = i + new_f.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = value / eval(new_f, values, variables); - i = i + new_f.length(); - } - break; - case '^': - - if (hasNumber) { - final Double numb = new Double(number); - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Math.pow(numb.doubleValue(), eval(new_f, values, variables)); - i = i + new_f.length(); - hasNumber = false; - number = ""; - } else if (hasFunction) { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Math.pow(eval(function, values, variables), eval(new_f, values, variables)); - i = i + new_f.length(); - hasFunction = false; - function = ""; - - } else { - final String new_f = nextFunction(f.substring(i + 1, f.length())); - value = Math.pow(value, eval(new_f, values, variables)); - i = i + new_f.length(); - } - - break; - case '0': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - - break; - case '1': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '2': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '3': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - - break; - case '4': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '5': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '6': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '7': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - - break; - case '8': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - break; - case '9': - hasNumber = true; - number = number + character; - if (i == (f.length() - 1)) { - value = new Double(number).doubleValue(); - number = ""; - hasNumber = false; - } - - break; - case '.': - if (i == (f.length() - 1)) { - throw new CalculatorException("The function is not well-formed"); - } - if (hasNumber && (number.length() > 0)) { - number = number + character; - } - break; - case '(': - if (i == (f.length() - 1)) { - throw new CalculatorException("The function is not well-formed"); - } - - final String new_f = f.substring(i + 1, nextBracket(f)); - if (hasFunction) { - if (function.equals(SIN)) { - if (this.degree) { - value = Math.sin(Math.toRadians(eval(new_f, values, variables))); - } else { - value = Math.sin(eval(new_f, values, variables)); - } - - } else if (function.equals(COS)) { - if (this.degree) { - value = Math.cos(Math.toRadians(eval(new_f, values, variables))); - } else { - value = Math.cos(eval(new_f, values, variables)); - } - } else if (function.equals(TAN)) { - if (this.degree) { - value = Math.tan(Math.toRadians(eval(new_f, values, variables))); - } else { - value = Math.tan(eval(new_f, values, variables)); - } - - } else if (function.equals(SINH)) { - value = Math.sinh(eval(new_f, values, variables)); - - } else if (function.equals(COSH)) { - value = Math.cosh(eval(new_f, values, variables)); - - } else if (function.equals(TANH)) { - value = Math.tanh(eval(new_f, values, variables)); - - } else if (function.equals(ASIN)) { - if (this.degree) { - value = Math.asin(eval(new_f, values, variables)) * (180 / Math.PI); - } else { - value = Math.asin(eval(new_f, values, variables)); - } - } else if (function.equals(ACOS)) { - if (this.degree) { - value = Math.acos(eval(new_f, values, variables)) * (180 / Math.PI); - } else { - value = Math.acos(eval(new_f, values, variables)); - } - } else if (function.equals(ATAN)) { - if (this.degree) { - value = Math.atan(eval(new_f, values, variables)) * (180 / Math.PI); - } else { - value = Math.atan(eval(new_f, values, variables)); - } - } else if (function.equals(LN)) { - value = Math.log(eval(new_f, values, variables)); - } else if (function.equals(LOG)) { - value = Math.log10(eval(new_f, values, variables)); - } else if (function.equals(SQRT)) { - value = Math.sqrt(eval(new_f, values, variables)); - } else if (function.equals(CBRT)) { - value = Math.cbrt(eval(new_f, values, variables)); - } else { - throw new CalculatorException("The function is not well-formed"); - } - - hasFunction = false; - function = ""; - - } else { - value = eval(new_f, values, variables); - } - i = i + new_f.length() + 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - break; - default: - if (isValidCharacter(character)) { - function = function + character; - hasFunction = true; - - if (i == (f.length() - 1)) { - - if (function.equals(E)) { - value = Math.E; - - } else if (function.equals(PI)) { - value = Math.PI; - } else { - if (function.length() == 1) { - final int n = variables.indexOf(function); - if (n >= 0) { - final double v = values.get(n).doubleValue(); - value = v; - } else { - throw new CalculatorException("function is not well defined"); - } - - } else { - throw new CalculatorException("function is not well defined"); - } - } - - } - - } else { - throw new CalculatorException("Invalid character"); - } - - break; - } - - } - return value; - } - - /** - * - * nextFunction - * - * @param f - * @return - * @throws CalculatorException - */ - private String nextFunction(String f) throws CalculatorException { - String result = ""; - f = f.trim().toLowerCase(); - - for (int i = 0; i < f.length(); i++) { - final char character = f.charAt(i); - - switch (character) { - case '*': - i = f.length(); - break; - case '/': - i = f.length(); - break; - case '+': - i = f.length(); - break; - case '-': - i = f.length(); - break; - case '^': - result = result + character; - break; - case '.': - result = result + character; - break; - case '(': - - final String new_f = f.substring(i, nextBracket(f) + 1); - result = result + new_f; - i = (i + new_f.length()) - 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; - } - } - return result; - } - - /** - * - * nextMinusFunction - * - * @param f - * @return - * @throws CalculatorException - */ - private String nextMinusFunction(String f) throws CalculatorException { - String result = ""; - f = f.trim().toLowerCase(); - - for (int i = 0; i < f.length(); i++) { - final char character = f.charAt(i); - - switch (character) { - case '*': - result = result + character; - break; - case '/': - result = result + character; - break; - case '+': - i = f.length(); - break; - case '-': - i = f.length(); - break; - case '^': - result = result + character; - break; - case '.': - result = result + character; - break; - case '(': - - final String new_f = f.substring(i, nextBracket(f) + 1); - result = result + new_f; - i = (i + new_f.length()) - 1; - - break; - case ')': - throw new CalculatorException(" '(' is not finished "); - - case ' ': - result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; - } - } - return result; - } - - /** - * - * isValidCharacter - * - * @param character - * @return - */ - private boolean isValidCharacter(final char character) { - boolean result = false; - switch (character) { - case 'a': - result = true; - break; - case 'b': - result = true; - break; - case 'c': - result = true; - break; - case 'd': - result = true; - break; - case 'e': - result = true; - break; - case 'f': - result = true; - break; - case 'g': - result = true; - break; - case 'h': - result = true; - break; - case 'i': - result = true; - break; - case 'j': - result = true; - break; - case 'k': - result = true; - break; - - case 'l': - result = true; - break; - case 'm': - result = true; - break; - case 'n': - result = true; - break; - case 'o': - result = true; - break; - case 'p': - result = true; - break; - case 'q': - result = true; - break; - case 'r': - result = true; - break; - case 's': - result = true; - break; - case 't': - result = true; - break; - case 'u': - result = true; - break; - case 'v': - result = true; - break; - case 'w': - result = true; - break; - case 'x': - result = true; - break; - case 'y': - result = true; - break; - case 'z': - result = true; - break; - default: - result = false; - break; - } - - return result; - } - - /** - * isValidNumericAndCharacter - * - * - * @param character - * @return - */ - private boolean isValidNumericAndCharacter(final char character) { - boolean result = false; - switch (character) { - case 'a': - result = true; - break; - case 'b': - result = true; - break; - case 'c': - result = true; - break; - case 'd': - result = true; - break; - case 'e': - result = true; - break; - case 'f': - result = true; - break; - case 'g': - result = true; - break; - case 'h': - result = true; - break; - case 'i': - result = true; - break; - case 'j': - result = true; - break; - case 'k': - result = true; - break; - - case 'l': - result = true; - break; - case 'm': - result = true; - break; - case 'n': - result = true; - break; - case 'o': - result = true; - break; - case 'p': - result = true; - break; - case 'q': - result = true; - break; - case 'r': - result = true; - break; - case 's': - result = true; - break; - case 't': - result = true; - break; - case 'u': - result = true; - break; - case 'v': - result = true; - break; - case 'w': - result = true; - break; - case 'x': - result = true; - break; - case 'y': - result = true; - break; - case 'z': - result = true; - break; - case '0': - result = true; - break; - case '1': - result = true; - break; - case '2': - result = true; - break; - case '3': - result = true; - break; - case '4': - result = true; - break; - case '5': - result = true; - break; - case '6': - result = true; - break; - case '7': - result = true; - break; - case '8': - result = true; - break; - case '9': - result = true; - break; - default: - result = false; - break; - } - - return result; - } - - /** - * - * nextBracket - * - * @param f - * @return - * @throws CalculatorException - */ - private int nextBracket(final String f) throws CalculatorException { - int result = 0; - int count = 0; - for (int i = 0; i < f.length(); i++) { - final char character = f.charAt(i); - switch (character) { - case '(': - result = i; - count++; - break; - case ')': - result = i; - count--; - if (count == 0) { - return i; - } - break; - default: - result = i; - break; - } - } - - if (count != 0) { - throw new CalculatorException("( is not finished"); - } - return result; - } + /** setup. */ + public boolean degree = false; + + /** + * f(x,y,z,...) + */ + private String f; + + /** + * FunctionXs. + * + * @param f the f + */ + public FunctionXs(final String f) { + this.f = f.trim().replaceAll(" ", "").toLowerCase(); + degree = ParserManager.getInstance().isDeegre(); + } + + /** + * getter f(x,y,z,...) + * + * @return the f + */ + public String getF() { + return f; + } + + /** + * setter f(x,y,z,...) + * + * @param f the new f + */ + public void setF(final String f) { + this.f = f; + } + + /** + * getValue f(x0,y0,z0...) + * + * @param values (sort the values taking into account the variables) + * @param variables x,y,z etc + * @return the value + * @throws CalculatorException the calculator exception + */ + public double getValue(final List values, final List variables) throws CalculatorException { + final List vars = new ArrayList(); + for (final String string : variables) { + vars.add(string.trim().replaceAll(" ", "").toLowerCase()); + } + return eval(f, values, vars); + } + + /** + * eval. + * + * @param f the f + * @param values the values + * @param variables the variables + * @return the double + * @throws CalculatorException the calculator exception + */ + private double eval(final String f, final List values, final List variables) + throws CalculatorException { + double value = 0; + String number = ""; + String function = ""; + boolean hasNumber = false; + boolean hasFunction = false; + + for (int i = 0; i < f.length(); i++) { + final char character = f.charAt(i); + + if (character >= '0' && character <= '9') { + + hasNumber = true; + number += character; + if (i == (f.length() - 1)) { + value = new Double(number).doubleValue(); + number = ""; + hasNumber = false; + } + + } else if (character == '+') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f = f.substring(i + 1, f.length()); + value = numb + eval(new_f, values, variables); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f = f.substring(i + 1, f.length()); + value = eval(function, values, variables) + eval(new_f, values, variables); + i += new_f.length(); + hasFunction = false; + function = ""; + + } else { + final String new_f = f.substring(i + 1, f.length()); + value = value + eval(new_f, values, variables); + i += new_f.length(); + } + + } else if (character == '*') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = numb * eval(new_f, values, variables); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = eval(function, values, variables) * eval(new_f, values, variables); + i += new_f.length(); + hasFunction = false; + function = ""; + } else { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = value * eval(new_f, values, variables); + i += new_f.length(); + } + + } else if (character == '-') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); + value = numb - eval(new_f, values, variables); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); + value = eval(function, values, variables) - eval(new_f, values, variables); + i += new_f.length(); + hasFunction = false; + function = ""; + + } else { + final String new_f = nextMinusFunction(f.substring(i + 1, f.length())); + value = value - eval(new_f, values, variables); + i += new_f.length(); + } + + } else if (character == '/') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = numb / eval(new_f, values, variables); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = eval(function, values, variables) / eval(new_f, values, variables); + i += new_f.length(); + hasFunction = false; + function = ""; + + } else { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = value / eval(new_f, values, variables); + i += new_f.length(); + } + + } else if (character == '^') { + + if (hasNumber) { + final Double numb = new Double(number); + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = StrictMath.pow(numb.doubleValue(), eval(new_f, values, variables)); + i += new_f.length(); + hasNumber = false; + number = ""; + } else if (hasFunction) { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = StrictMath.pow(eval(function, values, variables), eval(new_f, values, variables)); + i += new_f.length(); + hasFunction = false; + function = ""; + + } else { + final String new_f = nextFunction(f.substring(i + 1, f.length())); + value = StrictMath.pow(value, eval(new_f, values, variables)); + i += new_f.length(); + } + + } else if (character == '.') { + if (i == (f.length() - 1)) { + throw new CalculatorException("The function is not well-formed"); + } + if (hasNumber && (number.length() > 0)) { + number += character; + } + + } else if (character == '(') { + if (i == (f.length() - 1)) { + throw new CalculatorException("The function is not well-formed"); + } + + final String new_f = f.substring(i + 1, nextBracket(f)); + if (hasFunction) { + if (Constants.SIN.equals(function)) { + if (degree) { + value = StrictMath.sin(StrictMath.toRadians(eval(new_f, values, variables))); + } else { + value = StrictMath.sin(eval(new_f, values, variables)); + } + + } else if (Constants.COS.equals(function)) { + if (degree) { + value = StrictMath.cos(StrictMath.toRadians(eval(new_f, values, variables))); + } else { + value = StrictMath.cos(eval(new_f, values, variables)); + } + } else if (Constants.TAN.equals(function)) { + if (degree) { + value = StrictMath.tan(StrictMath.toRadians(eval(new_f, values, variables))); + } else { + value = StrictMath.tan(eval(new_f, values, variables)); + } + + } else if (Constants.SINH.equals(function)) { + value = StrictMath.sinh(eval(new_f, values, variables)); + + } else if (Constants.COSH.equals(function)) { + value = StrictMath.cosh(eval(new_f, values, variables)); + + } else if (Constants.TANH.equals(function)) { + value = StrictMath.tanh(eval(new_f, values, variables)); + + } else if (Constants.ASIN.equals(function)) { + if (degree) { + value = StrictMath.asin(eval(new_f, values, variables)) * (180 / StrictMath.PI); + } else { + value = StrictMath.asin(eval(new_f, values, variables)); + } + } else if (Constants.ACOS.equals(function)) { + if (degree) { + value = StrictMath.acos(eval(new_f, values, variables)) * (180 / StrictMath.PI); + } else { + value = StrictMath.acos(eval(new_f, values, variables)); + } + } else if (Constants.ATAN.equals(function)) { + if (degree) { + value = StrictMath.atan(eval(new_f, values, variables)) * (180 / StrictMath.PI); + } else { + value = StrictMath.atan(eval(new_f, values, variables)); + } + } else if (Constants.LN.equals(function)) { + value = StrictMath.log(eval(new_f, values, variables)); + } else if (Constants.LOG.equals(function)) { + value = StrictMath.log10(eval(new_f, values, variables)); + } else if (Constants.SQRT.equals(function)) { + value = StrictMath.sqrt(eval(new_f, values, variables)); + } else if (Constants.CBRT.equals(function)) { + value = StrictMath.cbrt(eval(new_f, values, variables)); + } else { + throw new CalculatorException("The function is not well-formed"); + } + + hasFunction = false; + function = ""; + + } else { + value = eval(new_f, values, variables); + } + i += new_f.length() + 1; + + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + + } else if (isValidCharacter(character)) { + function = function + character; + hasFunction = true; + + if (i == (f.length() - 1)) { + + if (Constants.E.equals(function)) { + value = StrictMath.E; + } else if (Constants.PI.equals(function)) { + value = StrictMath.PI; + } else { + if (function.length() == 1) { + final int n = variables.indexOf(function); + if (n >= 0) { + final double v = values.get(n).doubleValue(); + value = v; + } else { + throw new CalculatorException("function is not well defined"); + } + + } else { + throw new CalculatorException("function is not well defined"); + } + } + } + } else if (character == ' ') { + + } else { + throw new CalculatorException("Invalid character:" + character); + } + } + return value; + } + + /** + * nextFunction. + * + * @param f the f + * @return the string + * @throws CalculatorException the calculator exception + */ + private String nextFunction(final String f) throws CalculatorException { + String result = ""; + + for (int i = 0; i < f.length(); i++) { + final char character = f.charAt(i); + + if (isValidNumericAndCharacter(character)) { + result += character; + } else if (character == '+' || character == '*' || character == '-' || character == '/') { + i = f.length(); + } else if (character == '.' || character == '^') { + result += character; + } else if (character == '(') { + final String new_f = f.substring(i, nextBracket(f) + 1); + result += new_f; + i = (i + new_f.length()) - 1; + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + } else if (character == ' ') { + result += character; + } else { + throw new CalculatorException("Invalid character:" + character); + } + } + return result; + } + + /** + * nextMinusFunction. + * + * @param f the f + * @return the string + * @throws CalculatorException the calculator exception + */ + private String nextMinusFunction(final String f) throws CalculatorException { + String result = ""; + + for (int i = 0; i < f.length(); i++) { + final char character = f.charAt(i); + + if (isValidNumericAndCharacter(character)) { + result += character; + } else if (character == '+' || character == '-') { + i = f.length(); + } else if (character == '*' || character == '/' || character == '.' || character == '^') { + result += character; + } else if (character == '(') { + final String new_f = f.substring(i, nextBracket(f) + 1); + result += new_f; + i = (i + new_f.length()) - 1; + } else if (character == ')') { + throw new CalculatorException(" '(' is not finished "); + } else if (character == ' ') { + result += character; + } else { + throw new CalculatorException("Invalid character:" + character); + } + } + return result; + + } + + /** + * isValidCharacter. + * + * @param character the character + * @return true, if is valid character + */ + private boolean isValidCharacter(final char character) { + boolean result = false; + if ((character >= 'a' && character <= 'z')) { + result = true; + } + return result; + } + + /** + * isValidNumericAndCharacter. + * + * @param character the character + * @return true, if is valid numeric and character + */ + private boolean isValidNumericAndCharacter(final char character) { + boolean result = false; + if ((character >= 'a' && character <= 'z') || (character >= '0' && character <= '9')) { + result = true; + } + return result; + } + + /** + * nextBracket. + * + * @param f the f + * @return the int + * @throws CalculatorException the calculator exception + */ + private int nextBracket(final String f) throws CalculatorException { + int result = 0; + int count = 0; + for (int i = 0; i < f.length(); i++) { + final char character = f.charAt(i); + if (character == '(') { + result = i; + count++; + } else if (character == ')') { + result = i; + count--; + if (count == 0) { + return i; + } + } else { + result = i; + } + } + + if (count != 0) { + throw new CalculatorException("( is not finished"); + } + return result; + } } diff --git a/src/main/java/com/expression/parser/util/Combination.java b/src/main/java/com/expression/parser/util/Combination.java index 5824c49..136f0df 100644 --- a/src/main/java/com/expression/parser/util/Combination.java +++ b/src/main/java/com/expression/parser/util/Combination.java @@ -3,37 +3,33 @@ import com.expression.parser.exception.CalculatorException; /** - * - * - * @author Sergio Besada - * + * The Class Combination. */ public class Combination { - /** - * - * calc - * - * @param m - * @param n - * @return - * @throws CalculatorException - */ - public static double calc(final int m, final int n) throws CalculatorException { - if (n < 0) { - throw new CalculatorException("n cannot be <0"); - } + /** + * calc. + * + * @param m the m + * @param n the n + * @return the double + * @throws CalculatorException the calculator exception + */ + public static double calc(final int m, final int n) throws CalculatorException { + if (n < 0) { + throw new CalculatorException("n cannot be <0"); + } - double result = 0.0; - if (m == 0) { - result = 0.0; - } else { - result = (double) Factorial.cal(m, false) - / (double) (Factorial.cal(m - n, false) * Factorial.cal(n, false)); - } + double result = 0.0; + if (m == 0) { + result = 0.0; + } else { + result = (double) Factorial.cal(m, false) + / (double) (Factorial.cal(m - n, false) * Factorial.cal(n, false)); + } - return result; + return result; - } + } } diff --git a/src/main/java/com/expression/parser/util/Factorial.java b/src/main/java/com/expression/parser/util/Factorial.java index d7c0f8a..a07fbe3 100644 --- a/src/main/java/com/expression/parser/util/Factorial.java +++ b/src/main/java/com/expression/parser/util/Factorial.java @@ -3,40 +3,36 @@ import com.expression.parser.exception.CalculatorException; /** - * - * - * @author Sergio Besada - * + * The Class Factorial. */ public class Factorial { - /** - * - * cal - * - * @param m - * @param valueZero - * @return - * @throws CalculatorException - */ - public static int cal(final int m, final boolean valueZero) throws CalculatorException { - if (m < 0) { - throw new CalculatorException("the number must be greater than 0"); - } + /** + * cal. + * + * @param m the m + * @param valueZero the value zero + * @return the int + * @throws CalculatorException the calculator exception + */ + public static int cal(final int m, final boolean valueZero) throws CalculatorException { + if (m < 0) { + throw new CalculatorException("the number must be greater than 0"); + } - int result = 1; - if (m == 0) { - if (valueZero) { - result = 0; - } else { - result = 1; - } - } else { - for (int i = m; i > 0; i--) { - result *= i; - } - } - return result; - } + int result = 1; + if (m == 0) { + if (valueZero) { + result = 0; + } else { + result = 1; + } + } else { + for (int i = m; i > 0; i--) { + result *= i; + } + } + return result; + } } diff --git a/src/main/java/com/expression/parser/util/ParserResult.java b/src/main/java/com/expression/parser/util/ParserResult.java index eb0ad70..5ebaeb6 100644 --- a/src/main/java/com/expression/parser/util/ParserResult.java +++ b/src/main/java/com/expression/parser/util/ParserResult.java @@ -2,38 +2,74 @@ import com.expression.parser.function.Complex; +/** + * The Class ParserResult. + */ public class ParserResult { - private Double value; + /** The value. */ + private Double value; - private Complex complexValue; + /** The complex value. */ + private Complex complexValue; - private boolean complex; + /** The complex. */ + private boolean complex; - public Double getValue() { - return this.value; - } + /** + * Gets the value. + * + * @return the value + */ + public Double getValue() { + return value; + } - public void setValue(final Double value) { - this.value = value; - this.complex = false; - } + /** + * Sets the value. + * + * @param value the new value + */ + public void setValue(final Double value) { + this.value = value; + complex = false; + } - public Complex getComplexValue() { - return this.complexValue; - } + /** + * Gets the complex value. + * + * @return the complex value + */ + public Complex getComplexValue() { + return complexValue; + } - public void setComplexValue(final Complex complexValue) { - this.complexValue = complexValue; - this.complex = true; - } + /** + * Sets the complex value. + * + * @param complexValue the new complex value + */ + public void setComplexValue(final Complex complexValue) { + this.complexValue = complexValue; + complex = true; + } - public boolean isComplex() { - return this.complex; - } + /** + * Checks if is complex. + * + * @return true, if is complex + */ + public boolean isComplex() { + return complex; + } - public void setComplex(final boolean complex) { - this.complex = complex; - } + /** + * Sets the complex. + * + * @param complex the new complex + */ + public void setComplex(final boolean complex) { + this.complex = complex; + } } diff --git a/src/main/java/com/expression/parser/util/Point.java b/src/main/java/com/expression/parser/util/Point.java index 4b9b297..f5f3d6a 100644 --- a/src/main/java/com/expression/parser/util/Point.java +++ b/src/main/java/com/expression/parser/util/Point.java @@ -3,115 +3,156 @@ import com.expression.parser.function.Complex; /** - * - * - * @author Sergio Besada - * + * The Class Point. */ public class Point { - private String var; - - private Double value; - - private Complex complexValue; - - private boolean complex; - - public Point() { - - } - - public Point(final String var, final Double value) { - this.var = var; - this.value = value; - this.complex = false; - } - - public Point(final String var, final Complex value) { - this.var = var; - this.complexValue = value; - this.complex = true; - } - - /** - * getter var - * - * - * @return - */ - public String getVar() { - return this.var; - } - - /** - * - * setter var - * - * @param var - */ - public void setVar(final String var) { - this.var = var; - } - - /** - * - * getter Value - * - * @return - */ - public Double getValue() { - return this.value; - } - - /** - * - * setter Value - * - * @param value - */ - public void setValue(final Double value) { - this.value = value; - } - - /** - * - * getter complexValue - * - * @return - */ - public Complex getComplexValue() { - return this.complexValue; - } - - /** - * - * setter complexValue - * - * @param complexValue - */ - public void setComplexValue(final Complex complexValue) { - this.complexValue = complexValue; - } - - /** - * - * isComplex - * - * @return - */ - public boolean isComplex() { - return this.complex; - } - - /** - * - * setter complex - * - * @param complex - */ - public void setComplex(final boolean complex) { - this.complex = complex; - } + /** The var. */ + private String var; + + /** The value. */ + private Double value; + + /** The complex value. */ + private Complex complexValue; + + /** The string value. */ + private String stringValue; + + /** The complex. */ + private boolean complex; + + /** + * Instantiates a new point. + */ + public Point() { + + } + + /** + * Instantiates a new point. + * + * @param var the var + * @param value the value + */ + public Point(final String var, final Double value) { + this.var = var; + this.value = value; + complex = false; + } + + /** + * Instantiates a new point. + * + * @param var the var + * @param value the value + */ + public Point(final String var, final Complex value) { + this.var = var; + complexValue = value; + complex = true; + } + + /** + * Instantiates a new point. + * + * @param var the var + * @param value the value + */ + public Point(final String var, final String value) { + this.var = var; + stringValue = value; + + } + + /** + * getter var. + * + * @return the var + */ + public String getVar() { + return var; + } + + /** + * setter var. + * + * @param var the new var + */ + public void setVar(final String var) { + this.var = var; + } + + /** + * getter Value. + * + * @return the value + */ + public Double getValue() { + return value; + } + + /** + * setter Value. + * + * @param value the new value + */ + public void setValue(final Double value) { + this.value = value; + } + + /** + * getter complexValue. + * + * @return the complex value + */ + public Complex getComplexValue() { + return complexValue; + } + + /** + * setter complexValue. + * + * @param complexValue the new complex value + */ + public void setComplexValue(final Complex complexValue) { + this.complexValue = complexValue; + } + + /** + * isComplex. + * + * @return true, if is complex + */ + public boolean isComplex() { + return complex; + } + + /** + * setter complex. + * + * @param complex the new complex + */ + public void setComplex(final boolean complex) { + this.complex = complex; + } + + /** + * Gets the string value. + * + * @return the string value + */ + public String getStringValue() { + return stringValue; + } + + /** + * Sets the string value. + * + * @param stringValue the new string value + */ + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } } diff --git a/src/test/java/com/expression/parser/ComplexTest.java b/src/test/java/com/expression/parser/ComplexTest.java new file mode 100644 index 0000000..e4007c3 --- /dev/null +++ b/src/test/java/com/expression/parser/ComplexTest.java @@ -0,0 +1,182 @@ +package com.expression.parser; + +import org.junit.Test; + +import com.expression.parser.function.Complex; +import com.expression.parser.util.ParserResult; +import com.expression.parser.util.Point; + +public class ComplexTest { + + @Test + public void TestOne() { + + // TODO Auto-generated method stub + + String f_x = "1+j"; + + ParserResult result = Parser.eval(f_x); + + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "1+j*3"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "(1+j)*3"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "(1+2j)*3"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "(1+2j)^3"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "(1-2j)^3"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "ln((1-2j)^3)"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "log((1-2j)^3)"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "sqrt((1-2j)^3)"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "sin((2*3-2j)^0.5)"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "cos((3/2-2j)^0.5)"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "tan((3/2-2j)^(1+j))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "tan((3/2-2j)^(1+j))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "2*sinh((3/2-2j)^(1+j))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "(2+j)*cosh((3/2-2j)^(j+2j))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = " ((2+j)^2)/tanh((3/2-2j)^(j+2j))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = " ((2+j)^2) -asin((3/2-2j)^(j+2j))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = " ((2+j)^2) + acos((3/2-2j)^(5+2j))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = " ((2+j)/2) + atan((3/2-2j)^(5/2j))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = " e^(acos((3/2-2j)^(5+2j)))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = " e^(acos((3/2-2j)^(pi)))"; + + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + } + + @Test + public void TestTwo() { + + final Point xo = new Point("x", new Complex(1, 2)); + + String f_x = " e^(1*x*acos((3/2-2j)^(pi)))"; + + ParserResult result = Parser.eval(f_x, xo); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + final Point yo = new Point("y", new Complex(2, 1)); + + f_x = " e^(1*x*y*acos((3/2)^(pi)))"; + + result = Parser.eval(f_x, xo, yo); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = " e^(1*x*y*sin((3/2)^(pi)))"; + + result = Parser.eval(f_x, xo, yo); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "x+j"; + + result = Parser.eval(f_x, xo, yo); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + f_x = "x-y"; + + result = Parser.eval(f_x, xo, yo); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + + } + + @Test + public void TestThree() { + + String f_x = "1+j +x"; + final Point xo = new Point("x", "2 +j"); + + ParserResult result = Parser.eval(f_x, xo); + System.out.println("String Expressions-->real:" + result.getComplexValue().getR() + " imag:" + + result.getComplexValue().getI()); + + f_x = "1+j +x+y"; + final Point yo = new Point("y", "2*1+1"); + + result = Parser.eval(f_x, xo, yo); + System.out.println("String Expressions-->real:" + result.getComplexValue().getR() + " imag:" + + result.getComplexValue().getI()); + + f_x = "1 +x + y"; + + result = Parser.eval(f_x, xo, yo); + System.out.println("String Expressions-->real:" + result.getComplexValue().getR() + " imag:" + + result.getComplexValue().getI()); + + } +} diff --git a/src/test/java/com/expression/parser/RealTest.java b/src/test/java/com/expression/parser/RealTest.java new file mode 100644 index 0000000..aaa3e6a --- /dev/null +++ b/src/test/java/com/expression/parser/RealTest.java @@ -0,0 +1,153 @@ +package com.expression.parser; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.expression.parser.util.ParserResult; +import com.expression.parser.util.Point; + +public class RealTest { + + @Test + public void TestOne() { + + String f_x = " (2)-(5)"; + + double result = Parser.eval(f_x).getValue(); + assertTrue(result == -3.0); + + f_x = "((2)+(5))"; + + result = Parser.eval(f_x).getValue(); + assertTrue(result == 7.0); + + final Point xo = new Point("x", new Double(2)); + + f_x = "5*(x +3)"; + + result = Parser.eval(f_x, xo).getValue(); + assertTrue(result == 25.0); + + f_x = "5*(2*(sqrt((x+2)^2)) +3)"; + + result = Parser.eval(f_x, xo).getValue(); + assertTrue(result == 55.0); + + f_x = "5*(2*(sqrt((x+2)^2)/2) +3)"; + + result = Parser.eval(f_x, xo).getValue(); + assertTrue(result == 35.0); + + f_x = "cosh(6+(2/0))"; + System.out.println("result:" + Parser.eval(f_x, xo).getValue()); + + final String f_xs = " 2*(-(((z*3)*sqrt(x^(2)))+3))"; + + final Point zo = new Point("z", new Double(1)); + + result = Parser.eval(f_xs, xo, zo).getValue(); + assertTrue(result == -18.0); + + result = Parser.eval(f_xs, zo, xo).getValue(); + assertTrue(result == -18.0); + + final Point x2 = new Point("x", new Double(0)); + f_x = "cos(x)"; + ParserManager.getInstance().setDeegre(true); + result = Parser.eval(f_x, x2).getValue(); + assertTrue(result == 1.0); + ParserManager.getInstance().setDeegre(false); + + System.out.println("End test one"); + } + + @Test + public void TestTwo() { + + String f_x = " (2)-(5)"; + + double result = Parser.eval(f_x, null, null); + assertTrue(result == -3.0); + + f_x = "((2)+(5))"; + + result = Parser.eval(f_x, null, null); + assertTrue(result == 7.0); + + final Double x0 = new Double("2"); + + final Double[] values = { x0 }; + f_x = "5*(x +3)"; + + result = Parser.eval(f_x, null, values); + assertTrue(result == 25.0); + + final String f_xs = " 2*(-(((z*3)*sqrt(x^(2)))+3))"; + + final Double z0 = new Double("1"); + + final Double[] values2 = { x0, z0 }; + final String[] vars = { "x", "z" }; + + result = Parser.eval(f_xs, vars, values2); + assertTrue(result == -18.0); + System.out.println("End test two"); + + } + + @Test + public void TestThree() { + + String f_x = "+3 +5*5*(+1)"; + + ParserResult result = Parser.eval(f_x); + assertTrue(result.getValue() == 28.0); + + final Point xo = new Point("x", new Double(2)); + + f_x = "2.35*e^(-3)*x"; + + result = Parser.eval(f_x, xo); + assertTrue(result.getValue() == 0.2339992213289606); + + f_x = "sin(x)"; + + result = Parser.eval(f_x, xo); + assertTrue(result.getValue() == 0.9092974268256817); + + final Point yo = new Point("y", new Double(1)); + + final String f_xs = "x+5*y+(3 -y)"; + + result = Parser.eval(f_xs, xo, yo); + assertTrue(result.getValue() == 9.0); + System.out.println("End test three"); + } + + @Test + public void TestFour() { + + String f_xs = "x+5*y+(3 -y)"; + final Point xo = new Point("x", "1+1"); + final Point yo = new Point("y", "0+2*0+1*5-5 +1^4"); + + ParserResult result = Parser.eval(f_xs, xo, yo); + assertTrue(result.getValue() == 9.0); + + final String f_x = "2.35*e^(-3)*x"; + + result = Parser.eval(f_x, xo); + assertTrue(result.getValue() == 0.2339992213289606); + + f_xs = " 2*(-(((z*3)*sqrt(x^(2)))+3))"; + final Point zo = new Point("z", new Double(1)); + + result = Parser.eval(f_xs, zo, xo); + + assertTrue(result.getValue() == -18.0); + System.out.println("End test four"); + + } + +} diff --git a/src/test/java/com/expression/parser/SpeedTest.java b/src/test/java/com/expression/parser/SpeedTest.java new file mode 100644 index 0000000..f62164f --- /dev/null +++ b/src/test/java/com/expression/parser/SpeedTest.java @@ -0,0 +1,42 @@ +package com.expression.parser; + +import org.junit.Test; + +public class SpeedTest { + + @Test + public void testOne() { + + final long time1 = System.currentTimeMillis(); + Parser.simpleEval( + "6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4"); + final long time2 = System.currentTimeMillis(); + System.out.println("time test one:" + (time2 - time1)); + + } + + @Test + public void testTwo() { + + final long time1 = System.currentTimeMillis(); + + for (int i = 0; i < 1000000; i++) { + Parser.simpleEval( + "6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4 + 6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4"); + } + + final long time2 = System.currentTimeMillis(); + System.out.println("time test two:" + (time2 - time1)); + + } + + @Test + public void testThree() { + + final long time1 = System.currentTimeMillis(); + Parser.simpleEval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4"); + final long time2 = System.currentTimeMillis(); + System.out.println("time test three:" + (time2 - time1)); + + } +} diff --git a/src/test/java/com/expression/parser/Test_1.java b/src/test/java/com/expression/parser/Test_1.java deleted file mode 100644 index 43d9c79..0000000 --- a/src/test/java/com/expression/parser/Test_1.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.expression.parser; - -import org.junit.Test; - -import com.expression.parser.util.Point; - -public class Test_1 { - - @Test - public void Test_one() { - - final long time = System.currentTimeMillis(); - - final Point xo = new Point("x", new Double(2)); - final Point zo = new Point("z", new Double(1)); - for (int i = 0; i < 100000; i++) { - final String fx = ("2*x + 2*z^(2+1)"); - Parser.eval(fx, xo, zo); - } - - System.out.println(System.currentTimeMillis() - time); - /* - * String f_x = " (2)-(5)"; - * - * double result = Parser.eval(f_x); assertTrue(result == -3.0); - * - * f_x = "((2)+(5))"; - * - * result = Parser.eval(f_x); assertTrue(result == 7.0); - * - * final Point xo = new Point("x", new Double(2)); - * - * f_x = "5*(x +3)"; - * - * result = Parser.eval(f_x, xo); assertTrue(result == 25.0); - * - * f_x = "5*(2*(sqrt((x+2)^2)) +3)"; - * - * result = Parser.eval(f_x, xo); assertTrue(result == 55.0); - * - * f_x = "5*(2*(sqrt((x+2)^2)/2) +3)"; - * - * result = Parser.eval(f_x, xo); assertTrue(result == 35.0); - * - * f_x = "cosh(6+(2/0))"; System.out.println("result:" + Parser.eval(f_x, xo)); - * - * final String f_xs = " 2*(-(((z*3)*sqrt(x^(2)))+3))"; - * - * final Point zo = new Point("z", new Double(1)); - * - * result = Parser.eval(f_xs, xo, zo); assertTrue(result == -18.0); - * - * result = Parser.eval(f_xs, zo, xo); assertTrue(result == -18.0); - * - * final Point x2 = new Point("x", new Double(0)); f_x = "cos(x)"; ParserManager.getInstance().setDeegre(true); - * result = Parser.eval(f_x, x2); assertTrue(result == 1.0); ParserManager.getInstance().setDeegre(false); - */ - } -} diff --git a/src/test/java/com/expression/parser/Test_2.java b/src/test/java/com/expression/parser/Test_2.java deleted file mode 100644 index 8c835ae..0000000 --- a/src/test/java/com/expression/parser/Test_2.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.expression.parser; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -public class Test_2 { - - @Test - public void Test_two() { - - String f_x = " (2)-(5)"; - - double result = Parser.eval(f_x, null, null); - assertTrue(result == -3.0); - - f_x = "((2)+(5))"; - - result = Parser.eval(f_x, null, null); - assertTrue(result == 7.0); - - final Double x0 = new Double("2"); - - final Double[] values = { x0 }; - f_x = "5*(x +3)"; - - result = Parser.eval(f_x, null, values); - assertTrue(result == 25.0); - - final String f_xs = " 2*(-(((z*3)*sqrt(x^(2)))+3))"; - - final Double z0 = new Double("1"); - - final Double[] values2 = { x0, z0 }; - final String[] vars = { "x", "z" }; - - result = Parser.eval(f_xs, vars, values2); - assertTrue(result == -18.0); - - } -} diff --git a/src/test/java/com/expression/parser/Test_3.java b/src/test/java/com/expression/parser/Test_3.java deleted file mode 100644 index ded4777..0000000 --- a/src/test/java/com/expression/parser/Test_3.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.expression.parser; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.expression.parser.util.ParserResult; -import com.expression.parser.util.Point; - -public class Test_3 { - - @Test - public void Test_three() { - - String f_x = "+3 +5*5*(+1)"; - - ParserResult result = Parser.eval(f_x); - assertTrue(result.getValue() == 28.0); - - final Point xo = new Point("x", new Double(2)); - - f_x = "2.35*e^(-3)*x"; - - result = Parser.eval(f_x, xo); - assertTrue(result.getValue() == 0.2339992213289606); - - f_x = "sin(x)"; - - result = Parser.eval(f_x, xo); - - if (result.isComplex()) { - assertTrue(result.getComplexValue().getR() == 0.9092974268256817); - } else { - assertTrue(result.getValue() == 0.9092974268256817); - } - - final Point yo = new Point("y", new Double(1)); - - final String f_xs = "x+5*y+(3 -y)"; - - result = Parser.eval(f_xs, xo, yo); - assertTrue(result.getValue() == 9.0); - } -} diff --git a/src/test/java/com/expression/parser/Test_Complex.java b/src/test/java/com/expression/parser/Test_Complex.java deleted file mode 100644 index 3b5ca35..0000000 --- a/src/test/java/com/expression/parser/Test_Complex.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.expression.parser; - -import org.junit.Test; - -import com.expression.parser.function.Complex; -import com.expression.parser.util.ParserResult; -import com.expression.parser.util.Point; - -public class Test_Complex { - - @Test - public void Test_one() { - - // TODO Auto-generated method stub - - String f_x = "1+j"; - - ParserResult result = Parser.eval(f_x); - - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = "1+j*3"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); - - f_x = "(1+j)*3"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); - - f_x = "(1+2i)*3"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + - " imag:" + result.getComplexValue().getI()); - - f_x = "(1+2i)^3"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); - - f_x = "(1-2i)^3"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + - " imag:" + result.getComplexValue().getI()); - - f_x = "ln((1-2i)^3)"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); - - f_x = "log((1-2i)^3)"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); - - f_x = "sqrt((1-2i)^3)"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); - - f_x = "sin((2*3-2i)^0.5)"; - - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + - " imag:" + result.getComplexValue().getI()); - - f_x = "cos((3/2-2i)^0.5)"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = "tan((3/2-2i)^(1+j))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = "tan((3/2-2i)^(1+j))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = "2*sinh((3/2-2i)^(i+j))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = "(2+i)*cosh((3/2-2i)^(i+2j))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = " ((2+i)^2)/tanh((3/2-2i)^(i+2j))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = " ((2+i)^2) -asin((3/2-2i)^(i+2j))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = " ((2+i)^2) + acos((3/2-2i)^(5+2j))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = " ((2+i)/2) + atan((3/2-2i)^(5/2j))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = " e^(acos((3/2-2i)^(5+2j)))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = " e^(acos((3/2-2i)^(pi)))"; - - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - } - - @Test - public void Test_two() { - - Point xo = new Point("x", new Double(2)); - - xo = new Point("x", new Complex(1, 2)); - - String f_x = " e^(1*x*acos((3/2-2i)^(pi)))"; - - ParserResult result = Parser.eval(f_x, xo); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - final Point yo = new Point("y", new Complex(2, 1)); - - f_x = " e^(1*x*y*acos((3/2)^(pi)))"; - - result = Parser.eval(f_x, xo, yo); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = " e^(1*x*y*sin((3/2)^(pi)))"; - - result = Parser.eval(f_x, xo, yo); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = "x+j"; - - result = Parser.eval(f_x, xo, yo); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - f_x = "x-y"; - - result = Parser.eval(f_x, xo, yo); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - - } - -}