Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么scipy.optimize.root使用初始值调用回调函数四次?_Python_Scipy_Equation Solving - Fatal编程技术网

Python 为什么scipy.optimize.root使用初始值调用回调函数四次?

Python 为什么scipy.optimize.root使用初始值调用回调函数四次?,python,scipy,equation-solving,Python,Scipy,Equation Solving,我正在玩scipy.optimize.root,我试图了解它的功能和工作原理 我的示例代码如下: import numpy as np from scipy.optimize import root def func(x): """ test function x + 2 * np.cos(x) = 0 """ f = x + 2 * np.cos(x) print x,f return f def main(): sol = root(fun

我正在玩
scipy.optimize.root
,我试图了解它的功能和工作原理

我的示例代码如下:

import numpy as np
from scipy.optimize import root

def func(x):
     """ test function x + 2 * np.cos(x) = 0 """
     f = x + 2 * np.cos(x)
     print x,f
     return f

def main():
    sol = root(func, 0.3)

if __name__ == "__main__":
    main() 
使用func中的print语句,我得到以下输出:

[ 0.3] [ 2.21067298]
[ 0.3] [ 2.21067298]
[ 0.3] [ 2.21067298]
[ 0.3] [ 2.21067298]
[-5.10560121] [-4.33928627]
[-1.52444136] [-1.43176461]
[-0.80729233] [ 0.57562174]
[-1.01293614] [ 0.0458079]
[-1.03071618] [-0.0023067]
[-1.02986377] [  7.49624786e-06]
[-1.02986653] [  1.20746968e-09]
[-1.02986653] [ -6.66133815e-16]

到目前为止还不错。我现在想知道为什么它会用初始值调用四次?多谢各位

它们实际上是不一样的。一个潜在的方法是改变这个问题

从那时起输出

[0.3] [2.210672978251212]
[0.3] [2.210672978251212]
[0.3] [2.210672978251212]
[0.300000004470348] [2.210672980079404]
...
在这种情况下,我们很幸运:ε变化可能仍然低于我们的机器精度,我们什么也看不到

编辑

答案是用fortran语言。 通过在源代码中搜索“call fcn(n,x)”,它看起来像函数是:

  • 首先在起点进行评估
  • 然后在
    nprint>0
    请求时调用,以启用迭代的打印
  • 最后在终止前打电话
  • 因此,我们可以看到3张照片


    If随后表示,现在已“打开”迭代打印,并开始雅可比矩阵的数值(和打印)估计。

    您没有提供雅可比矩阵信息,因此使用了so。因此调用
    func
    的次数高于内部迭代计数

    这也意味着,第一个x值不相同,但接近机器精度。将numpy的printoptions更改为
    precision=15
    不足以观察到这一点

    默认的优化器是,文档说:

    每股收益:浮动

    雅可比矩阵正向差分近似的合适步长(对于fprime=None)。如果eps小于机器精度,则假定函数中的相对误差为机器精度的数量级

    编辑:看来我错了!

    print(x,f)
    print('hash x: ', hash(x[0].item()))
    
    输出:


    这些看起来确实是相同的数字(如果在
    散列中没有隐藏的魔力)!如果需要一些不缓存的设置(scipy.optimize cache x-arguments的某些部分),可能需要查看内部结构.

    根查找例程首先将调用一个函数,该函数将调用以初始值传入的函数。(第一次求值)

    然后默认值(即您正在使用的)将调用其内部MINPACK例程,该例程将在开始时计算一次(在初始值处进行第二次计算)。然后
    hybrd
    调用以查找此位置处的近似雅可比数。这需要两次计算,一次在值本身(第三次!),另一个在前面一步,这是第四个电话,有一个稍微不同的论点,正如卡纳克的回答所解释的


    编辑:当调用函数的成本很高时,重复的回调求值可能是非常不可取的。如果是这种情况,则可以对函数进行修改,从而避免使用相同的输入重复求值,而无需打开数值例程的黑盒。对于纯函数,记忆可以很好地工作(即无副作用的函数),这在将数值函数传递到根查找或最小化例程时通常是如此。

    虽然我不反对@Kanak,但我不会说“它们显然超过8”@AGNGazer.是的。我不是一个以英语为母语的人。对我来说,尽可能清楚地表达出来是很费劲的。抱歉。你可以通过计算
    7./3-4./3-1
    来获得机器精度。好吧,现在我们可以看到初始值只重复了三次。但问题仍然存在:为什么是三次?为什么?它只是显示了比t更高的值他需要(离散地)计算出更改的精度优于我们的机器精度。@卡纳克什么?哈希将使用该浮点的所有字节。如果有一位不同,则应该在输出中看到它(很有可能).我必须承认我没有检查浮点的散列impl,但在中,我不认为它们在进行取整或做任何这些事情。是的。我知道。这就是我所说的。数字确实是一样的。但理论上它们是不同的。提高机器精度会表明这一点。也许你比我更了解内部。但是使用a-priori set eps,它会导致向量的1:1位副本应该被缓存或动态调整(没有信息增益)。现在可能有这样的原因,但可能实现缺少这一点。你有最好的主意:首先查看源代码。+1
    print(x,f)
    print('hash x: ', hash(x[0].item()))
    
    [0.3] [2.21067298]
    hash x:  691752902764108160
    [0.3] [2.21067298]
    hash x:  691752902764108160
    [0.3] [2.21067298]
    hash x:  691752902764108160
    [0.3] [2.21067298]
    hash x:  691752913072029696