传递 numpy ndarray 作为 fsolve 函数的输入
passing numpy ndarray as inputs of a fsolve function
我想对非线性方程组进行数值求解,并将 numpy ndarrays 作为输入传递。考虑下面的任意代码:
import numpy as np
from scipy.optimize import fsolve
def eqs(A, B, C, D):
eq1 = (A - B * np.sin(C)).tolist()
eq2 = [5 * B + D * np.sum(A * np.cos(C))]
return eq1 + eq2
n = 3
A = np.zeros((n))
A0 = np.random.rand(n)
B = 0.0
B0 = np.random.rand(1)[0]
C = np.random.rand(n)
D = np.random.rand(1)[0]
sol = fsolve(func = eqs, x0 = [A0, B0], args = [C, D])
这导致
missing required positional arguments
错误并将函数更改为:
def eqs(A, B, C, D):
eq1 = A - B * np.sin(C)
eq2 = C[0] * B + D * np.sum(A * np.cos(C))
return [eq1, eq2]
也无济于事。但是,我非常怀疑该错误与传递 ndarrays 有任何关系。一种方法可能是将所有 ndarray 来回更改为 python 列表。但是那样我就无法使用像 np.sin()
...
这样的 numpy 向量化函数了
如果你能帮助我知道应该如何完成,我将不胜感激。
P.S. 上面的方程只是任意的,它们可能根本没有解。
检查这是否解决了你的方程式:
import numpy as np
from scipy.optimize import fsolve
def eqs(X, Y):
A, B = X[:3], X[3]
C, D = Y[:3], Y[3]
eq1 = A - B * np.sin(C)
eq2 = C[0] * B + D * np.sum(A * np.cos(C))
return np.append(eq1, eq2)
n = 3
A = np.zeros((n))
A0 = np.random.rand(n)
B = 0.0
B0 = np.random.rand(1)[0]
C = np.random.rand(n)
D = np.random.rand(1)[0]
sol = fsolve(func = eqs, x0 = np.append(A0, B0), args = np.append(C, D))
sol
输出:
array([ 0.e+000, -1.e-323, 5.e-324, -1.e-323])
这些 scipy.optimize
函数需要一个具有类似
签名的函数
f(x, *args)
x
是求解器会变化的数组(通常为 1d); args
是刚从外部传递过来的参数元组。
更改您的 eqs
以适应这种模式
In [11]: def eqs(X, C, D):
...: A, B = X[:-1], X[-1]
...: eq1 = (A - B * np.sin(C)).tolist()
...: eq2 = [5 * B + D * np.sum(A * np.cos(C))]
...: return eq1 + eq2
...: n = 3
...: A0 = np.random.rand(n)
...: B0 = np.random.rand(1)
...:
...: C = np.random.rand(n)
...: D = np.random.rand(1)
测试调用 eqs
:
In [12]: eqs(np.concatenate((A0,B0)),C,D)
Out[12]:
[-0.28460532658572657,
-0.03649115738682615,
0.7625781482352719,
array([5.46430853])]
现在在 fsolve
中试试:
In [13]: fsolve(eqs, np.concatenate((A0,B0)), args=(C,D))
Out[13]: array([0., 0., 0., 0.])
我想对非线性方程组进行数值求解,并将 numpy ndarrays 作为输入传递。考虑下面的任意代码:
import numpy as np
from scipy.optimize import fsolve
def eqs(A, B, C, D):
eq1 = (A - B * np.sin(C)).tolist()
eq2 = [5 * B + D * np.sum(A * np.cos(C))]
return eq1 + eq2
n = 3
A = np.zeros((n))
A0 = np.random.rand(n)
B = 0.0
B0 = np.random.rand(1)[0]
C = np.random.rand(n)
D = np.random.rand(1)[0]
sol = fsolve(func = eqs, x0 = [A0, B0], args = [C, D])
这导致
missing required positional arguments
错误并将函数更改为:
def eqs(A, B, C, D):
eq1 = A - B * np.sin(C)
eq2 = C[0] * B + D * np.sum(A * np.cos(C))
return [eq1, eq2]
也无济于事。但是,我非常怀疑该错误与传递 ndarrays 有任何关系。一种方法可能是将所有 ndarray 来回更改为 python 列表。但是那样我就无法使用像 np.sin()
...
如果你能帮助我知道应该如何完成,我将不胜感激。
P.S. 上面的方程只是任意的,它们可能根本没有解。
检查这是否解决了你的方程式:
import numpy as np
from scipy.optimize import fsolve
def eqs(X, Y):
A, B = X[:3], X[3]
C, D = Y[:3], Y[3]
eq1 = A - B * np.sin(C)
eq2 = C[0] * B + D * np.sum(A * np.cos(C))
return np.append(eq1, eq2)
n = 3
A = np.zeros((n))
A0 = np.random.rand(n)
B = 0.0
B0 = np.random.rand(1)[0]
C = np.random.rand(n)
D = np.random.rand(1)[0]
sol = fsolve(func = eqs, x0 = np.append(A0, B0), args = np.append(C, D))
sol
输出:
array([ 0.e+000, -1.e-323, 5.e-324, -1.e-323])
这些 scipy.optimize
函数需要一个具有类似
f(x, *args)
x
是求解器会变化的数组(通常为 1d); args
是刚从外部传递过来的参数元组。
更改您的 eqs
以适应这种模式
In [11]: def eqs(X, C, D):
...: A, B = X[:-1], X[-1]
...: eq1 = (A - B * np.sin(C)).tolist()
...: eq2 = [5 * B + D * np.sum(A * np.cos(C))]
...: return eq1 + eq2
...: n = 3
...: A0 = np.random.rand(n)
...: B0 = np.random.rand(1)
...:
...: C = np.random.rand(n)
...: D = np.random.rand(1)
测试调用 eqs
:
In [12]: eqs(np.concatenate((A0,B0)),C,D)
Out[12]:
[-0.28460532658572657,
-0.03649115738682615,
0.7625781482352719,
array([5.46430853])]
现在在 fsolve
中试试:
In [13]: fsolve(eqs, np.concatenate((A0,B0)), args=(C,D))
Out[13]: array([0., 0., 0., 0.])