【问题标题】:Integration with variable as an integration limit ( python)与变量集成作为集成限制(python)
【发布时间】:2017-02-24 01:29:36
【问题描述】:

我需要执行与 python 的集成,但其中一个限制是变量,而不是数字(从 0 到 z)。

我尝试了以下方法:

    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.integrate import quad

    def  I(z,y,a):    #function I want to integrate

      I = (a*(y*(1+z)**3+(1-y))**(0.5))**(-1)

      return I

    def dl(z,y,a):  #Integration of I

      dl = quad(I, 0, z, args =(z,y,a))

      return dl

我遇到的问题是dl(z,y,a) 给了我一个数组,所以每当我想绘制或评估它时,我都会获得以下信息:

ValueError:具有多个元素的数组的真值不明确。

我不知道是否有任何解决方案。在此致谢

【问题讨论】:

  • 您是在变量 y 还是 z 上进行积分?您正在集成的函数还包含 z,如果您可以包含使用示例,则可能不会那么混乱。
  • 我正在整合 z。是的,你是对的,该函数还包含 z,也许这是问题之一,谢谢。

标签: python scipy quad


【解决方案1】:

I 调用quad 的正确方法是:

In [20]: quad(I, 0, 10, args=(1,2))
Out[20]: (0.6984886554222364, 1.1361829471531105e-11)

正如 Longwen 所指出的,I 的第一个参数是 zquad 变化。 (y,a)quad 传递给 I 的参数而不做任何更改。

但您收到错误是因为您尝试使用数组作为z 边界

In [21]: quad(I, 0, np.arange(3), args=(1,2))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-21-fbbfa9c0cd3f> in <module>()
----> 1 quad(I, 0, np.arange(3), args=(1,2))

/usr/local/lib/python3.5/dist-packages/scipy/integrate/quadpack.py in quad(func, a, b, args, full_output, epsabs, epsrel, limit, points, weight, wvar, wopts, maxp1, limlst)
    313     if (weight is None):
    314         retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
--> 315                        points)
    316     else:
    317         retval = _quad_weight(func, a, b, args, full_output, epsabs, epsrel,

/usr/local/lib/python3.5/dist-packages/scipy/integrate/quadpack.py in _quad(func, a, b, args, full_output, epsabs, epsrel, limit, points)
    362 def _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points):
    363     infbounds = 0
--> 364     if (b != Inf and a != -Inf):
    365         pass   # standard integration
    366     elif (b == Inf and a != -Inf):

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

ValueError when using if commands in function - 另一个最近尝试做同样事情的问题,使用数组作为集成边界。那篇文章提供了更多的错误回溯,因此更容易识别问题。


如果不是因为这个 ValueError,你的 3 术语 args 会产生不同的错误:

In [19]: quad(I, 0, 10, args=(10,1,2))
....
TypeError: I() takes 3 positional arguments but 4 were given

【讨论】:

    【解决方案2】:

    编辑:在您的代码中,您应该只将 args 参数设置为 agrs=(y, a),不应包含 z。然后你可以通过索引返回元组的第一个元素来访问积分结果。

    其实quad 返回一个元组。元组中的第一个元素是你想要的结果。由于我无法让您的代码毫无问题地运行,因此我编写了一些短代码。我不确定这是否是您想要的:

    def I(a):
        return lambda z, y: (a*(y*(1+z)**3+(1-y))**(0.5))**(-1)
    
    def dl(z, y, a):
        return quad(I(a), 0, z, args=(y))
    
    print(dl(1,2,3)[0])
    

    结果:

    0.15826362868629346
    

    【讨论】:

    • 是的,我想这就是我需要的,我真的不明白你为什么不把变量 'a' 放在 args() 中。总之,非常感谢!!!
    • @Brny args 应该包含参数,除了您要集成的参数。在我的例子中,函数 I(a) 实际上返回带有两个参数 y 和 z 的函数。当我将它传递给quad 函数时,它实际上只需要一个额外的参数(y),除了我正在积分的变量(z)。这就是为什么我只在args 中包含y。但它的作用与您的代码相同。
    • 好的,我明白了。谢谢!
    【解决方案3】:

    Python 的考虑是空列表(或可迭代)在转换为布尔值时为假。想象一下,您正在列出一些东西。

    当您进行计算时,您可以考虑零向量,[0,0,0] 在线性代数中可能被视为零,但不是空列表。

    您的错误似乎来自非空检查。 正如其他答案所暗示的那样,您错误地调用了一个函数并提供了一个预期数字的数组。

    【讨论】:

      【解决方案4】:

      我不认为quad 接受向量值积分边界。所以在这种情况下,您实际上必须循环 z 或使用 np.vectorize

      【讨论】:

        猜你喜欢
        • 2020-12-25
        • 2018-10-07
        • 2019-12-26
        • 2017-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-17
        • 2016-08-22
        相关资源
        最近更新 更多