【问题标题】:''No loop matching the specified signature'' ERROR when trying to solve linear equation''没有与指定签名匹配的循环'' 尝试求解线性方程时出错
【发布时间】:2018-05-26 12:53:45
【问题描述】:

好的。所以我尝试使用一个 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。

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

【问题讨论】:

  • 请不要在 SO 中发布代码图片(如果您想知道原因,请阅读 this link)
  • 好的,抱歉。我正在解决这个系统: 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']]) 其中 c 是系数矩阵,d 是我的相关贵重物品数组。这些是我正在使用的数据: p = {'L': 6, 'L_1': 4, 'L_2': 2, 'q': 2000, 'F': 1000, 'M_0': 4000} 所以我尝试了以这种方式解决系统: result = np.linalg.solve(c, d) print(result) 但它不起作用。 ://
  • 编辑您的问题并将您的代码发布到其中
  • 我做到了。谢谢。 (我是 Stack 新手,抱歉)。
  • Error solving Matrix equation with numpy 的可能重复项。 F 是 <class 'sympy.core.symbol.Symbol'> 类型,而在 d 中定义的数组的其他元素是 float 类型。也许d = np.array([F, ...] 应该是d = np.array([p['F'], ...]?

标签: python numpy sympy


【解决方案1】:

如果您想以符号方式求解或操作方程,您应该使用 SymPy。如果你想要一个数值解,你应该使用 NumPy。如果您想从 SymPy 表达式开始并转到 NumPy 函数,您应该使用lambdify。

在您的代码中,您创建了一些 SymPy 方程式,但您没有使用它们。问题是您在d 的定义中使用了F 而不是p['F'],创建了一个带有未评估的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 打印为下标。

【讨论】:

    猜你喜欢
    • 2021-11-16
    • 1970-01-01
    • 2017-06-16
    • 2018-05-30
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多