`scipy.optimize.root`更快找根

时间:2016-06-06 15:43:36

标签: python performance scipy mathematical-optimization accelerate

我使用scipy.optimize.roothybr方法(最好的一个?)来查找数字函数的根

我在每次迭代时打印残差

delta d 117.960112417 delta d 117.960112417 delta d 117.960112417 delta d 117.960048733 delta d 117.960112427 delta d 117.960112121 delta d 1.46141491664 delta d 0.0322651167588 delta d 0.000363688881595 delta d 4.05494689256e-08

如何通过增加步长,特别是第一次迭代之间的加速来加速根发现? 我不知道算法是如何工作的,但看起来很奇怪3个第一个结果是相同的,3个nexts也完全相同。

Reading the doc,我试图修改eps因素,没有成功

编辑:@sasha,这是一个非常基本的函数来说明问题

def f(X1,X2):
    print ' X1 , diff , norm ' , X1 , X2 - X1 , np.linalg.norm(X2 - X1)
    return X2 - X1

Xa = np.array([1000,1000,1000,1000])
Xb = np.array([2000,2000,2000,2000])

SOL = scipy.optimize.root(f,Xa,(Xb,))

结果如下 无论X的长度如何,我们在开始时都有3个相同的迭代

 X1 , diff , norm  [1000 1000 1000 1000] [1000 1000 1000 1000] 2000.0
 X1 , diff , norm  [ 1000.  1000.  1000.  1000.] [ 1000.  1000.  1000.  1000.] 2000.0
 X1 , diff , norm  [ 1000.  1000.  1000.  1000.] [ 1000.  1000.  1000.  1000.] 2000.0
 X1 , diff , norm  [ 1000.0000149  1000.         1000.         1000.       ] [  999.9999851  1000.         1000.         1000.       ] 1999.99999255
 X1 , diff , norm  [ 1000.         1000.0000149  1000.         1000.       ] [ 1000.          999.9999851  1000.         1000.       ] 1999.99999255
 X1 , diff , norm  [ 1000.         1000.         1000.0000149  1000.       ] [ 1000.         1000.          999.9999851  1000.       ] 1999.99999255
 X1 , diff , norm  [ 1000.         1000.         1000.         1000.0000149] [ 1000.         1000.         1000.          999.9999851] 1999.99999255
 X1 , diff , norm  [ 2000.  2000.  2000.  2000.] [-0. -0. -0. -0.] 4.36239133705e-09
 X1 , diff , norm  [ 2000.  2000.  2000.  2000.] [ 0.  0.  0.  0.] 0.0  

1 个答案:

答案 0 :(得分:5)

首先,我认为你对函数调用的迭代感到困惑,这些调用并不完全相同。因为您没有为求解器提供Jacobean函数,所以它必须估计Jacobean(或者可能只是它的某些部分)本身。 Jacobean基本上是导数的多维等价物。它表示当您略微改变输入时目标函数的输出如何变化。

大多数数值求解器通过在非常接近当前猜测的某点评估目标函数并检查输出变化多少来数值估计Jacobeans。我的猜测是你看到的前几个调用是评估目标函数,然后估计Jacobean。第一次调用,你看到任何实际的变化发生在它估计了Jacobean之后,然后用它来计算根的下一个猜测。

如果您希望自己检查一下,请尝试为解算器提供回调函数。它将在每次迭代时调用此函数,您可以查看每次迭代的位置。我想你会发现它只会在几次迭代中收敛,但每次迭代都会多次调用该函数。

当然,你可以通过为求解器提供一个Jacobean函数来避免所有这些工作,它可以调用它来评估一个点上的Jacobean。如果你这样做,它不需要多次调用来估计它。

该文档包含有关如何添加回调和提供Jacobean功能的信息。如果需要,我可以添加一个例子。

http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.optimize.root.html