''没有与指定签名匹配的循环''在尝试求解线性方程时出错

时间:2017-12-12 18:37:10

标签: python numpy sympy

奥莱特。因此,我尝试使用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找到了强制转换。

如果有人知道这意味着什么或我如何纠正它,我会感激不尽。

1 个答案:

答案 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作为下标。