You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Detlef Günther <De...@gmx.net> on 2012/03/27 09:58:53 UTC

[math] Improvement: Interpreter for mathematical expressions

Hello,

it would be nice to have an interpreter for mathematical expressions so that functions may be defined at runtime.

Example for f(x):

  ExpInter ei = new ExpInter();
  ei.setFunction("ln(3*sin(2*x)+3)");
  // Plot the function:
  for (double x=0.0;x<3.0;x+=0.1) {
    y = ei(x);
    // ... do something useful with x,y
  }

Can be expanded to f(x,y) or functions wit params f(x,p1,p2,p3):

  ei.setFunction("1+p0*x-5*p1*(p2+7)*p3/x");
  double[] params = { 1.0, 2.0, 4.0, -1 };
  ei.setParams(params);
  // plot ....

If the interpreter implements UnivariateFunction it would be even nicer:

ExpInter function = new ExpInter("x^3-2*x^2+x-27");
double root = solver.solve(99999, function, 0.0, 5.0);
System.out.println("root is " + root + " / " + function.value(root));

function.setFunction("sin(x)");
root = solver.solve(99999, function, 3.0, 4.0);
System.out.println("root is " + root + " / " + function.value(root));

Result:
de.guenther.roots.RegulaFalsi:
        [java] root is 3.7009897720655234 / 0.0
        [java] root is 3.141592653589793 / 1.2246467991473532E-16

I may post my interpreter.

Kind regards

Detlef Guenther


-- 
NEU: FreePhone 3-fach-Flat mit kostenlosem Smartphone!                                  
Jetzt informieren: http://mobile.1und1.de/?ac=OM.PW.PW003K20328T7073a

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Improvement: Interpreter for mathematical expressions

Posted by Thomas Neidhart <th...@gmail.com>.
On Tue, Mar 27, 2012 at 1:32 PM, Gilles Sadowski <
gilles@harfang.homelinux.org> wrote:

> On Tue, Mar 27, 2012 at 12:53:25PM +0200, "Detlef Günther" wrote:
> > Hi Thomas,
> >
> > congrace may be used by writing a wrapper "Expression" to
> UnivarteFunction:
> >
> >
> > import org.apache.commons.math3.analysis.UnivariateFunction;
> >
> > import de.congrace.exp4j.Calculable;
> > import de.congrace.exp4j.ExpressionBuilder;
> >
> > public class Expression implements UnivariateFunction {
> >       private Calculable      calc    = null;
> >
> >       public Expression(String function) throws Exception {
> >               calc = new
> ExpressionBuilder(function).withVariableNames("x").build();
> >       }
> >
> >       public double value(double x) {
> >               calc.setVariable("x", x);
> >               return calc.calculate();
> >       }
> >
> > }
> >
> > Using this you get the folowing code:
> >
> > final double relativeAccuracy = 1.0e-10;
> > final double absoluteAccuracy = 1.0e-10;
> > UnivariateSolver solver = new RegulaFalsiSolver(relativeAccuracy,
> >                                               absoluteAccuracy);
> > Expression exp = new Expression("sin(3*x)");
> > double root = solver.solve(99999, exp, 9.4, 9.7);
> > System.out.println("root is " + root + " / " + exp.value(root));
> >
> > with output:
> >
> > root is 9.42477796076938 / 1.102182119232618E-15  (= 3*PI)
> >
> > ==> Interpreter may be integrated in commons/math, the same result as my
> interpreter.
>

Hi Detlef,

thanks for following up the discussion and testing out exp4j. This looks
really good, and I think we can leave it as it is, meaning if somebody
wants to use an math expression parser, exp4j is a good choice (considering
it is already under apache license and in maven central).


> The above shows a fine _use_ of Commons Math. What added value would there
> be from integrating it into Commons Math?
>

Hi Gilles,

you (and sebb) have a good point in *not* integrating something like this
into CM, so for me this issue is resolved and I learned something new today
(also jexl looks pretty good, never used it before) ;-)

Thomas

Re: [math] Improvement: Interpreter for mathematical expressions

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
On Tue, Mar 27, 2012 at 12:53:25PM +0200, "Detlef Günther" wrote:
> Hi Thomas,
> 
> congrace may be used by writing a wrapper "Expression" to UnivarteFunction:
> 
> 
> import org.apache.commons.math3.analysis.UnivariateFunction;
> 
> import de.congrace.exp4j.Calculable;
> import de.congrace.exp4j.ExpressionBuilder;
> 
> public class Expression implements UnivariateFunction {
> 	private Calculable	calc	= null;
> 
> 	public Expression(String function) throws Exception {
> 		calc = new ExpressionBuilder(function).withVariableNames("x").build();
> 	}
> 
> 	public double value(double x) {
> 		calc.setVariable("x", x);
> 		return calc.calculate();
> 	}
> 
> }
> 
> Using this you get the folowing code:
> 
> final double relativeAccuracy = 1.0e-10;
> final double absoluteAccuracy = 1.0e-10;
> UnivariateSolver solver = new RegulaFalsiSolver(relativeAccuracy,
> 						absoluteAccuracy);
> Expression exp = new Expression("sin(3*x)");
> double root = solver.solve(99999, exp, 9.4, 9.7);
> System.out.println("root is " + root + " / " + exp.value(root));
> 
> with output:
> 
> root is 9.42477796076938 / 1.102182119232618E-15  (= 3*PI)
> 
> ==> Interpreter may be integrated in commons/math, the same result as my interpreter.

The above shows a fine _use_ of Commons Math. What added value would there
be from integrating it into Commons Math?

> [...]

Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Improvement: Interpreter for mathematical expressions

Posted by Detlef Günther <De...@gmx.net>.
Hi Thomas,

congrace may be used by writing a wrapper "Expression" to UnivarteFunction:


import org.apache.commons.math3.analysis.UnivariateFunction;

import de.congrace.exp4j.Calculable;
import de.congrace.exp4j.ExpressionBuilder;

public class Expression implements UnivariateFunction {
	private Calculable	calc	= null;

	public Expression(String function) throws Exception {
		calc = new ExpressionBuilder(function).withVariableNames("x").build();
	}

	public double value(double x) {
		calc.setVariable("x", x);
		return calc.calculate();
	}

}

Using this you get the folowing code:

final double relativeAccuracy = 1.0e-10;
final double absoluteAccuracy = 1.0e-10;
UnivariateSolver solver = new RegulaFalsiSolver(relativeAccuracy,
						absoluteAccuracy);
Expression exp = new Expression("sin(3*x)");
double root = solver.solve(99999, exp, 9.4, 9.7);
System.out.println("root is " + root + " / " + exp.value(root));

with output:

root is 9.42477796076938 / 1.102182119232618E-15  (= 3*PI)

==> Interpreter may be integrated in commons/math, the same result as my interpreter.

Now I'll compare the functions implemented in congrace.  



Regards Detlef











-------- Original-Nachricht --------
> Datum: Tue, 27 Mar 2012 10:10:41 +0200
> Von: Thomas Neidhart <th...@gmail.com>
> An: Commons Developers List <de...@commons.apache.org>
> Betreff: Re: [math] Improvement: Interpreter for mathematical expressions

> On Tue, Mar 27, 2012 at 10:06 AM, Thomas Neidhart
> <thomas.neidhart@gmail.com
> > wrote:
> 
> > 2012/3/27 "Detlef Günther" <De...@gmx.net>
> >
> >> Hello,
> >>
> >> it would be nice to have an interpreter for mathematical expressions so
> >> that functions may be defined at runtime.
> >>
> >
> [snip]
> 
> ah something else I have found that looks quite interesting and may be
> used
> to get inspiration:
> 
> http://projects.congrace.de/exp4j/index.html
> 
> Thomas

-- 
Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Improvement: Interpreter for mathematical expressions

Posted by Thomas Neidhart <th...@gmail.com>.
On Tue, Mar 27, 2012 at 10:06 AM, Thomas Neidhart <thomas.neidhart@gmail.com
> wrote:

> 2012/3/27 "Detlef Günther" <De...@gmx.net>
>
>> Hello,
>>
>> it would be nice to have an interpreter for mathematical expressions so
>> that functions may be defined at runtime.
>>
>
[snip]

ah something else I have found that looks quite interesting and may be used
to get inspiration:

http://projects.congrace.de/exp4j/index.html

Thomas

Re: [math] Improvement: Interpreter for mathematical expressions

Posted by Thomas Neidhart <th...@gmail.com>.
2012/3/27 "Detlef Günther" <De...@gmx.net>

> Hello,
>
> it would be nice to have an interpreter for mathematical expressions so
> that functions may be defined at runtime.
>
> Example for f(x):
>
>  ExpInter ei = new ExpInter();
>  ei.setFunction("ln(3*sin(2*x)+3)");
>  // Plot the function:
>  for (double x=0.0;x<3.0;x+=0.1) {
>    y = ei(x);
>    // ... do something useful with x,y
>  }
>
> Can be expanded to f(x,y) or functions wit params f(x,p1,p2,p3):
>
>  ei.setFunction("1+p0*x-5*p1*(p2+7)*p3/x");
>  double[] params = { 1.0, 2.0, 4.0, -1 };
>  ei.setParams(params);
>  // plot ....
>
> If the interpreter implements UnivariateFunction it would be even nicer:
>
> ExpInter function = new ExpInter("x^3-2*x^2+x-27");
> double root = solver.solve(99999, function, 0.0, 5.0);
> System.out.println("root is " + root + " / " + function.value(root));
>
> function.setFunction("sin(x)");
> root = solver.solve(99999, function, 3.0, 4.0);
> System.out.println("root is " + root + " / " + function.value(root));
>
> Result:
> de.guenther.roots.RegulaFalsi:
>        [java] root is 3.7009897720655234 / 0.0
>        [java] root is 3.141592653589793 / 1.2246467991473532E-16
>
> I may post my interpreter.
>

