From fe757fb8bbd9cbcd732b01f5ed05b27c9d661d5a Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Wed, 20 May 2015 10:23:50 +0200 Subject: [PATCH 01/53] Update README.md --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e8802b3..b94d8d2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # 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 let you parse math expressions. This algorithm does not use a decision tree. It is a recursive algorithm. @@ -18,6 +18,14 @@ Here you can see an example: In the test package you can see more examples. +The last version supports complex expressions. Here an example: + + String f_x = " e^(1*x*acos((3/2-2i)^(pi)))"; + + Point xo = new Point("x", new Complex(1, 2)); + ParserResult result = Parser.eval(f_x, xo); + + This version is compiled for Java 1.6 From 357f25ee672b9e3a1d0c9f23ce40bfed4750460c Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 1 Aug 2019 20:15:30 +0200 Subject: [PATCH 02/53] Update README.md --- README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b94d8d2..90cea5f 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,20 @@ java math expression parser is a maven project that let you parse math expressio This algorithm does not use a decision tree. It is a recursive algorithm. -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 need 25% of the time to parse the same expression as JEP. With other algorithms that use trees like: + + --------- + | + | + --------- + | + --------------- + | | + --------- --------- + | 1 | | * | + --------- --------- + + It is even faster than them. This library is 10 times faster and it is tested using matlab. This library in python has 1600 downloads in the first 3 months. + Here you can see an example: @@ -15,6 +27,8 @@ Here you can see an example: double result = Parser.Eval(f_xs, xo, zo); + final double result1 = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); + In the test package you can see more examples. From 2621aa7c0d5e1d651bf174f452114e5dedd361ba Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Fri, 2 Aug 2019 12:23:19 +0200 Subject: [PATCH 03/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90cea5f..147c6f7 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m | 1 | | * | --------- --------- - It is even faster than them. This library is 10 times faster and it is tested using matlab. This library in python has 1600 downloads in the first 3 months. + It is even faster than them. This library is 10 times faster and it is tested using matlab. Here you can see an example: From 446a855687cc0b783d458a7fd7c1bb79ae11ed44 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Fri, 2 Aug 2019 18:05:38 +0200 Subject: [PATCH 04/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 147c6f7..36a1bbf 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ java math expression parser is a maven project that let you parse math expressio This algorithm does not use a decision tree. It is a recursive algorithm. -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. With other algorithms that use trees like: +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: --------- | + | From 92fee4429bba65270709791e3b29c5ad1eff4098 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Fri, 2 Aug 2019 22:48:28 +0200 Subject: [PATCH 05/53] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 36a1bbf..346e3b3 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m | 1 | | * | --------- --------- - It is even faster than them. This library is 10 times faster and it is tested using matlab. - + 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: + https://pypi.org/project/pymep/ Here you can see an example: From ccadc8b46965e577480eb7f22a7ff5daaad873fb Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Fri, 2 Aug 2019 22:53:31 +0200 Subject: [PATCH 06/53] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 346e3b3..5b939a7 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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: https://pypi.org/project/pymep/ -Here you can see an example: + +Examples: String f_xs = " 2*(-(((z*3)*sqrt(x^(2)))+3))"; From 38af4b716c12efa75caa2638b71ae9f04eac8e4b Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Mon, 5 Aug 2019 10:19:18 +0200 Subject: [PATCH 07/53] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b939a7..0a26dd7 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Examples: double result = Parser.Eval(f_xs, xo, zo); - final double result1 = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); + final double result1 = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); --> execution time = 4ms in i7-6500U In the test package you can see more examples. @@ -45,3 +45,5 @@ This version is compiled for Java 1.6 Enjoy it!! + +PD: If you think that my work deserves a donation you can do it: https://sbesada.github.io/ From ebce7b9c96729ad5571f87d55b387f5d69845ecf Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Mon, 5 Aug 2019 10:24:08 +0200 Subject: [PATCH 08/53] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a26dd7..c2a2a3e 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,8 @@ Examples: double result = Parser.Eval(f_xs, xo, zo); - final double result1 = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); --> execution time = 4ms in i7-6500U + final double result1 = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); + --> execution time = 4ms in i7-6500U In the test package you can see more examples. From 7950252013456cd57d088a31d12e2bbd7c18bde5 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Mon, 5 Aug 2019 11:01:56 +0200 Subject: [PATCH 09/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c2a2a3e..3899882 100644 --- a/README.md +++ b/README.md @@ -47,4 +47,4 @@ This version is compiled for Java 1.6 Enjoy it!! -PD: If you think that my work deserves a donation you can do it: https://sbesada.github.io/ +PD: If you think that my work deserves a donation, you can do it: https://sbesada.github.io/ From f9ae2ee4319bc9eed4fc4e0d995c3bff94bf2273 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Wed, 14 Aug 2019 23:23:14 +0200 Subject: [PATCH 10/53] Update README.md --- README.md | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3899882..2b1a8e0 100644 --- a/README.md +++ b/README.md @@ -20,21 +20,31 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m Examples: + String f_x = "+3 +5*5*(+1)"; + + ParserResult result = Parser.eval(f_x); + assertTrue(result.getValue() == 28.0); - 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)); + f_x = "2.35*e^(-3)*x"; + + result = Parser.eval(f_x, xo); + assertTrue(result.getValue() == 0.2339992213289606); - double result = Parser.Eval(f_xs, xo, zo); + + 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); - final double result1 = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); + final double result = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); --> execution time = 4ms in i7-6500U -In the test package you can see more examples. +In the test package you can see more examples with diferent constructors -The last version supports complex expressions. Here an example: +The last version supports expressions with complex numbers and multiple vars. Here an example: String f_x = " e^(1*x*acos((3/2-2i)^(pi)))"; From 95d2a5016b68131bcd93bdd1bc89352a233c8265 Mon Sep 17 00:00:00 2001 From: sbesda Date: Thu, 12 Sep 2019 22:59:20 +0200 Subject: [PATCH 11/53] DES new Version 2.0 --- pom.xml | 2 +- .../java/com/expression/parser/Parser.java | 439 ++-- .../com/expression/parser/ParserManager.java | 91 +- .../parser/exception/CalculatorException.java | 35 +- .../expression/parser/function/Complex.java | 1085 +++++----- .../parser/function/ComplexFunction.java | 1857 +++++++++-------- .../expression/parser/function/FunctionX.java | 1594 +++++++------- .../parser/function/FunctionXs.java | 1641 +++++++-------- .../expression/parser/util/Combination.java | 48 +- .../com/expression/parser/util/Factorial.java | 58 +- .../expression/parser/util/ParserResult.java | 82 +- .../com/expression/parser/util/Point.java | 255 ++- .../java/com/expression/parser/Test_1.java | 59 - .../java/com/expression/parser/Test_2.java | 41 - .../java/com/expression/parser/Test_3.java | 44 - .../com/expression/parser/Test_Complex.java | 223 +- .../java/com/expression/parser/Test_Real.java | 153 ++ 17 files changed, 3926 insertions(+), 3781 deletions(-) delete mode 100644 src/test/java/com/expression/parser/Test_1.java delete mode 100644 src/test/java/com/expression/parser/Test_2.java delete mode 100644 src/test/java/com/expression/parser/Test_3.java create mode 100644 src/test/java/com/expression/parser/Test_Real.java diff --git a/pom.xml b/pom.xml index 02607c3..3336b39 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.expression.parser com.expression.parser jar - 1.0.0 + 2.0.0 com.expression.parser diff --git a/src/main/java/com/expression/parser/Parser.java b/src/main/java/com/expression/parser/Parser.java index 643cc87..09fd62c 100644 --- a/src/main/java/com/expression/parser/Parser.java +++ b/src/main/java/com/expression/parser/Parser.java @@ -13,216 +13,237 @@ 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; - } + /** + * Eval. + * + * @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.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 the function + * @param vars the vars + * @param values the values + * @return the double + */ + 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 the function + * @param values the values + * @return the parser result + */ + 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 + // 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); + + 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; + } + + /** + * 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..a0720fb 100644 --- a/src/main/java/com/expression/parser/function/ComplexFunction.java +++ b/src/main/java/com/expression/parser/function/ComplexFunction.java @@ -6,930 +6,945 @@ import com.expression.parser.ParserManager; import com.expression.parser.exception.CalculatorException; +// TODO: Auto-generated Javadoc /** - * - * - * @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; - } + /** 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"; + + /** 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(" ", ""); + 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.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(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 the f + * @return the string + * @throws CalculatorException the calculator exception + */ + 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 the f + * @return the string + * @throws CalculatorException the calculator exception + */ + 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 the character + * @return true, if is valid character + */ + 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 the character + * @return true, if is valid numeric and character + */ + 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 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); + 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; + } } diff --git a/src/main/java/com/expression/parser/function/FunctionX.java b/src/main/java/com/expression/parser/function/FunctionX.java index cc68d6b..be8328d 100644 --- a/src/main/java/com/expression/parser/function/FunctionX.java +++ b/src/main/java/com/expression/parser/function/FunctionX.java @@ -3,788 +3,820 @@ 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; - } + /** 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"; + + /** 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(" ", ""); + 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(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 (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 (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 (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 (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 (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 (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; + } + + /** + * Next function. + * + * @param f_x the f x + * @return the string + * @throws CalculatorException the calculator exception + */ + 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; + } + + /** + * Next minus function. + * + * @param f_x the f x + * @return the string + * @throws CalculatorException the calculator exception + */ + 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 the character + * @return true, if is valid character + */ + 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 the character + * @return true, if is valid numeric and character + */ + 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 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); + 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; + } } diff --git a/src/main/java/com/expression/parser/function/FunctionXs.java b/src/main/java/com/expression/parser/function/FunctionXs.java index b77acf8..bc4cbfe 100644 --- a/src/main/java/com/expression/parser/function/FunctionXs.java +++ b/src/main/java/com/expression/parser/function/FunctionXs.java @@ -7,822 +7,835 @@ 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; - } + /** 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"; + + /** 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(" ", ""); + 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.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(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 (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 (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 (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 (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 (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 (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 the f + * @return the string + * @throws CalculatorException the calculator exception + */ + 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 the f + * @return the string + * @throws CalculatorException the calculator exception + */ + 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 the character + * @return true, if is valid character + */ + 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 the character + * @return true, if is valid numeric and character + */ + 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 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); + 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; + } } 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/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 index 3b5ca35..2700f2b 100644 --- a/src/test/java/com/expression/parser/Test_Complex.java +++ b/src/test/java/com/expression/parser/Test_Complex.java @@ -8,178 +8,175 @@ public class Test_Complex { - @Test - public void Test_one() { + @Test + public void Test_one() { - // TODO Auto-generated method stub + // TODO Auto-generated method stub - String f_x = "1+j"; + String f_x = "1+j"; - ParserResult result = Parser.eval(f_x); + ParserResult result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "1+j*3"; + f_x = "1+j*3"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "(1+j)*3"; + f_x = "(1+j)*3"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "(1+2i)*3"; + f_x = "(1+2j)*3"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + - " imag:" + result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "(1+2i)^3"; + f_x = "(1+2j)^3"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "(1-2i)^3"; + f_x = "(1-2j)^3"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + - " imag:" + result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "ln((1-2i)^3)"; + f_x = "ln((1-2j)^3)"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "log((1-2i)^3)"; + f_x = "log((1-2j)^3)"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "sqrt((1-2i)^3)"; + f_x = "sqrt((1-2j)^3)"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + " imag:" + - result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "sin((2*3-2i)^0.5)"; + f_x = "sin((2*3-2j)^0.5)"; - result = Parser.eval(f_x); - System.out.println("real:" + result.getComplexValue().getR() + - " imag:" + result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "cos((3/2-2i)^0.5)"; + f_x = "cos((3/2-2j)^0.5)"; - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "tan((3/2-2i)^(1+j))"; + f_x = "tan((3/2-2j)^(1+j))"; - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = "tan((3/2-2i)^(1+j))"; + f_x = "tan((3/2-2j)^(1+j))"; - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + 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))"; + 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()); + 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))"; + 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()); + 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))"; + 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()); + 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))"; + 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()); + 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))"; + 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()); + 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))"; + 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()); + 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)))"; + 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()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - f_x = " e^(acos((3/2-2i)^(pi)))"; + f_x = " e^(acos((3/2-2j)^(pi)))"; - result = Parser.eval(f_x); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + result = Parser.eval(f_x); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - } + } - @Test - public void Test_two() { + @Test + public void Test_two() { - Point xo = new Point("x", new Double(2)); + final Point xo = new Point("x", new Complex(1, 2)); - xo = new Point("x", new Complex(1, 2)); + String f_x = " e^(1*x*acos((3/2-2j)^(pi)))"; - 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()); - 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)); - final Point yo = new Point("y", new Complex(2, 1)); + f_x = " e^(1*x*y*acos((3/2)^(pi)))"; - 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()); - 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)))"; - 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()); - result = Parser.eval(f_x, xo, yo); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + f_x = "x+j"; - f_x = "x+j"; + result = Parser.eval(f_x, xo, yo); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - result = Parser.eval(f_x, xo, yo); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + f_x = "x-y"; - f_x = "x-y"; + result = Parser.eval(f_x, xo, yo); + System.out.println("real:" + result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); - result = Parser.eval(f_x, xo, yo); - System.out.println("real:" + - result.getComplexValue().getR() + " imag:" + result.getComplexValue().getI()); + } - } + @Test + public void Test_three() { + 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/Test_Real.java b/src/test/java/com/expression/parser/Test_Real.java new file mode 100644 index 0000000..9140f8d --- /dev/null +++ b/src/test/java/com/expression/parser/Test_Real.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 Test_Real { + + @Test + public void Test_one() { + + 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 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); + System.out.println("End test two"); + + } + + @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); + 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 Test_four() { + + 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"); + + } + +} From c72bb7eff057180a95cde4b87fbbc8296290138e Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 12 Sep 2019 23:05:00 +0200 Subject: [PATCH 12/53] Update README.md --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b1a8e0..2bf820d 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,14 @@ Examples: Parser.Eval(f_xs, xo, zo); + 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 + + ParserResult result = Parser.eval(f_xs, xo, yo); + + + final double result = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); --> execution time = 4ms in i7-6500U @@ -46,10 +54,15 @@ In the test package you can see more examples with diferent constructors The last version supports expressions with complex numbers and multiple vars. Here an example: - String f_x = " e^(1*x*acos((3/2-2i)^(pi)))"; + String f_x = " e^(1*x*acos((3/2-2j)^(pi)))"; Point xo = new Point("x", new Complex(1, 2)); 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); This version is compiled for Java 1.6 From 93adeabd8a2af564a42414bbbd263347af63de3f Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 12 Sep 2019 23:06:21 +0200 Subject: [PATCH 13/53] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2bf820d..48f80fc 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,10 @@ Examples: Parser.Eval(f_xs, xo, zo); 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 + 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 - ParserResult result = Parser.eval(f_xs, xo, yo); + ParserResult result = Parser.eval(f_xs, xo, yo); @@ -60,9 +60,9 @@ The last version supports expressions with complex numbers and multiple vars. He 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 + final Point xo = new Point("x", "2 +j"); //complex math expression in vars - ParserResult result = Parser.eval(f_x, xo); + ParserResult result = Parser.eval(f_x, xo); This version is compiled for Java 1.6 From 16adf86d71be93479c4a8352f9fe52bfecf5be85 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Wed, 23 Oct 2019 22:19:06 +0200 Subject: [PATCH 14/53] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 48f80fc..6c34140 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # 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 let you parse or evaluate math expressions. This algorithm does not use a decision tree. It is a recursive algorithm. @@ -50,7 +50,7 @@ Examples: --> execution time = 4ms in i7-6500U -In the test package you can see more examples with diferent constructors +In the test package you can see more examples with different constructors The last version supports expressions with complex numbers and multiple vars. Here an example: @@ -66,6 +66,8 @@ The last version supports expressions with complex numbers and multiple vars. He This version is compiled for Java 1.6 + +Also, you can visit https://github.com/sbesada/java.math.numerical.library that uses this library. Enjoy it!! From 3cf7ed27cdb1ebe636e34f27f04816cb113bc558 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 26 Oct 2019 22:23:10 +0200 Subject: [PATCH 15/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c34140..85ad338 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ The last version supports expressions with complex numbers and multiple vars. He This version is compiled for Java 1.6 -Also, you can visit https://github.com/sbesada/java.math.numerical.library that uses this library. +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 expressions. Enjoy it!! From 71b0eca44ad75d7ac867472c8f89dd9ac34aa28a Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 31 Oct 2019 22:51:07 +0100 Subject: [PATCH 16/53] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 85ad338..8f5311e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # java.math.expression.parser java math expression parser is a maven project that let 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 ascent parser (https://en.wikipedia.org/wiki/Recursive_ascent_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 needs 25% of the time to parse the same expression as JEP. With other algorithms that use trees like: @@ -15,8 +15,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m | 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: - https://pypi.org/project/pymep/ + 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. Examples: From 232774b9dd1e7168f56e35a035dec5ae095e51bc Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 31 Oct 2019 22:51:34 +0100 Subject: [PATCH 17/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f5311e..1bd4044 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # java.math.expression.parser java math expression parser is a maven project that let you parse or evaluate math expressions. -This algorithm does not use a decision tree. It is a kind of Recursive ascent parser (https://en.wikipedia.org/wiki/Recursive_ascent_parser). In fact, it is LR parser (Left-Right Parser) without backtracking. +This algorithm does not use a decision tree. It is a kind of Recursive Ascent Parser (https://en.wikipedia.org/wiki/Recursive_ascent_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 needs 25% of the time to parse the same expression as JEP. With other algorithms that use trees like: From 0acde58e9a524e10cc62a86849490d5e3b3c1e44 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 31 Oct 2019 22:56:27 +0100 Subject: [PATCH 18/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1bd4044..000204a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m | 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. + 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. Examples: From df1b48cd6a8e05ebc8f1cc198f9226b3eee17ced Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 31 Oct 2019 22:57:38 +0100 Subject: [PATCH 19/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 000204a..2b9cae9 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ The last version supports expressions with complex numbers and multiple vars. He This version is compiled for Java 1.6 -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 expressions. +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. Enjoy it!! From 1e1123c284f6cd55771fbb2a65afd1641613b82c Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 30 Nov 2019 20:24:18 +0100 Subject: [PATCH 20/53] Update README.md --- README.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2b9cae9..b512e97 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # java.math.expression.parser -java math expression parser is a maven project that let you parse or evaluate math expressions. +java math expression parser is a maven project that let you parse or evaluate math expressions and it is tested using matlab. This algorithm does not use a decision tree. It is a kind of Recursive Ascent Parser (https://en.wikipedia.org/wiki/Recursive_ascent_parser). In fact, it is LR parser (Left-Right Parser) without backtracking. @@ -16,8 +16,23 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m --------- --------- 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 + + - (...) -Examples: +## Examples: String f_x = "+3 +5*5*(+1)"; From 69775e48e5745e0b9abd1cca9ac13166dc1d81f0 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 30 Nov 2019 20:28:38 +0100 Subject: [PATCH 21/53] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index b512e97..3f8b658 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,15 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ### 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: From 20ca79431205f5c5dec635e9d59a690e10e1594b Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 30 Nov 2019 20:29:14 +0100 Subject: [PATCH 22/53] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3f8b658..7348de0 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,9 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m - 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") + 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: From 39fa1164fa1aeda65bde47865db309682da19dcb Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 30 Nov 2019 20:38:44 +0100 Subject: [PATCH 23/53] Update README.md --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7348de0..1fc10ad 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,8 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ## Examples: +## Real numbers + String f_x = "+3 +5*5*(+1)"; ParserResult result = Parser.eval(f_x); @@ -68,14 +70,17 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ParserResult result = Parser.eval(f_xs, xo, yo); - +## fast execution + final double result = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); --> execution time = 4ms in i7-6500U -In the test package you can see more examples with different constructors +- In the test package you can see more examples with different constructors + +### Complex numbers -The last version supports expressions with complex numbers and multiple vars. Here an example: +- The last version supports expressions with complex numbers and multiple vars. Here an example: String f_x = " e^(1*x*acos((3/2-2j)^(pi)))"; From 27b0828fb78bad053d7527b05f45edea2e995d1f Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 30 Nov 2019 20:40:21 +0100 Subject: [PATCH 24/53] Update README.md --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1fc10ad..3234080 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,10 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ## Examples: + + In the test package you can see more examples with different constructors -## Real numbers +### Real numbers String f_x = "+3 +5*5*(+1)"; @@ -70,17 +72,14 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ParserResult result = Parser.eval(f_xs, xo, yo); -## fast execution +### Fast execution final double result = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); --> execution time = 4ms in i7-6500U - -- In the test package you can see more examples with different constructors - ### Complex numbers -- The last version supports expressions with complex numbers and multiple vars. Here an example: +The last version supports expressions with complex numbers and multiple vars. Here an example: String f_x = " e^(1*x*acos((3/2-2j)^(pi)))"; From a36397d329c1c34b622b98e96918cbbba70a20a5 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 30 Nov 2019 20:46:22 +0100 Subject: [PATCH 25/53] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3234080..d76d3f2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # java.math.expression.parser -java math expression parser is a maven project that let you parse or evaluate math expressions and it is tested using matlab. +java math expression parser is a maven project that let you parse or evaluate math expressions. This algorithm does not use a decision tree. It is a kind of Recursive Ascent Parser (https://en.wikipedia.org/wiki/Recursive_ascent_parser). In fact, it is LR parser (Left-Right Parser) without backtracking. @@ -15,7 +15,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m | 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. + 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 From 16f41d83c0d1fd18377d2346a49e993598c2e654 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 30 Nov 2019 23:59:30 +0100 Subject: [PATCH 26/53] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index d76d3f2..cfca8b8 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,6 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ParserResult result = Parser.eval(f_xs, xo, yo); - -### Fast execution - final double result = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); --> execution time = 4ms in i7-6500U From b4b05ac08c254e13f84ce1f5a21c3176ff271ba9 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Fri, 13 Dec 2019 23:38:48 +0100 Subject: [PATCH 27/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cfca8b8..e51ee6f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # java.math.expression.parser -java math expression parser is a maven project that let you parse or evaluate 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 kind of Recursive Ascent Parser (https://en.wikipedia.org/wiki/Recursive_ascent_parser). In fact, it is LR parser (Left-Right Parser) without backtracking. From 7476f34c6abdc5b747a63c05dbe5adc6ed441127 Mon Sep 17 00:00:00 2001 From: sbesda Date: Mon, 3 Feb 2020 21:39:25 +0100 Subject: [PATCH 28/53] DES added documetation --- .../java/com/expression/parser/Parser.java | 157 ++++++++++-------- 1 file changed, 84 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/expression/parser/Parser.java b/src/main/java/com/expression/parser/Parser.java index 09fd62c..341f9cc 100644 --- a/src/main/java/com/expression/parser/Parser.java +++ b/src/main/java/com/expression/parser/Parser.java @@ -17,42 +17,83 @@ */ public class Parser { + /** - * Eval. + * Eval + * + * This a parser eval. The real parser of a function is within the Fuction * - * @param function the function - * @return the parser result + * FunctionX: functions with one var. Example 1+2*x --> it is more optimized + * FunctionXs: functions with several vars. Example: 1+2*x+3*y... + * ComplexFunction: Complex functions with several vars: one var or n vars. Example --> 1+x+y +j + * + * @param function the function: 1+2*x+j... + * @param values the values x=10, y=20 + * + * @return the parser result: complex or real value */ - public static ParserResult eval(final String function) { + public static ParserResult eval(final String function, final Point... values) { - ParserResult result = new ParserResult(); + final ParserResult result = new ParserResult(); FunctionX f_x = null; + FunctionXs f_xs = null; + ComplexFunction complexFunction = null; - if ((function != null) && !function.equals("")) { - try { + if ((function != null) && !function.isEmpty()) { - 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)); + if (Parser.pointIsComplex(values) || function.toLowerCase().contains("j")) { // Complex + - } else { - throw new CalculatorException("function is not well defined"); + 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(); } - } 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. * @@ -91,74 +132,44 @@ public static double eval(final String function, final String[] vars, final Doub } - /** + + /** * Eval. * * @param function the function - * @param values the values * @return the parser result */ - public static ParserResult eval(final String function, final Point... values) { + public static ParserResult eval(final String function) { - final ParserResult result = new ParserResult(); + 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 - // 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); - - 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())); - } + if ((function != null) && !function.equals("")) { + try { - } 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)); - } + if ((function.toLowerCase().contains("j") || function.toLowerCase().contains("i")) + && !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 { - 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(); - } + } catch (final CalculatorException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } + return result; - } + } + + /** * PointToValue. * From 4ec0fc55882ed3eb953dd0ff437771c99a4cc044 Mon Sep 17 00:00:00 2001 From: sbesda Date: Mon, 3 Feb 2020 21:56:21 +0100 Subject: [PATCH 29/53] DES added documetation --- .../java/com/expression/parser/Parser.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/expression/parser/Parser.java b/src/main/java/com/expression/parser/Parser.java index 341f9cc..6111a06 100644 --- a/src/main/java/com/expression/parser/Parser.java +++ b/src/main/java/com/expression/parser/Parser.java @@ -17,15 +17,16 @@ */ public class Parser { - /** * Eval - * - * This a parser eval. The real parser of a function is within the Fuction * - * FunctionX: functions with one var. Example 1+2*x --> it is more optimized + * This a parser eval. The real parser of a function is within the Fuction + * + * FunctionX: functions with one var. Example 1+2*x --> it is more optimized + * * FunctionXs: functions with several vars. Example: 1+2*x+3*y... - * ComplexFunction: Complex functions with several vars: one var or n vars. Example --> 1+x+y +j + * + * ComplexFunction: Complex functions with several vars: one var or n vars. Example: 1+x+y +j * * @param function the function: 1+2*x+j... * @param values the values x=10, y=20 @@ -42,7 +43,6 @@ public static ParserResult eval(final String function, final Point... values) { if ((function != null) && !function.isEmpty()) { if (Parser.pointIsComplex(values) || function.toLowerCase().contains("j")) { // Complex - complexFunction = new ComplexFunction(function); final List valuesList = pointToComplexValue(values); @@ -93,7 +93,6 @@ public static ParserResult eval(final String function, final Point... values) { return result; } - /** * Eval. * @@ -132,8 +131,7 @@ public static double eval(final String function, final String[] vars, final Doub } - - /** + /** * Eval. * * @param function the function @@ -149,7 +147,7 @@ public static ParserResult eval(final String function) { if ((function.toLowerCase().contains("j") || function.toLowerCase().contains("i")) && !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); @@ -168,8 +166,7 @@ public static ParserResult eval(final String function) { return result; } - - + /** * PointToValue. * From aed95df483307498236b4d60fb6d18b5386c1a83 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Mon, 3 Feb 2020 21:57:13 +0100 Subject: [PATCH 30/53] Update Parser.java --- src/main/java/com/expression/parser/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/expression/parser/Parser.java b/src/main/java/com/expression/parser/Parser.java index 6111a06..b0a3e34 100644 --- a/src/main/java/com/expression/parser/Parser.java +++ b/src/main/java/com/expression/parser/Parser.java @@ -20,7 +20,7 @@ public class Parser { /** * Eval * - * This a parser eval. The real parser of a function is within the Fuction + * This is a parser eval. The real parser of a function is within the Fuction * * FunctionX: functions with one var. Example 1+2*x --> it is more optimized * From c40a9f058957b1d37d7e98d95c82ec3cfe7f15e4 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Fri, 8 May 2020 11:43:19 +0200 Subject: [PATCH 31/53] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e51ee6f..4d0a976 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,9 @@ The last version supports expressions with complex numbers and multiple vars. He This version is compiled for Java 1.6 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. - -Enjoy it!! +## 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 -PD: If you think that my work deserves a donation, you can do it: https://sbesada.github.io/ +## Donation +If you think that my work deserves a donation, you can do it: https://sbesada.github.io/ From 2b388b7614b6db872e84c0861dca3a605ba9d698 Mon Sep 17 00:00:00 2001 From: sbesda Date: Fri, 18 Sep 2020 10:50:01 +0200 Subject: [PATCH 32/53] DES sin fuction returns complex value (only real part). fix it --- src/main/java/com/expression/parser/Parser.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/expression/parser/Parser.java b/src/main/java/com/expression/parser/Parser.java index b0a3e34..01344af 100644 --- a/src/main/java/com/expression/parser/Parser.java +++ b/src/main/java/com/expression/parser/Parser.java @@ -145,8 +145,7 @@ public static ParserResult eval(final String function) { if ((function != null) && !function.equals("")) { try { - if ((function.toLowerCase().contains("j") || function.toLowerCase().contains("i")) - && !function.toLowerCase().contains("x")) { + 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")) { From 4d46c4804a05c1554b768839a89741cb17ee7a44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 09:26:16 +0000 Subject: [PATCH 33/53] Bump junit from 4.12 to 4.13.1 Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3336b39..9d4da14 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ junit junit - 4.12 + 4.13.1 From d8b1c6e10d76cdd40a2fe331958a9848cfe30f99 Mon Sep 17 00:00:00 2001 From: sbesda Date: Sat, 5 Dec 2020 23:02:03 +0100 Subject: [PATCH 34/53] DES Version 3.0 --- .../java/com/expression/parser/Parser.java | 112 ++-- .../parser/function/ComplexFunction.java | 620 ++++-------------- .../expression/parser/function/Constants.java | 48 ++ .../expression/parser/function/FunctionX.java | 583 +++------------- .../parser/function/FunctionXs.java | 589 +++-------------- .../com/expression/parser/function/Test.java | 178 +++++ .../{Test_Complex.java => ComplexTest.java} | 8 +- .../parser/{Test_Real.java => RealTest.java} | 10 +- .../java/com/expression/parser/SpeedTest.java | 42 ++ 9 files changed, 669 insertions(+), 1521 deletions(-) create mode 100644 src/main/java/com/expression/parser/function/Constants.java create mode 100644 src/main/java/com/expression/parser/function/Test.java rename src/test/java/com/expression/parser/{Test_Complex.java => ComplexTest.java} (95%) rename src/test/java/com/expression/parser/{Test_Real.java => RealTest.java} (96%) create mode 100644 src/test/java/com/expression/parser/SpeedTest.java diff --git a/src/main/java/com/expression/parser/Parser.java b/src/main/java/com/expression/parser/Parser.java index 01344af..fecf9f5 100644 --- a/src/main/java/com/expression/parser/Parser.java +++ b/src/main/java/com/expression/parser/Parser.java @@ -18,18 +18,74 @@ public class Parser { /** - * Eval + * Simple eval. * - * This is a parser eval. The real parser of a function is within the Fuction + * function(fx) = 1 +2+ cos(0.5) * - * FunctionX: functions with one var. Example 1+2*x --> it is more optimized + * @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. * - * FunctionXs: functions with several vars. Example: 1+2*x+3*y... + * fx = 1 +2+ cos(0.5) --> real functions or fx = 1+j +cos(0.5) --> complex functions * - * ComplexFunction: Complex functions with several vars: one var or n vars. Example: 1+x+y +j + * @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 * - * @param function the function: 1+2*x+j... - * @param values the values x=10, y=20 * * @return the parser result: complex or real value */ @@ -96,17 +152,14 @@ public static ParserResult eval(final String function, final Point... values) { /** * Eval. * - * @param function the function - * @param vars the vars - * @param values the values - * @return the double + * 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.equals("")) { + if ((function != null) && !function.isEmpty()) { try { if ((((vars == null) || (vars.length < 1)) && (values == null)) || (values.length < 1)) { f_x = new FunctionX(function); @@ -131,41 +184,6 @@ public static double eval(final String function, final String[] vars, final Doub } - /** - * Eval. - * - * @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.equals("")) { - 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; - - } - /** * PointToValue. * diff --git a/src/main/java/com/expression/parser/function/ComplexFunction.java b/src/main/java/com/expression/parser/function/ComplexFunction.java index a0720fb..b5bc594 100644 --- a/src/main/java/com/expression/parser/function/ComplexFunction.java +++ b/src/main/java/com/expression/parser/function/ComplexFunction.java @@ -12,51 +12,6 @@ */ public class ComplexFunction { - /** 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"; - /** setup. */ public boolean degree = false; @@ -71,7 +26,7 @@ public class ComplexFunction { * @param f the f */ public ComplexFunction(final String f) { - this.f = f.trim().replaceAll(" ", ""); + this.f = f.trim().replaceAll(" ", "").toLowerCase(); degree = ParserManager.getInstance().isDeegre(); } @@ -105,9 +60,8 @@ public void setF(final String f) { 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()); + vars.add(string.trim().replaceAll(" ", "").toLowerCase()); } - return eval(f, values, vars); } @@ -120,9 +74,8 @@ public Complex getValue(final List values, final List variables * @return the complex * @throws CalculatorException the calculator exception */ - private Complex eval(String f, final List values, final List variables) + private Complex eval(final String f, final List values, final List variables) throws CalculatorException { - f = f.trim().toLowerCase(); Complex value = new Complex(0, 0); String number = ""; String function = ""; @@ -133,68 +86,78 @@ private Complex eval(String f, final List values, final List va for (int i = 0; i < f.length(); i++) { final char character = f.charAt(i); - switch (character) { - case '*': + + if (character >= '0' && character <= '9') { + + hasNumber = true; + number = 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 = nextFunction(f.substring(i + 1, f.length())); - value = Complex.mul(new Complex(numb, 0), eval(new_f, values, variables)); + 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 = nextFunction(f.substring(i + 1, f.length())); - value = Complex.mul(new Complex(0, numb), eval(new_f, values, variables)); + 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 = nextFunction(f.substring(i + 1, f.length())); - value = Complex.mul(eval(function, values, variables), eval(new_f, values, variables)); + 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 = nextFunction(f.substring(i + 1, f.length())); - value = Complex.mul(value, eval(new_f, values, variables)); + 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 '+': + + } 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)); + 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 = f.substring(i + 1, f.length()); - value = Complex.add(new Complex(0, numb), eval(new_f, values, variables)); + 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 = f.substring(i + 1, f.length()); - value = Complex.add(eval(function, values, variables), eval(new_f, values, variables)); + 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 = f.substring(i + 1, f.length()); - value = Complex.add(value, eval(new_f, values, variables)); + 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 '-': + } else if (character == '-') { if (hasNumber && !isImaginary) { final Double numb = new Double(number); @@ -224,8 +187,8 @@ private Complex eval(String f, final List values, final List va value = Complex.sub(value, eval(new_f, values, variables)); i = i + new_f.length(); } - break; - case '/': + + } else if (character == '/') { if (hasNumber && !isImaginary) { final Double numb = new Double(number); @@ -255,8 +218,8 @@ private Complex eval(String f, final List values, final List va value = Complex.div(value, eval(new_f, values, variables)); i = i + new_f.length(); } - break; - case '^': + + } else if (character == '^') { if (hasNumber && !isImaginary) { final Double numb = new Double(number); @@ -287,149 +250,54 @@ private Complex eval(String f, final List values, final List va 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 '.': + } else if (character == '.') { if (i == (f.length() - 1)) { throw new CalculatorException("The function is not well-formed"); } if (hasNumber && (number.length() > 0)) { number = number + character; } - break; - case '(': + + } 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 (function.equals(SIN)) { + if (function.equals(Constants.SIN)) { value = eval(new_f, values, variables).sin(); - } else if (function.equals(COS)) { + } else if (function.equals(Constants.COS)) { value = eval(new_f, values, variables).cos(); - } else if (function.equals(TAN)) { + } else if (function.equals(Constants.TAN)) { value = eval(new_f, values, variables).tan(); - } else if (function.equals(SINH)) { + } else if (function.equals(Constants.SINH)) { value = eval(new_f, values, variables).sinh(); - } else if (function.equals(COSH)) { + } else if (function.equals(Constants.COSH)) { value = eval(new_f, values, variables).cosh(); - } else if (function.equals(TANH)) { + } else if (function.equals(Constants.TANH)) { value = eval(new_f, values, variables).tanh(); - } else if (function.equals(ASIN)) { + } else if (function.equals(Constants.ASIN)) { value = eval(new_f, values, variables).asin(); - } else if (function.equals(ACOS)) { + } else if (function.equals(Constants.ACOS)) { value = eval(new_f, values, variables).acos(); - } else if (function.equals(ATAN)) { + } else if (function.equals(Constants.ATAN)) { value = eval(new_f, values, variables).atan(); - } else if (function.equals(LN)) { + } else if (function.equals(Constants.LN)) { value = eval(new_f, values, variables).log(); - } else if (function.equals(LOG)) { + } else if (function.equals(Constants.LOG)) { value = eval(new_f, values, variables).log10(); - } else if (function.equals(SQRT)) { + } else if (function.equals(Constants.SQRT)) { value = eval(new_f, values, variables).sqrt(); - } else if (function.equals(CBRT)) { + } else if (function.equals(Constants.CBRT)) { value = Complex.cbrt(eval(new_f, values, variables)); } else { throw new CalculatorException("The function is not well-formed"); @@ -443,14 +311,12 @@ private Complex eval(String f, final List values, final List va } i = i + new_f.length() + 1; - break; - case ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - case ' ': - break; + } else if (character == ' ') { - case 'i': + } else if (character == 'i') { if (!hasFunction) { if (hasNumber) { @@ -468,10 +334,9 @@ private Complex eval(String f, final List values, final List va if (i == (f.length() - 1)) { - if (function.equals(E)) { + if (function.equals(Constants.E)) { value = new Complex(Math.E, 0); - - } else if (function.equals(PI)) { + } else if (function.equals(Constants.PI)) { value = new Complex(Math.PI, 0); } else { if (function.length() == 1) { @@ -486,14 +351,10 @@ private Complex eval(String f, final List values, final List va throw new CalculatorException("function is not well defined"); } } - } - - break; } - break; - case 'j': + } else if (character == 'j') { if (!hasFunction) { if (hasNumber) { value = new Complex(0, new Double(number)); @@ -508,10 +369,9 @@ private Complex eval(String f, final List values, final List va if (i == (f.length() - 1)) { - if (function.equals(E)) { + if (function.equals(Constants.E)) { value = new Complex(Math.E, 0); - - } else if (function.equals(PI)) { + } else if (function.equals(Constants.PI)) { value = new Complex(Math.PI, 0); } else { if (function.length() == 1) { @@ -528,47 +388,39 @@ private Complex eval(String f, final List values, final List va } } - - break; } - break; - default: - if (isValidCharacter(character)) { - function = function + character; - hasFunction = true; - if (i == (f.length() - 1)) { + } else if (isValidCharacter(character)) { + function = function + character; + hasFunction = true; - if (function.equals(E)) { - value = new Complex(Math.E, 0); + if (i == (f.length() - 1)) { - } 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"); - } + if (function.equals(Constants.E)) { + value = new Complex(Math.E, 0); + } else if (function.equals(Constants.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; + } else { + throw new CalculatorException("Invalid character:" + character); } - } return value; + } /** @@ -578,56 +430,34 @@ private Complex eval(String f, final List values, final List va * @return the string * @throws CalculatorException the calculator exception */ - private String nextFunction(String f) throws CalculatorException { + private String nextFunction(final 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 '+': + if (character == '+' || character == '*' || character == '-' || character == '/') { i = f.length(); - break; - case '-': - i = f.length(); - break; - case '^': + } else if (character == '^') { result = result + character; - break; - case '.': + } else if (character == '.') { result = result + character; - break; - case '(': - + } else if (character == '(') { final String new_f = f.substring(i, nextBracket(f) + 1); result = result + new_f; i = (i + new_f.length()) - 1; - - break; - case ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - - case ' ': + } else if (character == ' ') { result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; + } else if (isValidNumericAndCharacter(character)) { + result = result + character; + } else { + throw new CalculatorException("Invalid character:" + character); } } return result; + } /** @@ -637,54 +467,38 @@ private String nextFunction(String f) throws CalculatorException { * @return the string * @throws CalculatorException the calculator exception */ - private String nextMinusFunction(String f) throws CalculatorException { + private String nextMinusFunction(final 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 '+': + if (character == '+') { i = f.length(); - break; - case '-': + } else if (character == '*') { + result = result + character; + } else if (character == '-') { i = f.length(); - break; - case '^': + } else if (character == '/') { result = result + character; - break; - case '.': + } else if (character == '^') { result = result + character; - break; - case '(': - + } else if (character == '.') { + result = result + character; + } else if (character == '(') { final String new_f = f.substring(i, nextBracket(f) + 1); result = result + new_f; i = (i + new_f.length()) - 1; - - break; - case ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - - case ' ': + } else if (character == ' ') { result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; + } else if (isValidNumericAndCharacter(character)) { + result = result + character; + } else { + throw new CalculatorException("Invalid character:" + character); } + } return result; } @@ -697,91 +511,9 @@ private String nextMinusFunction(String f) throws CalculatorException { */ 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': + if ((character >= 'a' && character <= 'z')) { 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; } @@ -793,121 +525,9 @@ private boolean isValidCharacter(final char character) { */ 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': + if ((character >= 'a' && character <= 'z') || (character >= '0' && character <= '9')) { 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; } @@ -923,21 +543,17 @@ private int nextBracket(final String f) throws CalculatorException { int count = 0; for (int i = 0; i < f.length(); i++) { final char character = f.charAt(i); - switch (character) { - case '(': + if (character == '(') { result = i; count++; - break; - case ')': + } else if (character == ')') { result = i; count--; if (count == 0) { return i; } - break; - default: + } else { result = i; - break; } } 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 be8328d..6092973 100644 --- a/src/main/java/com/expression/parser/function/FunctionX.java +++ b/src/main/java/com/expression/parser/function/FunctionX.java @@ -8,51 +8,6 @@ */ public class FunctionX { - /** 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"; - /** setup. */ private boolean degree = false; @@ -65,7 +20,7 @@ public class FunctionX { * @param f_x f(x) */ public FunctionX(final String f_x) { - this.f_x = f_x.trim().replaceAll(" ", ""); + this.f_x = f_x.trim().replaceAll(" ", "").toLowerCase(); degree = ParserManager.getInstance().isDeegre(); } @@ -95,7 +50,6 @@ public void setF_x(final String f_x) { * @throws CalculatorException the calculator exception */ public double getF_xo(final double xo) throws CalculatorException { - return eval(f_x, xo); } @@ -107,8 +61,7 @@ public double getF_xo(final double xo) throws CalculatorException { * @return the double * @throws CalculatorException the calculator exception */ - private double eval(String f_x, final double xi) throws CalculatorException { - f_x = f_x.trim().toLowerCase(); + private double eval(final String f_x, final double xi) throws CalculatorException { double value = 0; String number = ""; String function = ""; @@ -117,51 +70,60 @@ private double eval(String f_x, final double xi) throws CalculatorException { for (int i = 0; i < f_x.length(); i++) { final char character = f_x.charAt(i); - switch (character) { - case '*': + + if (character >= '0' && character <= '9') { + + hasNumber = true; + number = 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 = nextFunction(f_x.substring(i + 1, f_x.length())); - value = numb * eval(new_f_x, xi); + 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 = nextFunction(f_x.substring(i + 1, f_x.length())); - value = eval(function, xi) * eval(new_f_x, xi); + 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 = nextFunction(f_x.substring(i + 1, f_x.length())); - value = value * eval(new_f_x, xi); + 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 '+': + + } 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); + 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 = f_x.substring(i + 1, f_x.length()); - value = eval(function, xi) + eval(new_f_x, xi); + 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 = f_x.substring(i + 1, f_x.length()); - value = value + eval(new_f_x, xi); + 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 '-': + } else if (character == '-') { if (hasNumber) { final Double numb = new Double(number); @@ -176,14 +138,13 @@ private double eval(String f_x, final double xi) throws CalculatorException { 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 '/': + + } else if (character == '/') { if (hasNumber) { final Double numb = new Double(number); @@ -198,14 +159,13 @@ private double eval(String f_x, final double xi) throws CalculatorException { 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 '^': + + } else if (character == '^') { if (hasNumber) { final Double numb = new Double(number); @@ -220,177 +180,86 @@ private double eval(String f_x, final double xi) throws CalculatorException { 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; - } + } else if (character == '.') { - 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 '(': + + } 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 (function.equals(SIN)) { + if (function.equals(Constants.SIN)) { + if (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)) { + } else if (function.equals(Constants.COS)) { + if (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)) { + + } else if (function.equals(Constants.TAN)) { + if (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)) { + } else if (function.equals(Constants.SINH)) { value = Math.sinh(eval(new_f_x, xi)); - } else if (function.equals(COSH)) { + } else if (function.equals(Constants.COSH)) { value = Math.cosh(eval(new_f_x, xi)); - } else if (function.equals(TANH)) { + } else if (function.equals(Constants.TANH)) { value = Math.tanh(eval(new_f_x, xi)); - } else if (function.equals(ASIN)) { + } else if (function.equals(Constants.ASIN)) { if (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)) { + } else if (function.equals(Constants.ACOS)) { if (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)) { + } else if (function.equals(Constants.ATAN)) { if (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)) { + } else if (function.equals(Constants.LN)) { value = Math.log(eval(new_f_x, xi)); - } else if (function.equals(LOG)) { + } else if (function.equals(Constants.LOG)) { value = Math.log10(eval(new_f_x, xi)); - } else if (function.equals(SQRT)) { + } else if (function.equals(Constants.SQRT)) { value = Math.sqrt(eval(new_f_x, xi)); - } else if (function.equals(CBRT)) { + } else if (function.equals(Constants.CBRT)) { value = Math.cbrt(eval(new_f_x, xi)); } else { throw new CalculatorException("The function is not well-formed"); @@ -404,43 +273,33 @@ private double eval(String f_x, final double xi) throws CalculatorException { } i = i + new_f_x.length() + 1; - break; - case ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - case ' ': - break; - default: - if (isValidCharacter(character)) { - function = function + character; - hasFunction = true; - - if (i == (f_x.length() - 1)) { + } else if (character == ' ') { - 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 if (isValidCharacter(character)) { + function = function + character; + hasFunction = true; + if (i == (f_x.length() - 1)) { + if (function.equals(Constants.E)) { + value = Math.E; + } else if (function.equals(Constants.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; + } else { + throw new CalculatorException("Invalid character:" + character); } } return value; + } /** @@ -457,46 +316,25 @@ private String nextFunction(String f_x) throws CalculatorException { for (int i = 0; i < f_x.length(); i++) { final char character = f_x.charAt(i); - switch (character) { - case '*': + if (character == '+' || character == '*' || character == '-' || character == '/') { i = f_x.length(); - break; - case '/': - i = f_x.length(); - break; - case '+': - i = f_x.length(); - break; - case '-': - i = f_x.length(); - break; - case '^': + } else if (character == '^') { result = result + character; - break; - case '.': + } else if (character == '.') { result = result + character; - break; - case '(': - + } else if (character == '(') { 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 ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - case ' ': + } else if (character == ' ') { result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; + } else if (isValidNumericAndCharacter(character)) { + result = result + character; + } else { + throw new CalculatorException("Invalid character:" + character); } } return result; @@ -509,53 +347,35 @@ private String nextFunction(String f_x) throws CalculatorException { * @return the string * @throws CalculatorException the calculator exception */ - private String nextMinusFunction(String f_x) throws CalculatorException { + private String nextMinusFunction(final 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 '+': + if (character == '+') { i = f_x.length(); - break; - case '-': + } else if (character == '*') { + result = result + character; + } else if (character == '-') { i = f_x.length(); - break; - case '^': + } else if (character == '/') { result = result + character; - break; - case '.': + } else if (character == '^') { result = result + character; - break; - case '(': - + } else if (character == '.') { + result = result + character; + } else if (character == '(') { 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 ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - - case ' ': + } else if (character == ' ') { result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; + } else if (isValidNumericAndCharacter(character)) { + result = result + character; + } else { + throw new CalculatorException("Invalid character:" + character); } } return result; @@ -569,91 +389,9 @@ private String nextMinusFunction(String f_x) throws CalculatorException { */ 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': + if ((character >= 'a' && character <= 'z')) { 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; } @@ -665,121 +403,9 @@ private boolean isValidCharacter(final char character) { */ 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': + if ((character >= 'a' && character <= 'z') || (character >= '0' && character <= '9')) { 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; } @@ -795,21 +421,18 @@ private int nextBracket(final String f_x) throws CalculatorException { int count = 0; for (int i = 0; i < f_x.length(); i++) { final char character = f_x.charAt(i); - switch (character) { - case '(': + if (character == '(') { result = i; count++; - break; - case ')': + } else if (character == ')') { result = i; count--; if (count == 0) { return i; } - break; - default: + + } else { result = i; - break; } } diff --git a/src/main/java/com/expression/parser/function/FunctionXs.java b/src/main/java/com/expression/parser/function/FunctionXs.java index bc4cbfe..384ef79 100644 --- a/src/main/java/com/expression/parser/function/FunctionXs.java +++ b/src/main/java/com/expression/parser/function/FunctionXs.java @@ -11,51 +11,6 @@ */ public class FunctionXs { - /** 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"; - /** setup. */ public boolean degree = false; @@ -70,9 +25,8 @@ public class FunctionXs { * @param f the f */ public FunctionXs(final String f) { - this.f = f.trim().replaceAll(" ", ""); + this.f = f.trim().replaceAll(" ", "").toLowerCase(); degree = ParserManager.getInstance().isDeegre(); - } /** @@ -104,9 +58,8 @@ public void setF(final String f) { 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()); + vars.add(string.trim().replaceAll(" ", "").toLowerCase()); } - return eval(f, values, vars); } @@ -119,8 +72,8 @@ public double getValue(final List values, final List variables) * @return the double * @throws CalculatorException the calculator exception */ - private double eval(String f, final List values, final List variables) throws CalculatorException { - f = f.trim().toLowerCase(); + private double eval(final String f, final List values, final List variables) + throws CalculatorException { double value = 0; String number = ""; String function = ""; @@ -129,51 +82,61 @@ private double eval(String f, final List values, final List vari for (int i = 0; i < f.length(); i++) { final char character = f.charAt(i); - switch (character) { - case '*': + + if (character >= '0' && character <= '9') { + + hasNumber = true; + number = 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 = nextFunction(f.substring(i + 1, f.length())); - value = numb * eval(new_f, values, variables); + 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 = nextFunction(f.substring(i + 1, f.length())); - value = eval(function, values, variables) * eval(new_f, values, variables); + 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 = nextFunction(f.substring(i + 1, f.length())); - value = value * eval(new_f, values, variables); + final String new_f = f.substring(i + 1, f.length()); + value = value + eval(new_f, values, variables); i = i + new_f.length(); } - break; - case '+': + + } 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); + 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 = f.substring(i + 1, f.length()); - value = eval(function, values, variables) + eval(new_f, values, variables); + 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 = f.substring(i + 1, f.length()); - value = value + eval(new_f, values, variables); + 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 '-': + } else if (character == '-') { if (hasNumber) { final Double numb = new Double(number); @@ -194,8 +157,8 @@ private double eval(String f, final List values, final List vari value = value - eval(new_f, values, variables); i = i + new_f.length(); } - break; - case '/': + + } else if (character == '/') { if (hasNumber) { final Double numb = new Double(number); @@ -216,8 +179,8 @@ private double eval(String f, final List values, final List vari value = value / eval(new_f, values, variables); i = i + new_f.length(); } - break; - case '^': + + } else if (character == '^') { if (hasNumber) { final Double numb = new Double(number); @@ -239,170 +202,75 @@ private double eval(String f, final List values, final List vari 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 '.': + } else if (character == '.') { if (i == (f.length() - 1)) { throw new CalculatorException("The function is not well-formed"); } if (hasNumber && (number.length() > 0)) { number = number + character; } - break; - case '(': + + } 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 (function.equals(SIN)) { + if (function.equals(Constants.SIN)) { if (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)) { + } else if (function.equals(Constants.COS)) { if (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)) { + } else if (function.equals(Constants.TAN)) { if (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)) { + } else if (function.equals(Constants.SINH)) { value = Math.sinh(eval(new_f, values, variables)); - } else if (function.equals(COSH)) { + } else if (function.equals(Constants.COSH)) { value = Math.cosh(eval(new_f, values, variables)); - } else if (function.equals(TANH)) { + } else if (function.equals(Constants.TANH)) { value = Math.tanh(eval(new_f, values, variables)); - } else if (function.equals(ASIN)) { + } else if (function.equals(Constants.ASIN)) { if (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)) { + } else if (function.equals(Constants.ACOS)) { if (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)) { + } else if (function.equals(Constants.ATAN)) { if (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)) { + } else if (function.equals(Constants.LN)) { value = Math.log(eval(new_f, values, variables)); - } else if (function.equals(LOG)) { + } else if (function.equals(Constants.LOG)) { value = Math.log10(eval(new_f, values, variables)); - } else if (function.equals(SQRT)) { + } else if (function.equals(Constants.SQRT)) { value = Math.sqrt(eval(new_f, values, variables)); - } else if (function.equals(CBRT)) { + } else if (function.equals(Constants.CBRT)) { value = Math.cbrt(eval(new_f, values, variables)); } else { throw new CalculatorException("The function is not well-formed"); @@ -416,48 +284,39 @@ private double eval(String f, final List values, final List vari } i = i + new_f.length() + 1; - break; - case ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - case ' ': - break; - default: - if (isValidCharacter(character)) { - function = function + character; - hasFunction = true; + } else if (character == ' ') { - if (i == (f.length() - 1)) { + } else if (isValidCharacter(character)) { + function = function + character; + hasFunction = true; - 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"); - } + if (i == (f.length() - 1)) { + if (function.equals(Constants.E)) { + value = Math.E; + } else if (function.equals(Constants.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; + } else { + throw new CalculatorException("Invalid character:" + character); } - } return value; } @@ -469,53 +328,30 @@ private double eval(String f, final List values, final List vari * @return the string * @throws CalculatorException the calculator exception */ - private String nextFunction(String f) throws CalculatorException { + private String nextFunction(final 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 '*': + if (character == '+' || character == '*' || character == '-' || character == '/') { i = f.length(); - break; - case '/': - i = f.length(); - break; - case '+': - i = f.length(); - break; - case '-': - i = f.length(); - break; - case '^': + } else if (character == '^') { result = result + character; - break; - case '.': + } else if (character == '.') { result = result + character; - break; - case '(': - + } else if (character == '(') { final String new_f = f.substring(i, nextBracket(f) + 1); result = result + new_f; i = (i + new_f.length()) - 1; - - break; - case ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - - case ' ': + } else if (character == ' ') { result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; + } else if (isValidNumericAndCharacter(character)) { + result = result + character; + } else { + throw new CalculatorException("Invalid character:" + character); } } return result; @@ -535,49 +371,34 @@ private String nextMinusFunction(String f) throws CalculatorException { 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 '+': + if (character == '+') { i = f.length(); - break; - case '-': + } else if (character == '*') { + result = result + character; + } else if (character == '-') { i = f.length(); - break; - case '^': + } else if (character == '/') { result = result + character; - break; - case '.': + } else if (character == '^') { result = result + character; - break; - case '(': - + } else if (character == '.') { + result = result + character; + } else if (character == '(') { final String new_f = f.substring(i, nextBracket(f) + 1); result = result + new_f; i = (i + new_f.length()) - 1; - - break; - case ')': + } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - - case ' ': + } else if (character == ' ') { result = result + character; - break; - - default: - if (isValidNumericAndCharacter(character)) { - result = result + character; - } else { - throw new CalculatorException("Invalid character"); - } - break; + } else if (isValidNumericAndCharacter(character)) { + result = result + character; + } else { + throw new CalculatorException("Invalid character:" + character); } } return result; + } /** @@ -588,91 +409,9 @@ private String nextMinusFunction(String f) throws CalculatorException { */ 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': + if ((character >= 'a' && character <= 'z')) { 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; } @@ -684,121 +423,9 @@ private boolean isValidCharacter(final char character) { */ 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': + if ((character >= 'a' && character <= 'z') || (character >= '0' && character <= '9')) { 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; } @@ -814,21 +441,17 @@ private int nextBracket(final String f) throws CalculatorException { int count = 0; for (int i = 0; i < f.length(); i++) { final char character = f.charAt(i); - switch (character) { - case '(': + if (character == '(') { result = i; count++; - break; - case ')': + } else if (character == ')') { result = i; count--; if (count == 0) { return i; } - break; - default: + } else { result = i; - break; } } diff --git a/src/main/java/com/expression/parser/function/Test.java b/src/main/java/com/expression/parser/function/Test.java new file mode 100644 index 0000000..2c73ba0 --- /dev/null +++ b/src/main/java/com/expression/parser/function/Test.java @@ -0,0 +1,178 @@ +package com.expression.parser.function; + +public class Test { + public static void main(final String[] args) { + + final long time1 = System.currentTimeMillis(); + for (int i = 0; i < 10000000; i++) { + + final char character = 'k'; + + isValidNumericAndCharacter3(character); + } + + final long time2 = System.currentTimeMillis(); + System.out.println("time:" + (time2 - time1)); + } + + private static 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; + } + + private static boolean isValidNumericAndCharacter2(final char character) { + boolean result = false; + if ((character >= 'a' && character <= 'z') || (character >= '1' && character <= '9')) { + result = true; + } + + return result; + + } + + private static boolean isValidNumericAndCharacter3(final char character) { + boolean result = false; + + if (character == 'a') { + result = true; + } else if (character == 'b') { + result = true; + } else if (character == 'c') { + result = true; + } else if (character == 'd') { + result = true; + } else if (character == 'e') { + result = true; + } else if (character == 'f') { + result = true; + } else if (character == 'g') { + result = true; + } else if (character == 'h') { + result = true; + } else if (character == 'i') { + result = true; + } else if (character == 'j') { + result = true; + } else if (character == 'k') { + result = true; + } + + return result; + + } +} diff --git a/src/test/java/com/expression/parser/Test_Complex.java b/src/test/java/com/expression/parser/ComplexTest.java similarity index 95% rename from src/test/java/com/expression/parser/Test_Complex.java rename to src/test/java/com/expression/parser/ComplexTest.java index 2700f2b..e4007c3 100644 --- a/src/test/java/com/expression/parser/Test_Complex.java +++ b/src/test/java/com/expression/parser/ComplexTest.java @@ -6,10 +6,10 @@ import com.expression.parser.util.ParserResult; import com.expression.parser.util.Point; -public class Test_Complex { +public class ComplexTest { @Test - public void Test_one() { + public void TestOne() { // TODO Auto-generated method stub @@ -122,7 +122,7 @@ public void Test_one() { } @Test - public void Test_two() { + public void TestTwo() { final Point xo = new Point("x", new Complex(1, 2)); @@ -156,7 +156,7 @@ public void Test_two() { } @Test - public void Test_three() { + public void TestThree() { String f_x = "1+j +x"; final Point xo = new Point("x", "2 +j"); diff --git a/src/test/java/com/expression/parser/Test_Real.java b/src/test/java/com/expression/parser/RealTest.java similarity index 96% rename from src/test/java/com/expression/parser/Test_Real.java rename to src/test/java/com/expression/parser/RealTest.java index 9140f8d..aaa3e6a 100644 --- a/src/test/java/com/expression/parser/Test_Real.java +++ b/src/test/java/com/expression/parser/RealTest.java @@ -7,10 +7,10 @@ import com.expression.parser.util.ParserResult; import com.expression.parser.util.Point; -public class Test_Real { +public class RealTest { @Test - public void Test_one() { + public void TestOne() { String f_x = " (2)-(5)"; @@ -63,7 +63,7 @@ public void Test_one() { } @Test - public void Test_two() { + public void TestTwo() { String f_x = " (2)-(5)"; @@ -97,7 +97,7 @@ public void Test_two() { } @Test - public void Test_three() { + public void TestThree() { String f_x = "+3 +5*5*(+1)"; @@ -126,7 +126,7 @@ public void Test_three() { } @Test - public void Test_four() { + public void TestFour() { String f_xs = "x+5*y+(3 -y)"; final Point xo = new Point("x", "1+1"); 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..7444eaa --- /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 < 100000; 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)); + + } +} From d51c829d601fd705bad5dc4ae4e6e9027f1d70fc Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 5 Dec 2020 23:18:01 +0100 Subject: [PATCH 35/53] Update README.md Version 3.0 --- README.md | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 4d0a976..e31c36a 100644 --- a/README.md +++ b/README.md @@ -47,23 +47,24 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ### 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); + 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); + result = Parser.eval(f_x, xo); --> for real or complex functions with real or complex vars assertTrue(result.getValue() == 0.2339992213289606); - 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); + Parser.Eval(f_xs, xo, zo); --> multiple vars String f_xs = "x+5*y+(3 -y)"; final Point xo = new Point("x", "1+1"); @@ -71,16 +72,13 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ParserResult result = Parser.eval(f_xs, xo, yo); - final double result = Parser.eval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4", null, null); - --> execution time = 4ms in i7-6500U - + + ### Complex numbers - -The last version supports expressions with complex numbers and multiple vars. Here an example: - - String f_x = " e^(1*x*acos((3/2-2j)^(pi)))"; - Point xo = new Point("x", new Complex(1, 2)); + 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"; @@ -88,6 +86,18 @@ The last version supports expressions with complex numbers and multiple vars. He 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: execute once the expression: 4ms + test 2: execute 100000 times: 2100 ms --> mean time 0.021 ms per execution + test 3: execute one million times: 16500 ms --> mean time 0.0165 ms per execution + This version is compiled for Java 1.6 From aec48aebe808cdadad65325d70ae1c14e260fbc4 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 5 Dec 2020 23:19:25 +0100 Subject: [PATCH 36/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e31c36a..2b2a978 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ### Complex numbers - String f_x = " e^(1*x*acos((3/2-2j)^(pi)))"; + 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); From 021a041c850400c3761630113c7a6c3bc72f4c75 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 5 Dec 2020 23:20:27 +0100 Subject: [PATCH 37/53] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b2a978..5686644 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,8 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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"); + 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 From 8b23328134a7098a5481a6a16de00a0f594a4fb2 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 5 Dec 2020 23:20:57 +0100 Subject: [PATCH 38/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5686644..4122fbb 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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"); + 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 From d9b3a854c4e980b2c35674d5a6e096239d2bd5ee Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sat, 5 Dec 2020 23:22:49 +0100 Subject: [PATCH 39/53] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4122fbb..97dc03d 100644 --- a/README.md +++ b/README.md @@ -95,9 +95,9 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m CPU: i7-6500U - test 1: execute once the expression: 4ms - test 2: execute 100000 times: 2100 ms --> mean time 0.021 ms per execution - test 3: execute one million times: 16500 ms --> mean time 0.0165 ms per execution + test 1: one execution: 4ms + test 2: 100000 executions : 2100 ms --> mean time 0.021 ms per execution + test 3: million executions: 16500 ms --> mean time 0.0165 ms per execution This version is compiled for Java 1.6 From 1a9434f1a5582c6556636bd064d04d216d2eb80d Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Sun, 6 Dec 2020 00:28:16 +0100 Subject: [PATCH 40/53] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 97dc03d..51b34e8 100644 --- a/README.md +++ b/README.md @@ -90,8 +90,8 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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"); + 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 From 3d987e74c27c834b316bd7183876018ac9e1d9f5 Mon Sep 17 00:00:00 2001 From: sbesda Date: Tue, 22 Dec 2020 17:40:48 +0100 Subject: [PATCH 41/53] DES SimpleEval to simpleEval --- src/main/java/com/expression/parser/Parser.java | 2 +- src/test/java/com/expression/parser/SpeedTest.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/expression/parser/Parser.java b/src/main/java/com/expression/parser/Parser.java index fecf9f5..6c22dd7 100644 --- a/src/main/java/com/expression/parser/Parser.java +++ b/src/main/java/com/expression/parser/Parser.java @@ -25,7 +25,7 @@ public class Parser { * @param function the function * @return the double */ - public static double SimpleEval(final String function) { + public static double simpleEval(final String function) { double result = 0; FunctionX f_x = null; diff --git a/src/test/java/com/expression/parser/SpeedTest.java b/src/test/java/com/expression/parser/SpeedTest.java index 7444eaa..8be74eb 100644 --- a/src/test/java/com/expression/parser/SpeedTest.java +++ b/src/test/java/com/expression/parser/SpeedTest.java @@ -8,7 +8,7 @@ public class SpeedTest { public void testOne() { final long time1 = System.currentTimeMillis(); - Parser.SimpleEval( + 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)); @@ -21,7 +21,7 @@ public void testTwo() { final long time1 = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { - Parser.SimpleEval( + 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"); } @@ -34,7 +34,7 @@ public void testTwo() { 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"); + 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)); From f56a9fa58479663f4d09cbd1d251c788e7e68d26 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Tue, 22 Dec 2020 17:42:40 +0100 Subject: [PATCH 42/53] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 51b34e8..677e255 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m ### Real numbers - Parser.SimpleEval("6.5*7.8^2.3 + (3.5^3+7/2)^3 -(5*4/(2-3))*4"); --> for real functions + 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)"; @@ -64,7 +64,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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 + Parser.eval(f_xs, xo, zo); --> multiple vars String f_xs = "x+5*y+(3 -y)"; final Point xo = new Point("x", "1+1"); @@ -90,7 +90,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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 + 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 From 97e1d7a16324f8bc11d3f63c2b13e204767d9b09 Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Mon, 28 Dec 2020 20:51:29 +0100 Subject: [PATCH 43/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 677e255..6f9f289 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m test 1: one execution: 4ms test 2: 100000 executions : 2100 ms --> mean time 0.021 ms per execution - test 3: million executions: 16500 ms --> mean time 0.0165 ms per execution + test 3: one million executions: 16500 ms --> mean time 0.0165 ms per execution This version is compiled for Java 1.6 From 604ebc6a5aa0c0c5a38a8b2aaff6a63b798b420e Mon Sep 17 00:00:00 2001 From: sbesda Date: Sat, 9 Jan 2021 10:50:49 +0100 Subject: [PATCH 44/53] pom to version 3.0.0 --- pom.xml | 2 +- .../com/expression/parser/function/Test.java | 178 ------------------ 2 files changed, 1 insertion(+), 179 deletions(-) delete mode 100644 src/main/java/com/expression/parser/function/Test.java diff --git a/pom.xml b/pom.xml index 9d4da14..4f5b566 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.expression.parser com.expression.parser jar - 2.0.0 + 3.0.0 com.expression.parser diff --git a/src/main/java/com/expression/parser/function/Test.java b/src/main/java/com/expression/parser/function/Test.java deleted file mode 100644 index 2c73ba0..0000000 --- a/src/main/java/com/expression/parser/function/Test.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.expression.parser.function; - -public class Test { - public static void main(final String[] args) { - - final long time1 = System.currentTimeMillis(); - for (int i = 0; i < 10000000; i++) { - - final char character = 'k'; - - isValidNumericAndCharacter3(character); - } - - final long time2 = System.currentTimeMillis(); - System.out.println("time:" + (time2 - time1)); - } - - private static 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; - } - - private static boolean isValidNumericAndCharacter2(final char character) { - boolean result = false; - if ((character >= 'a' && character <= 'z') || (character >= '1' && character <= '9')) { - result = true; - } - - return result; - - } - - private static boolean isValidNumericAndCharacter3(final char character) { - boolean result = false; - - if (character == 'a') { - result = true; - } else if (character == 'b') { - result = true; - } else if (character == 'c') { - result = true; - } else if (character == 'd') { - result = true; - } else if (character == 'e') { - result = true; - } else if (character == 'f') { - result = true; - } else if (character == 'g') { - result = true; - } else if (character == 'h') { - result = true; - } else if (character == 'i') { - result = true; - } else if (character == 'j') { - result = true; - } else if (character == 'k') { - result = true; - } - - return result; - - } -} From 7310e0c596df1916abe8696001316a079c9a9bde Mon Sep 17 00:00:00 2001 From: sbesda Date: Fri, 9 Apr 2021 19:34:27 +0200 Subject: [PATCH 45/53] New version 3.2 --- pom.xml | 2 +- .../parser/function/ComplexFunction.java | 131 +++++++------- .../expression/parser/function/FunctionX.java | 170 ++++++++---------- .../parser/function/FunctionXs.java | 159 ++++++++-------- 4 files changed, 216 insertions(+), 246 deletions(-) diff --git a/pom.xml b/pom.xml index 4f5b566..fa9967b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.expression.parser com.expression.parser jar - 3.0.0 + 3.2.0 com.expression.parser diff --git a/src/main/java/com/expression/parser/function/ComplexFunction.java b/src/main/java/com/expression/parser/function/ComplexFunction.java index b5bc594..05194d6 100644 --- a/src/main/java/com/expression/parser/function/ComplexFunction.java +++ b/src/main/java/com/expression/parser/function/ComplexFunction.java @@ -6,7 +6,6 @@ import com.expression.parser.ParserManager; import com.expression.parser.exception.CalculatorException; -// TODO: Auto-generated Javadoc /** * The Class ComplexFunction. */ @@ -90,7 +89,7 @@ private Complex eval(final String f, final List values, final List= '0' && character <= '9') { hasNumber = true; - number = number + character; + number += character; if (i == (f.length() - 1)) { value = new Complex(new Double(number), 0); number = ""; @@ -103,28 +102,28 @@ private Complex eval(final String f, final List values, final List values, final List values, final List values, final List values, final List values, final List values, final List values, final List values, final List values, final List 0)) { - number = number + character; + number += character; } } else if (character == '(') { @@ -265,39 +264,39 @@ private Complex eval(final String f, final List values, final List values, final List values, final List values, final List values, final List= '0' && character <= '9') { hasNumber = true; - number = number + character; + number += character; if (i == (f_x.length() - 1)) { value = new Double(number).doubleValue(); number = ""; @@ -87,19 +87,19 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio 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(); + 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(); + 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(); + i += new_f_x.length(); } } else if (character == '*') { @@ -108,19 +108,19 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio 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(); + 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(); + 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(); + i += new_f_x.length(); } } else if (character == '-') { @@ -129,19 +129,19 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio 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(); + 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(); + 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(); + i += new_f_x.length(); } } else if (character == '/') { @@ -150,19 +150,19 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio 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(); + 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(); + 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(); + i += new_f_x.length(); } } else if (character == '^') { @@ -170,20 +170,20 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio 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(); + 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 = Math.pow(eval(function, xi), eval(new_f_x, xi)); - i = i + new_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 = Math.pow(value, eval(new_f_x, xi)); - i = i + new_f_x.length(); + value = StrictMath.pow(value, eval(new_f_x, xi)); + i += new_f_x.length(); } } else if (character == '.') { @@ -192,7 +192,7 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio throw new CalculatorException("The function is not well-formed"); } if (hasNumber && (number.length() > 0)) { - number = number + character; + number += character; } } else if (character == '(') { @@ -202,65 +202,65 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio final String new_f_x = f_x.substring(i + 1, nextBracket(f_x)); if (hasFunction) { - if (function.equals(Constants.SIN)) { + if (Constants.SIN.equals(function)) { if (degree) { - value = Math.sin(Math.toRadians(eval(new_f_x, xi))); + value = StrictMath.sin(StrictMath.toRadians(eval(new_f_x, xi))); } else { - value = Math.sin(eval(new_f_x, xi)); + value = StrictMath.sin(eval(new_f_x, xi)); } - } else if (function.equals(Constants.COS)) { + } else if (Constants.COS.equals(function)) { if (degree) { - value = Math.cos(Math.toRadians(eval(new_f_x, xi))); + value = StrictMath.cos(StrictMath.toRadians(eval(new_f_x, xi))); } else { - value = Math.cos(eval(new_f_x, xi)); + value = StrictMath.cos(eval(new_f_x, xi)); } - } else if (function.equals(Constants.TAN)) { + } else if (Constants.TAN.equals(function)) { if (degree) { - value = Math.tan(Math.toRadians(eval(new_f_x, xi))); + value = StrictMath.tan(StrictMath.toRadians(eval(new_f_x, xi))); } else { - value = Math.tan(eval(new_f_x, xi)); + value = StrictMath.tan(eval(new_f_x, xi)); } - } else if (function.equals(Constants.SINH)) { - value = Math.sinh(eval(new_f_x, xi)); + } else if (Constants.SINH.equals(function)) { + value = StrictMath.sinh(eval(new_f_x, xi)); - } else if (function.equals(Constants.COSH)) { - value = Math.cosh(eval(new_f_x, xi)); + } else if (Constants.COSH.equals(function)) { + value = StrictMath.cosh(eval(new_f_x, xi)); - } else if (function.equals(Constants.TANH)) { - value = Math.tanh(eval(new_f_x, xi)); + } else if (Constants.TANH.equals(function)) { + value = StrictMath.tanh(eval(new_f_x, xi)); - } else if (function.equals(Constants.ASIN)) { + } else if (Constants.ASIN.equals(function)) { if (degree) { - value = Math.asin(eval(new_f_x, xi)) * (180 / Math.PI); + value = StrictMath.asin(eval(new_f_x, xi)) * (180 / StrictMath.PI); } else { - value = Math.asin(eval(new_f_x, xi)); + value = StrictMath.asin(eval(new_f_x, xi)); } - } else if (function.equals(Constants.ACOS)) { + } else if (Constants.ACOS.equals(function)) { if (degree) { - value = Math.acos(eval(new_f_x, xi)) * (180 / Math.PI); + value = StrictMath.acos(eval(new_f_x, xi)) * (180 / StrictMath.PI); } else { - value = Math.acos(eval(new_f_x, xi)); + value = StrictMath.acos(eval(new_f_x, xi)); } - } else if (function.equals(Constants.ATAN)) { + } else if (Constants.ATAN.equals(function)) { if (degree) { - value = Math.atan(eval(new_f_x, xi)) * (180 / Math.PI); + value = StrictMath.atan(eval(new_f_x, xi)) * (180 / StrictMath.PI); } else { - value = Math.atan(eval(new_f_x, xi)); + value = StrictMath.atan(eval(new_f_x, xi)); } - } else if (function.equals(Constants.LN)) { - value = Math.log(eval(new_f_x, xi)); - } else if (function.equals(Constants.LOG)) { - value = Math.log10(eval(new_f_x, xi)); - } else if (function.equals(Constants.SQRT)) { - value = Math.sqrt(eval(new_f_x, xi)); - } else if (function.equals(Constants.CBRT)) { - value = Math.cbrt(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"); } @@ -271,35 +271,34 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio } else { value = eval(new_f_x, xi); } - i = i + new_f_x.length() + 1; - - } else if (character == ')') { - throw new CalculatorException(" '(' is not finished "); - - } else if (character == ' ') { + i += new_f_x.length() + 1; } else if (isValidCharacter(character)) { function = function + character; hasFunction = true; if (i == (f_x.length() - 1)) { - if (function.equals(Constants.E)) { - value = Math.E; - } else if (function.equals(Constants.PI)) { - value = Math.PI; + 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; - } /** @@ -309,30 +308,26 @@ private double eval(final String f_x, final double xi) throws CalculatorExceptio * @return the string * @throws CalculatorException the calculator exception */ - private String nextFunction(String f_x) throws CalculatorException { + private String nextFunction(final 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); if (character == '+' || character == '*' || character == '-' || character == '/') { i = f_x.length(); - } else if (character == '^') { - result = result + character; - } else if (character == '.') { - result = result + character; + } else if (isValidNumericAndCharacter(character)) { + result += character; + } else if (character == '^' || character == '.') { + result += character; } else if (character == '(') { final String new_f_x = f_x.substring(i, nextBracket(f_x) + 1); - result = result + new_f_x; + result += new_f_x; i = (i + new_f_x.length()) - 1; } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); - } else if (character == ' ') { - result = result + character; - } else if (isValidNumericAndCharacter(character)) { - result = result + character; + result += character; } else { throw new CalculatorException("Invalid character:" + character); } @@ -352,28 +347,22 @@ private String nextMinusFunction(final String f_x) throws CalculatorException { for (int i = 0; i < f_x.length(); i++) { final char character = f_x.charAt(i); - if (character == '+') { - i = f_x.length(); - } else if (character == '*') { - result = result + character; - } else if (character == '-') { + if (character == '+' || character == '-') { i = f_x.length(); - } else if (character == '/') { - result = result + character; - } else if (character == '^') { - result = result + character; - } else if (character == '.') { - result = result + character; + } else if (character == '*' || character == '/') { + result += character; + } else if (isValidNumericAndCharacter(character)) { + result += character; + } else if (character == '^' || character == '.') { + result += character; } else if (character == '(') { final String new_f_x = f_x.substring(i, nextBracket(f_x) + 1); - result = result + new_f_x; + result += new_f_x; i = (i + new_f_x.length()) - 1; } else if (character == ')') { throw new CalculatorException(" '(' is not finished "); } else if (character == ' ') { - result = result + character; - } else if (isValidNumericAndCharacter(character)) { - result = result + character; + result += character; } else { throw new CalculatorException("Invalid character:" + character); } @@ -430,7 +419,6 @@ private int nextBracket(final String f_x) throws CalculatorException { if (count == 0) { return i; } - } else { result = i; } diff --git a/src/main/java/com/expression/parser/function/FunctionXs.java b/src/main/java/com/expression/parser/function/FunctionXs.java index 384ef79..fc6397c 100644 --- a/src/main/java/com/expression/parser/function/FunctionXs.java +++ b/src/main/java/com/expression/parser/function/FunctionXs.java @@ -86,7 +86,7 @@ private double eval(final String f, final List values, final List= '0' && character <= '9') { hasNumber = true; - number = number + character; + number += character; if (i == (f.length() - 1)) { value = new Double(number).doubleValue(); number = ""; @@ -99,20 +99,20 @@ private double eval(final String f, final List values, final List values, final List values, final List values, final List values, final List values, final List 0)) { - number = number + character; + number += character; } } else if (character == '(') { @@ -217,61 +217,61 @@ private double eval(final String f, final List values, final List values, final List values, final List Date: Fri, 9 Apr 2021 19:35:36 +0200 Subject: [PATCH 46/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f9f289..c3b6d67 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m CPU: i7-6500U - test 1: one execution: 4ms + test 1: one execution: 3ms test 2: 100000 executions : 2100 ms --> mean time 0.021 ms per execution test 3: one million executions: 16500 ms --> mean time 0.0165 ms per execution From b4856ec31bc78a9d026cecaaeb74e850223bd6a1 Mon Sep 17 00:00:00 2001 From: sbesda Date: Sat, 10 Apr 2021 20:36:55 +0200 Subject: [PATCH 47/53] new version 3.3.0 --- pom.xml | 2 +- .../parser/function/ComplexFunction.java | 18 ++++++++---------- .../expression/parser/function/FunctionX.java | 18 ++++++++---------- .../expression/parser/function/FunctionXs.java | 18 ++++++++---------- .../java/com/expression/parser/SpeedTest.java | 2 +- 5 files changed, 26 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index fa9967b..7fd17c3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.expression.parser com.expression.parser jar - 3.2.0 + 3.3.0 com.expression.parser diff --git a/src/main/java/com/expression/parser/function/ComplexFunction.java b/src/main/java/com/expression/parser/function/ComplexFunction.java index 05194d6..739b0cb 100644 --- a/src/main/java/com/expression/parser/function/ComplexFunction.java +++ b/src/main/java/com/expression/parser/function/ComplexFunction.java @@ -435,11 +435,11 @@ private String nextFunction(final String f) throws CalculatorException { for (int i = 0; i < f.length(); i++) { final char character = f.charAt(i); - if (character == '+' || character == '*' || character == '-' || character == '/') { - i = f.length(); - } else if (isValidNumericAndCharacter(character)) { + if (isValidNumericAndCharacter(character)) { result += character; - } else if (character == '^' || 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); @@ -470,13 +470,11 @@ private String nextMinusFunction(final String f) throws CalculatorException { for (int i = 0; i < f.length(); i++) { final char character = f.charAt(i); - if (character == '+' || character == '-') { - i = f.length(); - } else if (character == '*' || character == '/') { + if (isValidNumericAndCharacter(character)) { result += character; - } else if (isValidNumericAndCharacter(character)) { - result += character; - } else if (character == '^' || 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); diff --git a/src/main/java/com/expression/parser/function/FunctionX.java b/src/main/java/com/expression/parser/function/FunctionX.java index 852ddd8..f57ba25 100644 --- a/src/main/java/com/expression/parser/function/FunctionX.java +++ b/src/main/java/com/expression/parser/function/FunctionX.java @@ -314,11 +314,11 @@ private String nextFunction(final String f_x) throws CalculatorException { for (int i = 0; i < f_x.length(); i++) { final char character = f_x.charAt(i); - if (character == '+' || character == '*' || character == '-' || character == '/') { - i = f_x.length(); - } else if (isValidNumericAndCharacter(character)) { + if (isValidNumericAndCharacter(character)) { result += character; - } else if (character == '^' || 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); @@ -347,13 +347,11 @@ private String nextMinusFunction(final String f_x) throws CalculatorException { for (int i = 0; i < f_x.length(); i++) { final char character = f_x.charAt(i); - if (character == '+' || character == '-') { - i = f_x.length(); - } else if (character == '*' || character == '/') { + if (isValidNumericAndCharacter(character)) { result += character; - } else if (isValidNumericAndCharacter(character)) { - result += character; - } else if (character == '^' || 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); diff --git a/src/main/java/com/expression/parser/function/FunctionXs.java b/src/main/java/com/expression/parser/function/FunctionXs.java index fc6397c..0322cfa 100644 --- a/src/main/java/com/expression/parser/function/FunctionXs.java +++ b/src/main/java/com/expression/parser/function/FunctionXs.java @@ -334,11 +334,11 @@ private String nextFunction(final String f) throws CalculatorException { for (int i = 0; i < f.length(); i++) { final char character = f.charAt(i); - if (character == '+' || character == '*' || character == '-' || character == '/') { - i = f.length(); - } else if (isValidNumericAndCharacter(character)) { + if (isValidNumericAndCharacter(character)) { result += character; - } else if (character == '^' || 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); @@ -368,13 +368,11 @@ private String nextMinusFunction(final String f) throws CalculatorException { for (int i = 0; i < f.length(); i++) { final char character = f.charAt(i); - if (character == '+' || character == '-') { - i = f.length(); - } else if (character == '*' || character == '/') { + if (isValidNumericAndCharacter(character)) { result += character; - } else if (isValidNumericAndCharacter(character)) { - result += character; - } else if (character == '^' || 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); diff --git a/src/test/java/com/expression/parser/SpeedTest.java b/src/test/java/com/expression/parser/SpeedTest.java index 8be74eb..f62164f 100644 --- a/src/test/java/com/expression/parser/SpeedTest.java +++ b/src/test/java/com/expression/parser/SpeedTest.java @@ -20,7 +20,7 @@ public void testTwo() { final long time1 = System.currentTimeMillis(); - for (int i = 0; i < 100000; i++) { + 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"); } From c6cd7a6ea4fe4b3946d6afb242e3a88e011fe1ef Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 14 Sep 2023 13:27:45 +0200 Subject: [PATCH 48/53] Update README.md execution test with graalvm-jdk-17.0.8+9.1 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c3b6d67..4f69cd6 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,8 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m CPU: i7-6500U test 1: one execution: 3ms - test 2: 100000 executions : 2100 ms --> mean time 0.021 ms per execution - test 3: one million executions: 16500 ms --> mean time 0.0165 ms per execution + 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) + 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 7980ma) This version is compiled for Java 1.6 From 21f4622f656b3051add7534367fa85f29055673a Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 14 Sep 2023 13:29:58 +0200 Subject: [PATCH 49/53] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4f69cd6..e8e8b02 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,10 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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) - 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 7980ma) + 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) + 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 7980ma) This version is compiled for Java 1.6 From 5158adfc94315dce50c3d07b28b8e929b47d582e Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 14 Sep 2023 13:31:04 +0200 Subject: [PATCH 50/53] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8e8b02..9d6ad02 100644 --- a/README.md +++ b/README.md @@ -90,8 +90,9 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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"); + 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 From c0b425f376e078b023fb8f6865bcceb551b8ba9b Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 14 Sep 2023 13:31:55 +0200 Subject: [PATCH 51/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d6ad02..c39422d 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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) 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 7980ma) + (with graalvm-jdk-17.0.8+9.1 the total time is 7980ms) This version is compiled for Java 1.6 From d71ffb762f1e6ff70e92414455a00773f1243b0b Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Thu, 14 Sep 2023 13:34:58 +0200 Subject: [PATCH 52/53] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c39422d..87b25fe 100644 --- a/README.md +++ b/README.md @@ -98,9 +98,9 @@ This algorithm is faster than JEP math expresion parser!!! If you compare java.m 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) + (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) + (with graalvm-jdk-17.0.8+9.1 the total time is 7980ms --> 0,00798 per execution) This version is compiled for Java 1.6 From cc92f58f6074b21cf6f5d4056b7f7cc5168f50af Mon Sep 17 00:00:00 2001 From: Sergio Besada Date: Tue, 26 Dec 2023 11:42:08 +0100 Subject: [PATCH 53/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 87b25fe..2007bd6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # java.math.expression.parser 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 kind of Recursive Ascent Parser (https://en.wikipedia.org/wiki/Recursive_ascent_parser). In fact, it is LR parser (Left-Right Parser) without backtracking. +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 needs 25% of the time to parse the same expression as JEP. With other algorithms that use trees like: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy