How to insert a trigonometric function in the console for further work with it?? For example, sin(x) = 2x + 3log (y) or something like this.I think.. I need to enter an expression as a string, and then it is processed as. But how?
Take a look at exp4j
We have used this library extensively in one of our projects for solving the exact same problem that you are facing.
Expression e = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
.variables("x", "y")
.build()
.setVariable("x", 2.3)
.setVariable("y", 3.14);
double result = e.evaluate();
In your particular case, you can ask the user for the following inputs in the console and build your expression using these inputs :
Enter the expression to evaluate. This will become the argument to the ExpressionBuilder constructor.
Enter the Strings that represent the variables in the expression. This will become the input to the variables method. You can add these Strings as keys to a Map which can be used in the next step.
Enter the value of each variable. This will become the input to the setVariable methods. You could collect all the variable values as values in the Map created in the above step. You can iterate over the map and call setVariable(key,value) so that you don't need to know how many variables are present in an expression before hand.
Try exp4j. Example(from the link):
Expression e = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
.variables("x", "y")
.build()
.setVariable("x", 2.3)
.setVariable("y", 3.14);
double result = e.evaluate();
Another option is Javaluator. See the link for example.
And there's EvalX. See below example(from the link):
Expression expression = new Expression("1+1/3");
result = expression.eval():
expression.setPrecision(2);
result = expression.eval():
I hope this helps!
Just an addition, I recently found out you can separate exp4j ExpressionBuilder into two parts and add values to the variables in a for loop, you can find may examples at this website https://github.com/fasseg/exp4j/blob/master/src/test/java/net/objecthunter/exp4j/ExpressionBuilderTest.java
ExpressionBuilder e = new ExpressionBuilder("x^2")
.variable("x")
.build();
for(int i = 0; i < 10; i++) {
e.setVariable("x", i);
System.out.println("x^2 = " + e.evaluate());
}
Related
I am trying to implement a parser in Java to extract the arguments of some functions.
When I have a function like:
max(1, 2, 3)
I just simply can use a Regular Expresion to extract the args.
But all my functions are not like that. If I have some nested function, eg:
max(sum(1, max(1,2,sum(2,5)), 3, 5, mult(3,3))
I would like to obtain:
sum(1, max(1,2,sum(2,5))
3
5
mult(3,3)
I tried using a Regular Expression, but I asume the language is not regular. Another approach was splliting by ',', but did not work as well.
Is there any method for extracting the arguments of a function? I do not really know how this type of problem can be solved since there is no a pattern to use for extracting the arguments.
Any help or insight would be really appreciated. Thanks!!
Parsing a source code into an some abstract model is quite complex topic, depending on the language complexity.
But first step is usually tokenization, where you read one character at a time and detect full tokens (like variable names, function names, operators, literals etc).
Since you presented only very limited scope for the problem , you have very small set of tokens:
name of a function
( and ) to indicate method call
, to separate arguments
numbers
Reading one symbol at the time, you should be able to very easily detect when one token ends and the next one begins. Also your tokens are very distinct (i.e. you don't have to differentiate function name from variable name), you can very easily categorize them.
Once you have a token, you know the grammar (you have only function calls), you can easily build a syntax tree (where at the root you have top level function call with its arguments being children nodes).
From that structure you can easily fetch whichever parts you wish.
If you are more interested in how it works in the javac compiler, you can always check out its source code (it's open source after all):
https://github.com/openjdk/jdk/blob/master/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
https://github.com/openjdk/jdk/blob/master/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java
However, that may be quite a long read.
Finally found a method that works:
public List<String> parseArgs(String l){
int startIdx = l.indexOf("(") + 1;
int endIdx = l.lastIndexOf(")") - 1;
int count = 0;
int argIdx = startIdx;
List<String> args = new ArrayList<>();
for (int i = startIdx; i < endIdx; i++) {
if (l.charAt(i) == '(')
count -= 1;
else if (l.charAt(i) == ')'){
count += 1;
}
else if (l.charAt(i) == ',' && count == 0){
args.add(l.substring(argIdx, i).trim());
argIdx = i + 1;
}
}
args.add(l.substring(argIdx, endIdx + 1).trim());
return args;
}
String l = "max(sum(1, max(1,2,sum(2,5))), 3, 5, mult(3,3))";
parseArgs(l).forEach(System.out::println);
//Prints
sum(1, max(1,2,sum(2,5)))
3
5
mult(3,3)
I'm solving a LP with CPLEX using the Java API. I build my model with the methods provided (like cplex.numVar(col, lb, ub) and cplex.addLe()) After optimization is done, I'm interested in reading the simplex tableau of the final iteration (to be precise: not only the duals and reduced costs but also the coefficients inside the tableau).
I tried to access the IloLPMatrix object cplex.LPMatrix(), but this only returns an empty matrix. I'm interested in the "filled" matrix associated to the problem I just solved.
So, how can I read the simplex tableau?
The short answer is that you cannot access the simplex tableau with the Concert (Java/.NET/C++) APIs. You can access this advanced feature with the C Callable Library and Python APIs, though. For example, see CPXXbinvarow and examining the simplex tableau in the Python API.
Now, to clear up your possible confusion with what IloLPMatrix does, consider the following (mostly cribbed from this thread on the official IBM developerWorks forum).
If you add constraints to the model with cplex.addLe() then you can use rangeIterator to access them (and possibly conversionIterator, SOS1Iterator, SO2Iterator). Note that when you use rangeIterator you have to figure out the runtime type of an expression before you can get at the coefficients. For example:
for (Iterator it = cplex.rangeIterator(); it.hasNext(); /* nothing */) {
IloRange range = (IloRange)it.next();
IloNumExpr expr = range.getExpr(); // Cannot get the coefficients of expr directly :-(
if (expr instanceof IloLinearNumExpr) {
IloLinearNumExpr linExpr = (IloLinearNumExpr)expr;
for (IloLinearNumExprIterator jt = linExpr.linearIterator(); jt.hasNext(); /* nothing */) {
IloNumVar var = jt.nextNumVar();
double coef = jt.getValue();
...
}
}
else if (expr instance of ...) {
...
}
}
On the other hand, if you build your model with an IloLPMatrix, then you can access it with LPMatrixIterator. When you call cplex.LPMatrix it "Creates and returns an empty LP matrix object." You then have to fill it and add it to the model. Alternately, you can use addLPMatrix to create and add it in one step (you still need to populate it).
For example:
// Create a matrix in which we setup the model.
IloLPMatrix matrix = cplex.LPMatrix();
// Create variables.
IloNumVar x = cplex.numVar();
IloNumVar y = cplex.numVar();
matrix.addCols(new IloNumVar[]{ x, y });
// Create constraint x + y <= 2.
IloLinearNumExpr lhs = cplex.linearNumExpr();
lhs.addTerm(x, 1.0);
lhs.addTerm(y, 1.0);
matrix.addRow(cplex.le(lhs, 2.0));
// When all constraints are setup add the matrix to the model.
cplex.add(matrix);
Note that you can only add linear constraints when using an IloLPMatrix.
Whether you use the first method to build your model and rangeIterator to access it, or the second method and LPMatrixIterator, is a matter of taste and possibly some performance trade-offs; you'd have to experiment with both approaches.
In CPLEX_Studio128\cplex\examples\src\java you could have a look at the example LPex1.java.
I want to use guava iterator or java8 foreach(may be lambda expression) nested for loop and process some statements and return a long variable. Here is my code in native java. Please excuse my code may not efficient. I read over net accessing non final variables inside new java 8 foreach is not possible.
Long x = Long.valueOf(0);
Long y = Long.valueOf(0);
for(FirstLevel first : Levels)
{
if(first.getSecondLevels() == null)
{
x= x + getSomeValue(first);
}
for (SecondLevel second : first.getSecondLevels())
{
y = y + getSomeValue(second);
}
}
return x + y;
I have tried but unable to return the values. Thanks in advance for help!
Couple things:
Before approaching "refactoring" like that one you ask, I really strongly recommend learning more "pure" Java (which I assume is the case here, #javalearner). For example you can use long literals instead of manually boxing values:
long x = 0L;
long y = 0L;
Anyway...
using Guava won't help here - this is the imperative way of doing it, and with Java 7 + Guava you'd have to write awkward anonymous classes (i.e. Functions), which without language support is painful. Which brings me to...
Java 8 and Streams. This is probably the best way to go, but first you have to fix (?) your code and define actual problem - for example this statement x= x + getSomeValue(x); evaluates x each time and does not take FirstLevel into account (same is true for y and SecondLevel), so I assume what you really meant was x =+ getSomeValue(firstLevel);.
Having all that said - please be more specific what your problem really is.
EDIT:
After your clarification, using streams your code could look like this:
final long sum = levels.stream()
.mapToLong(first -> getSomeValue(first) + first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum())
.sum();
or with some helper method:
final long s = levels.stream()
.mapToLong(first -> getSomeValue(first) + getSecondLevelSum(first))
.sum();
private long getSecondLevelSum(final FirstLevel first) {
return first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum();
}
First of all, there is no sense in using boxed Long values and even if you once need a boxed value, you don’t need to invoke Long.valueOf, Java already does that for you when converting a long primitive to a boxed Long object.
Further, since adding long values does not depend on the order of summands, there is no reason to maintain two variable throughout the operation, when you will add them at the end anyway:
long result=0;
for(FirstLevel first: Levels) {
result += getSomeValue(first);
for(SecondLevel second: first.getSecondLevels()) {
result += getSomeValue(second);
}
}
return result;
Note that the operator += does the same as result = result + … here, but avoids the repetition of the target operand.
Assuming that both, Levels and the result of getSecondLevels, are collections you can write the same as Stream operation as
return Levels.stream()
.mapToLong(first ->
getSomeValue(first) + first.getSecondLevels().stream()
.mapToLong(second -> getSomeValue(second)).sum())
.sum();
or, alternatively
return Levels.stream()
.flatMapToLong(first -> LongStream.concat(
LongStream.of(getSomeValue(first)),
first.getSecondLevels().stream().mapToLong(second -> getSomeValue(second))))
.sum();
If Levels is an array, you have to replace Levels.stream() with Arrays.stream(Levels) and likewise, if getSecondLevels() returns an array, you have to replace first.getSecondLevels().stream() with Arrays.stream(first.getSecondLevels())
I have a problem in using the apache commons math library.
I just want to create functions like f(x) = 4x^2 + 2x and I want to compute the derivative of this function --> f'(x) = 8x + 2
I read the article about Differentiation (http://commons.apache.org/proper/commons-math/userguide/analysis.html, section 4.7).
There is an example which I don't understand:
int params = 1;
int order = 3;
double xRealValue = 2.5;
DerivativeStructure x = new DerivativeStructure(params, order, 0, xRealValue);
DerivativeStructure y = f(x); //COMPILE ERROR
System.out.println("y = " + y.getValue();
System.out.println("y' = " + y.getPartialDerivative(1);
System.out.println("y'' = " + y.getPartialDerivative(2);
System.out.println("y''' = " + y.getPartialDerivative(3);
In Line 5 a compile error occurs of course. The function f(x) is called and not defined. What I am getting wrong?
Has anyone any experience with the differentiation/derivation with the apache commons math library or does anyone know another library/framework which can help me?
Thanks
In the paragraph below that example, the author describes ways to create DerivativeStructures. It isn't magic. In the example you quoted, someone was supposed to write the function f. Well, that wasn't very clear.
There are several ways a user can create an implementation of the UnivariateDifferentiableFunction interface. The first method is to simply write it directly using the appropriate methods from DerivativeStructure to compute addition, subtraction, sine, cosine... This is often quite straigthforward and there is no need to remember the rules for differentiation: the user code only represent the function itself, the differentials will be computed automatically under the hood. The second method is to write a classical UnivariateFunction and to pass it to an existing implementation of the UnivariateFunctionDifferentiator interface to retrieve a differentiated version of the same function. The first method is more suited to small functions for which user already control all the underlying code. The second method is more suited to either large functions that would be cumbersome to write using the DerivativeStructure API, or functions for which user does not have control to the full underlying code (for example functions that call external libraries).
Use the first idea.
// Function of 1 variable, keep track of 3 derivatives with respect to that variable,
// use 2.5 as the current value. Basically, the identity function.
DerivativeStructure x = new DerivativeStructure(1, 3, 0, 2.5);
// Basically, x --> x^2.
DerivativeStructure x2 = x.pow(2);
//Linear combination: y = 4x^2 + 2x
DerivativeStructure y = new DerivativeStructure(4.0, x2, 2.0, x);
System.out.println("y = " + y.getValue());
System.out.println("y' = " + y.getPartialDerivative(1));
System.out.println("y'' = " + y.getPartialDerivative(2));
System.out.println("y''' = " + y.getPartialDerivative(3));
The following thread from the Apache mailing list seems to illustrate the two possible ways of how the derivative of a UnivariateDifferentiableFunction can be defined. I am adding a new answer as I'm unable to comment on the previous one (insufficient reputation).
The used sample specification of the function is f(x) = x^2.
(1) Using a DerivativeStructure:
public DerivativeStructure value(DerivativeStructure t) {
return t.multiply(t);
}
(2) By writing a classical UnivariateFunction:
public UnivariateRealFunction derivative() {
return new UnivariateRealFunction() {
public double value(double x) {
// example derivative
return 2.*x;
}
}
}
If I understand well, the advantage of the first case is that the derivative does not need to be obtained manually, as in the second case. In case the derivative is known, there should thus be no advantage of defining a DerivativeStructure, right? The application I have in mind is that of a Newton-Raphson solver, for which generally the function value and its derivative need to be known.
The full example is provided on the aforementioned web site (authors are Thomas Neidhart and Franz Simons). Any further comments are most welcome!
This question already has answers here:
How to evaluate a math expression given in string form?
(26 answers)
Closed 6 years ago.
Is there a way in Java to get the result from this mathematical expression:
String code = "5+4*(7-15)";
In other hand what's the best way to parse an arithmetic expression?
You can pass it to a BeanShell bsh.Interpreter, something like this:
Interpreter interpreter = new Interpreter();
interpreter.eval("result = 5+4*(7-15)");
System.out.println(interpreter.get("result"));
You'll want to ensure the string you evaluate is from a trusted source and the usual precautions but otherwise it'll work straight off.
If you want to go a more complicated (but safer) approach you could use ANTLR (that I suspect has a math grammar as a starting point) and actually compile/interpret the statement yourself.
i recently developed a expression parser and released it under the apache license. you can grab it at http://projects.congrace.de/exp4j/index.html
hope that helped
You can use the ScriptEngine class and evaluate it as a javascript string
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("5+4*(7-15)");
Indeed , yu should know that the result of the following instruction in javascript :
eval('var aa=5+4*(7-15)')
aa // -27
There may be a better way, but this one works.
Probably not in as straight forward a manner as you are hoping!
But perhaps you could use a javax.script.ScriptEngine and treat the string as a ECMAScript expression, for example?
Take a look at: Scripting for the Java Platform.
Recently I was using very mature math expression parser library, open source, giving the same API for JAVA and .NET. The library name is mXparser. mXparser provides basic functionalities (simple formulas parsing and calculation) and more advanced ones (i.e. user defined arguments, functions). Additionally it is worth to notice that mXparser has rich built-in math collection (meaning operators, unary / binary / variadic functions, iterated operators such as summation and product).
https://mathparser.org/
https://mathparser.org/mxparser-tutorial/
Please find below a few examples to have more clear view on the syntax.
Example 1 - simple formula
Expression e = new Expression("2+3");
double v = e.calculate();
Example 2 - built-in function
Expression e = new Expression("2+sin(3)");
double v = e.calculate();
Example 3 - built-in constants
Expression e = new Expression("2+sin(pi)");
double v = e.calculate();
Example 4 - user defined arguments and constants
Argument x = new Argument("x = 5");
Constant a = new Constant("a = 2 + sin(3)");
Expression e = new Expression("a + x^2", x, a);
double v1 = e.calculate();
x.setArgumentValue(10);
double v2 = e.calculate();
Example 5 - user defined functions
Function f = new Function("f(x,y) = x^2 + cos(y)");
Expression e = new Expression("f(10,pi) - 3", f);
double v = e.calculate();
Example 6 - user defined recursion
Function factorial = new Function("fact(n) = if( n > 0; n*fact(n-1); 1)");
Expression e = new Expression("fact(10) - 10!", factorial);
double v = e.calculate();
Found recntly - in case you would like to try the syntax (and see the advanced use case) you can download the Scalar Calculator app that is powered by mXparser.
Best regards
LK
There is no builtin way of doing that. But you can use one of the many many open source calculators available.
There is no direct support in the Java SDK for doing this.
You will either have to implement it yourself (possibly using a parser generator such as JavaCC), or use an existing library.
One option would be JEP (commercial), another JEval (free software).
You coul use that project
How to use:
double result = 0;
String code = "5+4*(7-15)";
try {
Expr expr = Parser.parse(code);
result = expr.value();
} catch (SyntaxException e) {
e.printStackTrace();
}
System.out.println(String.format("Result: %.04f", result));
There's an open-source tool called formula4j that does that job.
To take your example expression, it would be evaluated like this using formula4j:
Formula formula = new Formula("5+4*(7-15)");
Decimal answer = formula.getAnswer(); //-27
public static int calc(String string){
int result=0;
String numbers="0123456789";
String operations="+-/*";
for (int i=0;i<string.length();i++){
if (numbers.contains(string.charAt(i)+"")){
result=result*10+(Integer.parseInt(string.charAt(i)+""));
}
else {
if (string.charAt(i)=='+'){ result+=calc(string.substring(i+1));}
if (string.charAt(i)=='-'){ result-=calc(string.substring(i+1));}
if (string.charAt(i)=='*'){ result*=calc(string.substring(i+1));}
if (string.charAt(i)=='/'){ try{result/=calc(string.substring(i+1));}
catch (ArithmeticException e){
System.err.println("You cannot devide by Zero!");}
}
break;
}
}
return result;
}