Hi Detlef,

this is something really interesting, I was thinking of this myself several
times. I guess you know similar projects like jformula or jep, but their
license is usually quite restrictive.
So if you are willing to work on something like this and contribute it to
commons-math, I would be very much in favor and can help with it.

Thomas

Re: [math] Improvement: Interpreter for mathematical expressions

Posted by sebb <se...@gmail.com>.
On 27 March 2012 13:18, Gary Gregory <ga...@gmail.com> wrote:
> On Tue, Mar 27, 2012 at 5:50 AM, sebb <se...@gmail.com> wrote:
>
>> 2012/3/27 "Detlef Günther" <De...@gmx.net>:
>> > Hello,
>> >
>> > it would be nice to have an interpreter for mathematical expressions so
>> that functions may be defined at runtime.
>> >
>> > Example for f(x):
>> >
>> >  ExpInter ei = new ExpInter();
>> >  ei.setFunction("ln(3*sin(2*x)+3)");
>> >  // Plot the function:
>> >  for (double x=0.0;x<3.0;x+=0.1) {
>> >    y = ei(x);
>> >    // ... do something useful with x,y
>> >  }
>> >
>>
>> Seems completely out of scope for Math to me.
>>
>> Besides, there are already scripting languages such as Commons JEXL
>> and BeanShell.
>>
>
> JavaScript is also baked in Java 6 and you can use any Java scripting
> enabled engine.

Further, Commons BSF 3 allows one to use any JSR-223 (javax.scripting)
engine with Java 5.

There's also Commons BSF 2.x which gives access to an earlier version
of Java Scripting; there are quite a few languages that support it.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Improvement: Interpreter for mathematical expressions

Posted by Gary Gregory <ga...@gmail.com>.
On Tue, Mar 27, 2012 at 5:50 AM, sebb <se...@gmail.com> wrote:

> 2012/3/27 "Detlef Günther" <De...@gmx.net>:
> > Hello,
> >
> > it would be nice to have an interpreter for mathematical expressions so
> that functions may be defined at runtime.
> >
> > Example for f(x):
> >
> >  ExpInter ei = new ExpInter();
> >  ei.setFunction("ln(3*sin(2*x)+3)");
> >  // Plot the function:
> >  for (double x=0.0;x<3.0;x+=0.1) {
> >    y = ei(x);
> >    // ... do something useful with x,y
> >  }
> >
>
> Seems completely out of scope for Math to me.
>
> Besides, there are already scripting languages such as Commons JEXL
> and BeanShell.
>

JavaScript is also baked in Java 6 and you can use any Java scripting
enabled engine.

Gary


> These can call just about any method you want, and BeanShell allows
> one to define functions.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
JUnit in Action, 2nd Ed: <http://goog_1249600977>http://bit.ly/ECvg0
Spring Batch in Action: <http://s.apache.org/HOq>http://bit.ly/bqpbCK
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Re: [math] Improvement: Interpreter for mathematical expressions

Posted by sebb <se...@gmail.com>.
2012/3/27 "Detlef Günther" <De...@gmx.net>:
> Hello,
>
> it would be nice to have an interpreter for mathematical expressions so that functions may be defined at runtime.
>
> Example for f(x):
>
>  ExpInter ei = new ExpInter();
>  ei.setFunction("ln(3*sin(2*x)+3)");
>  // Plot the function:
>  for (double x=0.0;x<3.0;x+=0.1) {
>    y = ei(x);
>    // ... do something useful with x,y
>  }
>

Seems completely out of scope for Math to me.

Besides, there are already scripting languages such as Commons JEXL
and BeanShell.
These can call just about any method you want, and BeanShell allows
one to define functions.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Improvement: Interpreter for mathematical expressions

Posted by Bruce A Johnson <jo...@umbc.edu>.
On Mar 27, 2012, at 5:55 AM, Gilles Sadowski wrote:

