0

Is it possible, to resolve mathematical functions dynamically, e.g by the use of a given API?

Given there is a function

a = b + c

is there a way to write something comparable to:

Function func = new Function("a=b+c");
Result result = func.resolve("a=1", "b=?", "c=a"); 
System.out.println(result.getValue());

Ideally, resolve(Object... args) should accept further classes of type Function.

EDIT 1: The API should be includable into a Java EE environment such as jBossAS.

EDIT 2: Actually I want to solve equations with one unknown variable, but I want to avoid hard coded functions. Thus, for the function

a+b=c

I don't want to write the functions hard coded

getA(int b, int c){...}
getB(int a, int c){...}
getC(int a, int b){...}

Instead, as @Berylium says, I want to evaluate the expression dynamically.


EDIT 3: I'm trying symja right now and I think I'm getting closer, but I have troubles with the syntax.

try {
    F.initSymbols(null);
    EvalUtilities util = new EvalUtilities();
    StringBufferWriter buf = new StringBufferWriter();
    String input = "....";  
    IExpr result = util.evaluate(input);
    OutputFormFactory.get().convert(buf, result);
    String output = buf.toString();
    System.out.println("Evaluation for " + input + " is " + output);
} catch (final Exception e) {

Can you help me with the input syntax?


EDIT 4: Got it :-) For input

String input = "Solve[{a==10,c==20,a+b==c},{a,b,c}]";  

the output is

Evaluation for Solve[{a==10,c==20,a+b==c},{a,b,c}] is {{a->10,c->20,b->10}}
aboger
  • 2,214
  • 6
  • 33
  • 47
  • 2
    Are you looking for a symbolic math package? Like [SymPy](http://sympy.org/)? – Carsten Aug 29 '13 at 10:09
  • If it was written in Java, yes. I will edit my question to be more precisely. – aboger Aug 29 '13 at 10:24
  • 1
    Sure. There seem to be some options, for example [JAS](http://krum.rz.uni-mannheim.de/jas/) or [symja](https://code.google.com/p/symja/). Or you could always go with Jython and call sympy from Java. – Carsten Aug 29 '13 at 10:34
  • Let me have a look. I want to avoid Jython :-) my first approach was to combine Java and [octave](http://www.gnu.org/software/octave/). – aboger Aug 29 '13 at 10:40
  • Both seem complex to me, and I think I prefer JAS. Are there some Java usage examples? I cloned the repo, but I found no Java files in the examples folder. By using Google I had no luck either. I'd like to get started with something easy just as my example above. – aboger Aug 29 '13 at 11:00
  • 1
    You have added "for Java EE" explicitly to your question. But really, it's not tied to "Java EE". Look at any scripting solution for Java (beanshell, rhino, jython, ...) which can evaluate an expression given as a string. So I have replaced "java-ee" with "java" which should enhance the visibility of your question. – Beryllium Aug 29 '13 at 11:10
  • By "resolve" do you mean evaluating functions or actually solving equations? – Joni Aug 29 '13 at 12:44

2 Answers2

1

Any embeddable Java scripting engine will do:

For example, using BeanShell:

    final Interpreter interp = new Interpreter();
    try {
        interp.eval("System.out.println(\"Hello, world\");");

        final String s = "Hello, world (2)";
        interp.set("test", s);
        interp.eval("System.out.println(test);");

        System.out.println("3+4=" + interp.eval("3+4"));

        interp.set("a", 4);
        interp.set("b", 5);
        System.out.println("a + b = " + interp.eval("a + b"));

        final String script1 =
          "public int f(int a) { return a * a; }; System.out.println(f(4));";
        interp.eval(script1);

        final String script2 = 
          "public int f(int a) { return a * a; }; f(4)";
        System.out.println(interp.eval(script2));

        final String script3 = 
          "import java.util.Date; Date date = new Date(); date";
        System.out.println(interp.eval(script3));

        final String script4 = 
          "class X { public int a; } X x = new X(); x.a = 5; x.a";
        System.out.println(interp.eval(script4));

    } catch (EvalError e) {
        e.printStackTrace();
    }

One advantage is that BeanShell uses Java syntax which is quite close to Java. So there is no need to learn/use another language/syntax.

Beryllium
  • 12,808
  • 10
  • 56
  • 86
  • Ok, I tried your example and it works fine. But enables this to resolve functions dynamically according to my question? – aboger Aug 29 '13 at 11:24
  • I have added two additional examples: Just pass in the functions. BeanShell is not only an expression evaluator, it's a full-fledged scripting engine. – Beryllium Aug 29 '13 at 11:30
  • ... and another two examples: One shows how to use existing classes, the other one how to define one on-the-fly. – Beryllium Aug 29 '13 at 11:33
  • Now this is awesome :-) But still I have to resolve the function myself, haven't I? Or is the interpreter able to do this for me? Consider script5: `"public int f(int a) { int b = a+a;return b; }; f(4)"`. Now what if `b` is known and `a` is unknown. – aboger Aug 29 '13 at 11:35
  • In that case `a` is known (it's an argument of the method). Otherwise use `interp.set("a", 4);` to *bind* a *name* to a *value* (is this what you mean by resolving?). – Beryllium Aug 29 '13 at 12:55
0

After adding symja JAR to the build path, the following code prints the output below:

Code:

public static void main(String[] args) {

    try {
        F.initSymbols(null);
        EvalUtilities util = new EvalUtilities();

        StringBufferWriter buf = new StringBufferWriter();
        String input = "Solve[{a==10,c==20,a+b==c},{a,b,c}]";  
        IExpr result = util.evaluate(input);
        OutputFormFactory.get().convert(buf, result);
        String output = buf.toString();
        System.out.println("Evaluation for " + input + " is " + output);

    } catch (final Exception e) {
        e.printStackTrace();
    } finally {
        // Call terminate() only one time at the end of the program  
        ComputerThreads.terminate();
    }

}

Output:

Evaluation for Solve[{a==10,c==20,a+b==c},{a,b,c}] is {{a->10,c->20,b->10}}
aboger
  • 2,214
  • 6
  • 33
  • 47