Java 有没有优化数学公式的工具?

Java 有没有优化数学公式的工具?,java,c++,c,optimization,Java,C++,C,Optimization,我最近遇到了一个问题: 我必须在一个程序中做一些复杂的数学。一位朋友注意到它运行缓慢,并告诉我,通过公式中的一些简单的重新调整,可以改进结果的计算。大概是这样的: 1/15 * x = x/15 or 2*x + 2*y = 2*(x + y) 我知道这些都很简单。所以我有一个更复杂的例子: 我的CAS给了我这个公式: -1/10*v+1/15*(3*v^2+60*s)^(1/2) 我把它放在Java中: (Math.sqrt(3.0 * (v*v + 20.0*s))/15.0) - (v

我最近遇到了一个问题:
我必须在一个程序中做一些复杂的数学。一位朋友注意到它运行缓慢,并告诉我,通过公式中的一些简单的重新调整,可以改进结果的计算。大概是这样的:

1/15 * x = x/15
or
2*x + 2*y = 2*(x + y)
我知道这些都很简单。所以我有一个更复杂的例子:
我的CAS给了我这个公式:

-1/10*v+1/15*(3*v^2+60*s)^(1/2)
我把它放在Java中:

(Math.sqrt(3.0 * (v*v + 20.0*s))/15.0) - (v/10.0)
这是一个巨大的进步。但我非常确信,这可以通过其他一些简单的优化进一步优化。
我提出了一些其他等价的公式。但是我如何知道哪一个是最快的(当然不需要分析。每个人都可以这样做,而且需要花费大量的时间)。
(很明显,最后一个是最快的。)

我真的把上面的公式带到了极限(重新安排公式以消除不成功的操作,并预先计算一些常数…真的一点也不容易!)。这些都是手工完成的,还有一些数学知识。此外,我真诚地怀疑任何编译器或解释器(Java和其他运行时解释语言)是否能够将
(Math.sqrt(3.0*(v*v+20.0*s))/15.0)-(v/10.0)
转换为更快的公式
(Math.sqrt(v*v+20.0*s)-(0.8660254037844387*v))*0.11547005383792515
,这将给出完全相同的结果…
这是一项需要花费大量时间的工作。特别是如果有几百个公式。
事实上,你可以对一个公式做很多小的改变,其中一些确实可以帮助提高计算速度

有没有类似的工具可以为C/C++/Java代码优化这些公式

(如果需要更多示例,我将提供更多)


(假设所有计算都使用浮点运算。我只是想让公式保持可读性)

有一本经典的书叫做

数学方程的效率可能不是实现它们最简单的形式

示例:z=2*x+2*y
如前所述,有两个乘法运算和一个加法运算

使用分配属性,可以将其重写为:
z=2*(x+y)

现在只有一个乘法运算

一般来说,操作按从快到慢的顺序排列如下:

  • 加成
  • 减法——在加法之前需要否定(因此需要一个额外的 操作)
  • 乘法——可能是一种转变,但很可能是 移动并添加
  • 分部 可以根据上述内容重新安排的数学计算将更加有效

其他技术包括循环展开(在重新启动循环之前执行许多语句)和数据设置(在处理之前加载所有数据)

嗯,大多数体面的编译器都会自动为您执行这样的优化。我不会尝试手动优化它们,除非是不明显的强度降低优化。当然,你给出的例子对于编译器来说是微不足道的。它被称为&(另见…)数学公式的简化在一般情况下是不可判定的。它被称为“程序员”;-)不过,说真的,优化器会为您做一些事情,确保结果相同。如果没有,像这样的更改可能会影响算法的数值稳定性,因此您不应该以效率的名义自动应用这些更改,否则您将破坏别人缓慢但正确的代码。在C等语言中,
1/15*x
甚至与
x/15
并不近似,尽管如果你说
15.0
它们非常接近。试试数字公式:你应该分析一下你的程序。我知道最简单的形式不是最有效的。但是有没有一种简单的方法(或工具)来自动化这个过程?我的意思是,要做一些已知速度更快的基本更改不会那么难。这意味着使用更多更快的运算(如加法和减法)重写公式。编译器会为您完成“已知更快的基本更改”。请查看数字配方网站。他们可能有一些工具或项目的链接。我没有找到任何东西。。。(我可能只是忽略了它…)
((2.0 * Math.sqrt(3.0 * (v*v + 20.0*s))) - (3.0 * v))/30.0
((3.4641016151377544 * Math.sqrt(v*v + 20.0*s)) - (3.0 * v))/30.0
((3.4641016151377544 * Math.sqrt(v*v + 20.0*s)) - (3.0 * v)) * 0.03333333333333333
(Math.sqrt(v*v + 20.0*s) - (0.8660254037844387 * v)) * 0.11547005383792515