【问题标题】:Is it possible to resolve mathematical function dynamically是否可以动态解析数学函数
【发布时间】:2013-08-29 10:06:04
【问题描述】:

是否可以动态解析数学函数,例如通过使用给定的 API?

给定一个函数

a = b + c

有没有办法写出类似的东西:

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

理想情况下,resolve(Object... args) 应该接受更多 Function 类型的类。

编辑 1: API 应该包含在 Java EE 环境中,例如 jBossAS。

编辑 2: 实际上我想用一个未知变量求解方程,但我想避免硬编码函数。因此,对于函数

a+b=c

我不想写硬编码的函数

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

相反,正如@Berylium 所说,我想动态评估表达式。


编辑 3: 我现在正在尝试 symja,我想我越来越接近了,但我在语法上遇到了麻烦。

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) {

你能帮我输入语法吗?


编辑 4:知道了 :-) 输入

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

输出是

Evaluation for Solve[{a==10,c==20,a+b==c},{a,b,c}] is {{a->10,c->20,b->10}}

【问题讨论】:

  • 您在寻找符号数学包吗?喜欢SymPy
  • 如果它是用 Java 编写的,是的。我会更准确地编辑我的问题。
  • 当然。似乎有一些选项,例如JASsymja。或者您可以随时使用 Jython 并从 Java 调用 sympy。
  • 让我看看。我想避免使用 Jython :-) 我的第一个方法是结合 Java 和 octave
  • 您已将“for Java EE”明确添加到您的问题中。但实际上,它与“Java EE”无关。查看任何可以评估作为字符串给出的表达式的 Java 脚本解决方案(beanshell、rhino、jython...)。所以我用“java”替换了“java-ee”,这应该会提高你问题的可见性。

标签: java api math expression-evaluation


【解决方案1】:

任何可嵌入的 Java 脚本引擎都可以:

例如,使用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();
    }

一个优点是 BeanShell 使用非常接近 Java 的 Java 语法。所以没有必要学习/使用另一种语言/语法。

【讨论】:

  • 好的,我试过你的例子,效果很好。但是可以根据我的问题动态解析函数吗?
  • 我添加了两个额外的示例:只需传入函数即可。 BeanShell 不仅是一个表达式评估器,它还是一个成熟的脚本引擎。
  • ... 以及另外两个示例:一个展示如何使用现有类,另一个展示如何动态定义一个。
  • 现在这太棒了:-) 但是我仍然必须自己解决这个功能,不是吗?或者口译员可以为我做这件事吗?考虑 script5:"public int f(int a) { int b = a+a;return b; }; f(4)"。现在如果b 是已知的而a 是未知的会怎样。
  • 在这种情况下,a 是已知的(它是方法的参数)。否则使用 interp.set("a", 4);name 绑定到 value (这就是您所说的解析吗?)。
【解决方案2】:

symja JAR 添加到构建路径后,以下代码会打印以下输出:

代码:

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();
    }

}

输出:

Evaluation for Solve[{a==10,c==20,a+b==c},{a,b,c}] is {{a->10,c->20,b->10}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多