将值列表传递给SciPy fsolve参数

时间:2017-03-17 22:55:58

标签: python python-3.x scipy

我有以下功能:

def equation1(xy, d=7.62, G=8.2728, rhop=7.51, ut=399):
    ep, uc = xy     # define variables
    g = 981         # acceleration due to gravity, cm/s^2

    f1 = 2*g*d*((ep**-4.7) - 1) - 0.01*(uc/ep - ut)**2
    f2 = G - (uc/ep - ut)*rhop*(1 - ep)
    return f1, f2

我在SciPy中使用ep来解析ucfsolve

ep1, uc1 = fsolve(equation1, [1, 500])

我不想为G定义单个值,而是为epuc求解范围为G的{​​{1}}值。当我传递G的值列表时,我收到有关使用序列设置数组元素的错误。

是否可以使用G = [8, 10, 12]其中一个参数是列表或值数组?

2 个答案:

答案 0 :(得分:1)

您可以将G作为equation1的参数并通过fsolve(使用其args参数)传递给:{/ p>

from scipy.optimize import fsolve

def equation1(xy, G, d=7.62, rhop=7.51, ut=399):
    ep, uc = xy     # define variables
    g = 981         # acceleration due to gravity, cm/s^2

    f1 = 2*g*d*((ep**-4.7) - 1) - 0.01*(uc/ep - ut)**2
    f2 = G - (uc/ep - ut)*rhop*(1 - ep)
    return f1, f2


for G in [8, 10, 12]:
    ep1, uc1 = fsolve(equation1, [1, 500], (G, ))
    print(G, ep1, uc1)

这在我的机器上显示:

8 0.994582431487 592.401268397
10 0.993718674117 607.148953105
12 0.992912345764 620.018209488

答案 1 :(得分:1)

如果我用:

运行你的功能
In [83]: ep1, uc1 = fsolve(equation1, [1, 500],args=(7.62, [8,10,12]))
...
ValueError: setting an array element with a sequence.

但是看看调用堆栈。这很长,但这条线很突出

res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))

正在对你的功能进行测试。

例如:

In [121]: x0=np.array([1,500])
In [122]: numinputs=2
In [123]: args = (1,8)     # scalar G
In [124]: np.atleast_1d(equation1(*((x0[:numinputs],) + args)))
Out[124]: array([-102.01,    8.  ])

In [125]: args = (1,[8,10])    # list G
In [126]: np.atleast_1d(equation1(*((x0[:numinputs],) + args)))
....
ValueError: setting an array element with a sequence.

专门研究你的功能产生了什么:

In [127]: equation1(*((x0[:numinputs],) + args))
Out[127]: (-102.01000000000001, array([  8.,  10.]))

它无法将此元组转换为有效的1d数组,因此会显示错误消息。

请注意,您的函数的参数是:

In [128]: ((x0[:numinputs],) + args)
Out[128]: (array([  1, 500]), 1, [8, 10])

fsolve将整个args元组传递给您的函数。它不会遍历数组或列表。

因此,对于各种fsolve值,您需要G,您必须自己进行迭代。 fsolve(以及大多数其他scipy函数)不会为您执行此操作。