奥莱特。因此,我尝试使用3x3系数矩阵(命名为c)和依赖有价值数组(命名为d)来获得3个线性方程的解。 我的代码:
import numpy as np
import sympy as sym
Ax, Ay, By, M0, F, q, L, L1, L2 = sym.symbols('A_x, A_y, B_y, M_0, F, q, L, L_1, L_2')
p = {'L': 6, 'L_1': 4, 'L_2': 2, 'q': 2000, 'F': 1000, 'M_0': 4000}
eq_Fx = sym.Eq(Ax - F, 0)
eq_MB = sym.Eq(-Ay*L + q*L1*(L1/2) + M0, 0)
eq_MA = sym.Eq(By*L + M0 - L1*q*(L1/2), 0)
c = np.array([[1, 0, 0],
[0, p['L'], 0],
[0, 0, p['L']]])
d = np.array([F,
(p['q']*p['L_1']**2)/2 + p['M_0'],
(p['q']*p['L_1']**2)/2 - p['M_0']])
result = np.linalg.solve(c, d)
print(result)
它引发了一个我不明白的奇怪错误:
TypeError:找不到与指定签名匹配的循环,并为ufunc solve1找到了强制转换。
如果有人知道这意味着什么或我如何纠正它,我会感激不尽。
答案 0 :(得分:1)
如果您想象征性地解决或操纵方程式,您应该使用SymPy。如果您需要数字解决方案,则应使用NumPy。如果您想从SymPy表达式开始并转到NumPy函数,则应使用lambdify。
在您的代码中,您创建了一些SymPy方程式,但您没有使用它们。问题是您在F
的定义中使用了p['F']
而不是d
,创建了一个带有未评估的SymPy符号F
的NumPy数组,它不知道如何处理。实际上,如果你完全删除SymPy部分,你的代码仍然可以工作,因为你根本不使用它来导出方程或任何东西。
顺便说一下,由于你的方程是线性的,SymPy可以完全解决它。如果您有兴趣,可以使用以下方法。
>>> p = {M0: 4000, L1: 4, F: 1000, L: 6, L2: 2, q: 2000}
>>> solve([eq_Fx.subs(p), eq_MB.subs(p), eq_MA.subs(p)], [Ax, Ay, By])
{B_y: 2000, A_x: 1000, A_y: 10000/3}
请注意,我使用符号本身而非字符串定义p
,以便subs
替换它们。
要使用SymPy实际生成方程式并使用lambdify
将它们转换为NumPy,您可以使用类似
>>> linear_eq_to_matrix([eq_Fx, eq_MB, eq_MA], [Ax, Ay, By])
(Matrix([
[1, 0, 0],
[0, -L, 0],
[0, 0, L]]), Matrix([
[ F],
[-L_1**2*q/2 - M_0],
[ L_1**2*q/2 - M_0]]))
>>> C, D = linear_eq_to_matrix([eq_Fx, eq_MB, eq_MA], [Ax, Ay, By])
>>> p = {'L': 6, 'L_1': 4, 'L_2': 2, 'q': 2000, 'F': 1000, 'M_0': 4000}
>>> fC = lambdify([M0, F, q, L, L1, L2], C, 'numpy', dummify=False)
>>> fC(**p)
array([[ 1, 0, 0],
[ 0, -6, 0],
[ 0, 0, 6]])
>>> c = fC(**p)
>>> fD = lambdify([M0, F, q, L, L1, L2], D, 'numpy', dummify=False)
>>> d = fD(**p)
>>> import numpy
>>> np.linalg.solve(c, d)
array([[ 1000. ],
[ 3333.33333333],
[ 2000. ]])
这里我再次使用字符串定义p
,以便我们可以将它们用作lambdified函数的关键字参数(否则你必须按顺序传递它们,如fC(4000, 1000, 2000, 6, 4, 2)
)。 dummify=False
参数也是使这项工作成为必要的。
linear_eq_to_matrix
函数将符号方程转换为SymPy矩阵。然后lambdify
允许您将符号元素的SymPy矩阵转换为数字NumPy数组。
最后一点:如果您在符号和变量名称中使用或不使用下划线,例如使用
,则可以避免给自己造成很多混淆。M0 = symbols("M0")
或
M_0 = symbols("M_0")
在任何一种情况下,SymPy都会打印0作为下标。