Numpy 有没有一种方法可以将fsolve矢量化?

Numpy 有没有一种方法可以将fsolve矢量化?,numpy,scipy,Numpy,Scipy,我正在尝试将fsolve应用于数组: from __future__ import division from math import fsum from numpy import * from scipy.optimize import fsolve from scipy.constants import pi nu = 0.05 cn = [0] cn.extend([pi*n - pi/4 for n in range(1, 5 +1)]) b = linspace(200, 600,

我正在尝试将fsolve应用于数组:

from __future__ import division
from math import fsum
from numpy import *
from scipy.optimize import fsolve
from scipy.constants import pi

nu = 0.05
cn = [0]
cn.extend([pi*n - pi/4 for n in range(1, 5 +1)])
b = linspace(200, 600, 400)
a = fsolve(lambda a: 1/b + fsum([1/(b+cn[i]) for i in range(1, 5 +1)]) - nu*(sqrt(a) - 1)**2, 3)
默认情况下不允许:

TypeError: only length-1 arrays can be converted to Python scalars
有没有一种方法可以将fsolve应用于数组

编辑:

解决它。

fsum用于python标量,因此您应该使用numpy进行矢量化。您的方法可能会失败,因为您正在尝试对包含五个numpy数组的列表求和,而不是对五个数字或单个numpy数组求和

首先,我将使用numpy重新计算cn:

import numpy as np

cn = np.pi * np.arange(6) - np.pi / 4.
cn[0] = 0.
接下来我将分别计算前面的fsum结果,因为它是一个常量向量。这是一种方法,尽管可能有更有效的方法:

cn.shape = (6,1)
cn_grid = np.repeat(cn, b.size, axis=1)
K = np.sum(1/(b + cn_grid), axis=0)
根据K重新定义函数现在应该可以工作了:

f = lambda a: K - nu*(np.sqrt(a) - 1)**2
要使用fsolve找到解决方案,请为其提供适当的初始向量以进行迭代。这使用零向量:

a0 = np.zeros(K.shape)
a = fsolve(f, a0)
也可以使用a0=3:

此函数是可逆的,因此您可以根据两个精确解检查fa=0:

a = (1 - np.sqrt(K/nu))**2

当从a0=0开始时,fsolve似乎选择了第一个解决方案,对于a0=3则选择了第二个解决方案。

fsum用于python标量,因此您应该使用numpy进行矢量化。您的方法可能会失败,因为您正在尝试对包含五个numpy数组的列表求和,而不是对五个数字或单个numpy数组求和

首先,我将使用numpy重新计算cn:

import numpy as np

cn = np.pi * np.arange(6) - np.pi / 4.
cn[0] = 0.
接下来我将分别计算前面的fsum结果,因为它是一个常量向量。这是一种方法,尽管可能有更有效的方法:

cn.shape = (6,1)
cn_grid = np.repeat(cn, b.size, axis=1)
K = np.sum(1/(b + cn_grid), axis=0)
根据K重新定义函数现在应该可以工作了:

f = lambda a: K - nu*(np.sqrt(a) - 1)**2
要使用fsolve找到解决方案,请为其提供适当的初始向量以进行迭代。这使用零向量:

a0 = np.zeros(K.shape)
a = fsolve(f, a0)
也可以使用a0=3:

此函数是可逆的,因此您可以根据两个精确解检查fa=0:

a = (1 - np.sqrt(K/nu))**2


当从a0=0开始时,fsolve似乎选择了第一个解决方案,对于a0=3,则选择了第二个解决方案。

您可以定义一个函数来最小化,该函数应为原始函数的平方,然后使用一个简单的最小化函数。您最好也定义函数的导数:

funcOrig = lambda a: (K - nu*(np.sqrt(a) - 1)**2)
func2 = lambda a: funcOrig(a)**2
dotfunc2 = lambda a: 2*funcOrig(a)* (-nu * 2 * ( np.sqrt(a)-1) * 1./2./np.sqrt(a))
ret = scipy.optimize.fmin_l_bfgs_b(func2, np.ones(400)+1, fprime=dotfunc2, pgtol=1e-20)      

您可以定义一个函数来最小化,该函数应该是原始函数的平方,然后使用一个简单的最小化函数。您最好也定义函数的导数:

funcOrig = lambda a: (K - nu*(np.sqrt(a) - 1)**2)
func2 = lambda a: funcOrig(a)**2
dotfunc2 = lambda a: 2*funcOrig(a)* (-nu * 2 * ( np.sqrt(a)-1) * 1./2./np.sqrt(a))
ret = scipy.optimize.fmin_l_bfgs_b(func2, np.ones(400)+1, fprime=dotfunc2, pgtol=1e-20)      

比特它给你一个a,而它应该是400个,每个b。请看原始帖子的编辑。你是对的,我需要使用一个向量作为初始猜测。我更新了这个建议。它给你一个a,而应该是400个,每个b。请看原始帖子的编辑。你是对的,我需要使用一个向量作为初始猜测。我已经更新了这个建议。