1
的多个I需要计算有效的像f(i,a) = exp(-0.5 * (i-1) * i * a)
阵列针对所有i in (0..n)
,与n
高达20.000和a
正值非常接近于0效率,但仍然精确的,指数
为了避免计算exp
N次,我用了一个增量的方法,如(Scala中写):
def fInc(n: Int, a: Double)
val expA = Math.exp(-a)
var u = 1.0
var v = 1.0
var i = 1
while(i < n){
u *= expA
v *= u // in practice I store that value in an array, for all i
i += 1
}
}
// reference by calling exp directly
def fRef(n: Int, a: Double) = Math.exp(-0.5 * (i-1) * i * a)
这在数学上是正确的,但随后直接EXP计算的差异太大。下面是一些结果:
n a v Math.exp diff
1000 1E-6 0.6068340008761639 0.6068340008714599 4.704014955336788E-12
1000 1E-9 0.9995006247427483 0.9995006247293567 1.339151E-11
1000 1E-12 0.9999995005111699 0.9999995005001248 1.1045164782785832E-11
1000 1E-15 0.9999999995008992 0.9999999995005 3.992361996552063E-13
10000 1E-6 1.938417748402E-22 1.938417746809E-22 1.5929953847004499E-31
10000 1E-9 0.9512341819777599 0.9512341806597269 1.3180330160622589E-9
10000 1E-12 0.9999500073554776 0.9999500062497292 1.1057483817467073E-9
10000 1E-15 0.9999999500449599 0.9999999500050013 3.995859199079632E-11
正如你所看到的,对于一些价值,差异上升到1E-9,而我也许可以接受1E-13
所以问题:
- 有没有一种方法可以获得更好的近似算法,这个算法比调用所有的
i
上的exp更有效率?
注:
- 我使用Apache FastMath EXP,这给了几乎相同的结果为标准的Java EXP。
- 实际algorith是更复杂的,与其它这样的增量EXP(未虽然二次)
代码评论属于http://codereview.stackexchange.com/您可能想要删除#java标记。 –
我不是要求代码审查。我正在谈论高效的数值方法。呼叫exp时间(慢)vs exp的乘积(快但不够精确)。实际的代码并不重要,我只是简单地解释我的问题 –