在scipy.optimize.root中计算雅可比行列式的默认选项

时间:2017-07-17 03:30:21

标签: python scipy mathematical-optimization

scipy.optimize.root method = lm的文档中,以下是options关键字的默认值。

options={'col_deriv': 0, 'diag': None, 'factor': 100, 'gtol': 0.0, 'eps': 0.0, 'func': None, 'maxiter': 0, 'xtol': 1.49012e-08, 'ftol': 1.49012e-08}

关于col_deriv的说明,他们说

col_deriv : bool, optional non-zero to specify that the Jacobian function computes derivatives down the columns (faster, because there is no transpose operation)

如果我理解它的说法,如果我写col_deriv = True例如,jacobian将按列计算,因此更快。

问题:如果速度更快,为什么col_deriv的默认值为非零值?

我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:2)

也许来自scipy.optimize.leastsq的文档可以提供帮助,因为它同时记录Dfun(雅各布)和col_deriv。从Dfun我们得到:

  

Dfun:可调用,可选

     

使用行中的导数计算func 的雅可比行列式的函数或方法。如果这是None,则估计Jacobian。

col_deriv我们得到:

  

col_deriv:bool,可选

     

非零指定雅可比函数计算列中的导数(更快,因为没有转置操作)。

我对此的解读如下:

  1. 默认情况下,scipy期望计算雅可比矩阵的函数返回一个遵循“正常”定义的矩阵(例如,参见https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant)。

  2. 但是,scipy本身会调用其他函数,可能是用Fortran see, e.g., minpack编写的,它们希望衍生物(关于坐标)放在列中。

  3. 如果计算雅可比矩阵的函数可以返回一个矩阵,其中衍生物沿着列而不是行放置,那么scipy在将它传递给minpack之前不需要转置雅可比矩阵。因此节省了计算时间。

答案 1 :(得分:2)

默认值对应于写入雅可比矩阵的数学约定,如Wikipedia中记录的那样:矩阵的第一行由函数的第一个分量的偏导数等组成。在多变量微积分中效果更好,因为可以将右边的矩阵乘以变量的列向量,以获得函数的线性逼近。

例如,让

fun = lambda x: [x[0]**3-x[1], 2*x[0]+x[1]-12]

雅各比派的传统写法是

jac = lambda x: [[3*x[0]**2, -1], [2, 1]]

其中[3*x[0]**2, -1]来区分fun的第一个组成部分,x[0]**3-x[1]

方法root(fun, [0, 0], jac=jac)在12次迭代中收敛。或者我们可以用转置的方式写雅可比,

jact = lambda x: [[3*x[0]**2, 2], [-1, 1]]

并使用

root(fun, [0, 0], jac=jact, options={"col_deriv": 1})

达到同样的效果。我不明白增益是值得的,但也许是非常大的系统。

如果"col_deriv": 1是默认设置,那么用他们习惯的方式实现Jacobian的不满意的用户会发现性能很差(在上面的示例中使用了不正确的Jacobian版本更多比根搜索的步数加倍。