我有两个数量a& b由递归和通过引用另一个值列表x = [x_1,x_2,... x_N]定义的b,它将是程序的输入。该程序将迭代x中的所有值并更新& b根据:
INFO [85893e95] Running ~/.rvm/bin/rvm default do bundle exec rake db:migrate on 107.170.105.223
DEBUG [85893e95] Command: cd /home/deploy/apps/capstone_project/releases/20160205235633 && ( export RAILS_ENV="production" ; ~/.rvm/bin/rvm default do bundle exec rake db:migrate )
和起始值
for n in range(1,N)
a[n] = a[n-1] * exp(+x[n]) + b[n-1] * exp(-x[n])
b[n] = b[n-1] * exp(+x[n]) + a[n-1] * exp(-x[n])
x中的值不是大数(总是<10),但是N将是数百,并且由于所有指数,a&amp;的最终值。 b会非常大。我担心由于递归的形式,我们不断地将指数大的数字乘以指数小的数字并加上它们,这个方案将变得非常不稳定。
理想情况下,我会计算log(a)和log(b)来阻止值变得太大。但是由于递归方案是不可能的,除非我计算一些像
那样混乱的东西a[0] = exp(+x[0])
b[0] = exp(-x[0])
数值稳定性是我在这里关注的问题吗?如果是这样,基于日志的方案会有助于稳定它吗?
答案 0 :(得分:1)
我们可以先将其重写为:
for n in range(1,N)
a[n] = exp(log(a[n-1]) + x[n]) + exp(log(b[n-1]) - x[n])
b[n] = exp(log(b[n-1]) + x[n]) + exp(log(a[n-1]) - x[n]))
然后改变我们的迭代变量:
for n in range(1,N)
log_a[n] = log(exp(log_a[n-1] + x[n]) + exp(log_b[n-1] - x[n]))
log_b[n] = log(exp(log_b[n-1] + x[n]) + exp(log_a[n-1] - x[n]))
使用np.logaddexp
可以更稳定地计算:
for n in range(1,N)
log_a[n] = np.logaddexp(log_a[n-1] + x[n], log_b[n-1] - x[n])
log_b[n] = np.logaddexp(log_b[n-1] + x[n], log_a[n-1] - x[n])
可以看到logaddexp
的实施here
答案 1 :(得分:-1)
据我所知,所有(?)递归问题都可以通过动态编程来解决。例如,Fibonacci序列可以这样表达:
/
或者,迭代地:
def fibo(n):
if n == 0:
return 0
elif n == 1:
return 1
return fibo(n-1) + fibo(n-2)
大概如果你有一个递归问题,你可以执行类似的解包。