> Hello.
> 
>> 
>> it would be nice to have an interpreter for mathematical expressions so that functions may be defined at runtime.
>> 
>> Example for f(x):
>> 
>>  ExpInter ei = new ExpInter();
>>  ei.setFunction("ln(3*sin(2*x)+3)");
>>  // Plot the function:
>>  for (double x=0.0;x<3.0;x+=0.1) {
>>    y = ei(x);
>>    // ... do something useful with x,y
>>  }
>> 
>> Can be expanded to f(x,y) or functions wit params f(x,p1,p2,p3):
>> 
>>  ei.setFunction("1+p0*x-5*p1*(p2+7)*p3/x");
>>  double[] params = { 1.0, 2.0, 4.0, -1 };
>>  ei.setParams(params);
>>  // plot ....
>> 
>> If the interpreter implements UnivariateFunction it would be even nicer:
>> 
>> ExpInter function = new ExpInter("x^3-2*x^2+x-27");
>> double root = solver.solve(99999, function, 0.0, 5.0);
>> System.out.println("root is " + root + " / " + function.value(root));
>> 
>> function.setFunction("sin(x)");
>> root = solver.solve(99999, function, 3.0, 4.0);
>> System.out.println("root is " + root + " / " + function.value(root));
>> 
>> Result:
>> de.guenther.roots.RegulaFalsi:
>>        [java] root is 3.7009897720655234 / 0.0
>>        [java] root is 3.141592653589793 / 1.2246467991473532E-16
>> 
>> I may post my interpreter.
> 
> Did you implement a parser from scratch, or do you use existing libraries?
> 
> [I must say that I'm wary of such a functionality, that has more to do with
> string manipulation than mathematical concepts or numerical algorithms.
> Clearly, it's something that could rely on CM when it comes to evaluation.
> But it should probably not (IMHO) become part of CM.]
> 
> 
> Best regards,
> Gilles
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 
> 

Somewhat relevant to this discussion is my AMath4JTcl project.  It's still early in the project and so I wouldn't recommend running a nuclear power plant with it, but it is getting to a point where it is showing its utility.

Basically it adds an expression processor to the JTcl project (Java implementation of the Tcl dynamic programming language) that  supports using  vectors and matrices (as implemented in Commons Math) as well as direct access to various Commons Math features such as linear algebra, Fourier Transforms, and optimization (and more coming).  For those who have experience in Tcl, one would normally write a simple math expression (here the equation of a line) with the somewhat ugly:

set y [expr {$a*$x+$b}]

with the AMath4JTcl library you can write

set y [= a*x+b]

and the variables (like x and y) can be vectors and matrices (much like an environment like MatLab)

Integration with my Fleet concurrent programming library for JTcl (very new) is also possible to allow distributing scripted calculations across multiple cores/processors.


The project is at: http://amath4jtcl.kenai.com/
Look at the Getting Started page for some simple examples.

AMath4JTcl can also be integrated with my Swank ("Tk GUI toolkit in Java") to allow for a full GUI with plotting etc.


Suggestions, contributions comments etc. are all welcomed.

cheers

Bruce



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Improvement: Interpreter for mathematical expressions

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
Hello.

> 
> it would be nice to have an interpreter for mathematical expressions so that functions may be defined at runtime.
> 
> Example for f(x):
> 
>   ExpInter ei = new ExpInter();
>   ei.setFunction("ln(3*sin(2*x)+3)");
>   // Plot the function:
>   for (double x=0.0;x<3.0;x+=0.1) {
>     y = ei(x);
>     // ... do something useful with x,y
>   }
> 
> Can be expanded to f(x,y) or functions wit params f(x,p1,p2,p3):
> 
>   ei.setFunction("1+p0*x-5*p1*(p2+7)*p3/x");
>   double[] params = { 1.0, 2.0, 4.0, -1 };
>   ei.setParams(params);
>   // plot ....
> 
> If the interpreter implements UnivariateFunction it would be even nicer:
> 
> ExpInter function = new ExpInter("x^3-2*x^2+x-27");
> double root = solver.solve(99999, function, 0.0, 5.0);
> System.out.println("root is " + root + " / " + function.value(root));
> 
> function.setFunction("sin(x)");
> root = solver.solve(99999, function, 3.0, 4.0);
> System.out.println("root is " + root + " / " + function.value(root));
> 
> Result:
> de.guenther.roots.RegulaFalsi:
>         [java] root is 3.7009897720655234 / 0.0
>         [java] root is 3.141592653589793 / 1.2246467991473532E-16
> 
> I may post my interpreter.

Did you implement a parser from scratch, or do you use existing libraries?

[I must say that I'm wary of such a functionality, that has more to do with
string manipulation than mathematical concepts or numerical algorithms.
Clearly, it's something that could rely on CM when it comes to evaluation.
But it should probably not (IMHO) become part of CM.]


Best regards,
Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org