【问题标题】:minimazing function , how to pass arguments into a function scipy最小化函数,如何将参数传递给函数 scipy
【发布时间】:2016-12-30 06:46:28
【问题描述】:

我编写了一个代码,用于使用 scipy 最小化与 r 和 alpha 相关的某个函数。但是,我在将参数传递给函数时遇到了问题。

#!/usr/bin/env python
import numpy as np
from scipy.integrate import quad
import scipy.optimize as opt

def integrand(t, alpha, r):
    return np.exp(-alpha*(t-r))**2

def my_function(parameters, rho):
    alpha = parameters[0]
    r = parameters[1]
    return quad(integrand, 0, rho, args=(alpha, r))[0]

alpha_0 = 1
r_0 = 1
rho = 5.0

vec_expint = np.vectorize(my_function)

res = opt.minimize(my_function(rho), np.asarray([alpha_0, r_0]), method='CG', tol=1.e-2, options={'gtol': 0.01, 'maxiter': 5})
print(res)

我想将积分边界作为变量。我添加了一个变量 rho,我收到以下错误消息:

 res = opt.minimize(my_function(rho), np.asarray([alpha_0, r_0]), method='CG', tol=1.e-2, options={'gtol': 0.01, 'maxiter': 5})
    TypeError: my_function() takes exactly 2 arguments (1 given)

谁能解释我如何以正确的方式传递参数,好吗?

【问题讨论】:

    标签: python scipy


    【解决方案1】:

    你已经定义了:

    def my_function(parameters, rho):
    

    现在试试

    my_function(1)
    

    什么是错误?显而易见的 Python 之一,对吧?当你运行时

     res = opt.minimize(**my_function(rho)**, np.asarray([alpha_0, r_0]), method='CG', tol=1.e-2, options={'gtol': 0.01, 'maxiter': 5})
    

    它甚至没有超过我突出显示的那个表达式。

    有几个解决方案:

    • 定义一个新函数,它只接受一个参数parameters,并事先定义rho。这可以通过deflambdapartial 来完成。

    • optimize 一个args 参数。您在拨打quad 时已经在使用args 功能。

    【讨论】:

      【解决方案2】:

      使用args参数。

      我的代码:

      #!/usr/bin/env python
      import numpy as np
      from scipy.integrate import quad
      import scipy.optimize as opt
      
      def integrand(t, alpha, r):
          return np.exp(-alpha*(t-r))**2
      
      def my_function(parameters, rho):
          alpha = parameters[0]
          r = parameters[1]
          return quad(integrand, 0, rho, args=(alpha, r))[0]
      
      alpha_0 = 1
      r_0 = 1
      rho = 5.0
      
      vec_expint = np.vectorize(my_function)
      
      res = opt.minimize(my_function, np.asarray([alpha_0, r_0]), method='CG', tol=1.e-2, args=(rho),options={'gtol': 0.01, 'maxiter': 5})
      print(res)
      

      输出:

           fun: 0.0018415003336983448
           jac: array([-0.00523077,  0.00762011])
       message: 'Optimization terminated successfully.'
          nfev: 12
           nit: 2
          njev: 3
        status: 0
       success: True
             x: array([ 2.06899361, -1.1785839 ])
      

      【讨论】:

        【解决方案3】:

        首先,让我指出一件可能会让您感到困惑的事情:您有一个名为 rho 的全局(实际上是模块级)变量和一个名为 rho 的局部变量 my_function。这些不一样。将全局变量重命名为 rho_0 可能有助于清除问题,即将代码的最后几行替换为:

        alpha_0 = 1
        r_0 = 1
        rho_0 = 5.0
        
        vec_expint = np.vectorize(my_function)
        
        res = opt.minimize(my_function(rho_0), np.asarray([alpha_0, r_0]), method='CG', tol=1.e-2, options={'gtol': 0.01, 'maxiter': 5})
        print(res)
        

        现在,您遇到的问题来自于在您对opt.minimize 的调用中写入my_function(rho)。当您编写my_function(rho) 时,这意味着您调用 my_function 带有一个参数,并且该参数是您存储在名称rho_0 下的5.0 的值。但是my_function 需要两个 参数:parametersrho。你不能用一个参数来调用它。这就是 Python 给出您遇到的错误的原因。

        为了做你想做的事,你必须知道opt.minimize 需要一个函数 作为它的第一个参数。例如,您可以调用

        opt.minimize(my_function, ...)
        

        你给它的是调用函数的结果,

        opt.minimize(my_function(...), ...)
        

        这不是一回事。

        如您所知,您传递给opt.minimize 的函数需要具有类似的签名

        def my_function(parameters, arg0, arg1, ...):
            ...
        

        当您想将特定值传递给arg0arg1 等时,您可以使用opt.minimizeargs 参数。

        opt.minimize(my_function, parameters_0, args=(arg0_value, arg1_value, ...)
        

        opt.minimize 内部,在每个评估步骤中,它将为parameters 选择值,将它们打包成一个元组,并将其作为第一个参数传递给my_function,而它对你传递的任何内容都进行相反的处理到args:它将元组解包成单独的参数,并在parameters 之后将它们传递给my_function

        【讨论】:

        • 我明白了!谢谢你深刻的解释!它对我帮助很大!
        猜你喜欢
        • 2018-01-01
        • 2019-07-03
        • 1970-01-01
        • 2020-06-09
        • 1970-01-01
        • 2017-07-18
        • 2015-10-30
        • 1970-01-01
        相关资源
        最近更新 更多