矩阵乘法的符号表示法

  • 本文关键字:符号 表示 sympy
  • 更新时间 :
  • 英文 :


在numpy中,定义矩阵和点积是标准的,如下所示

import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[7, 8, 9, 10], [11, 12, 13, 14], [15, 16, 17, 18]])
print(a.shape)
print(b.shape)
print(a.dot(b).shape)

按预期输出:

(2, 3)
(3, 4)
(2, 4)

但令我惊讶的是,以下内容在 sympy 中失败

import sympy as sp
a = sp.Matrix([[1, 2, 3], [4, 5, 6]])
b = sp.Matrix([[7, 8, 9, 10], [11, 12, 13, 14], [15, 16, 17, 18]])
print(a.shape)
print(b.shape)
print(a.dot(b).shape)

哪些输出

(2, 3)
(3, 4)
---------------------------------------------------------------------------
ShapeError                                Traceback (most recent call last)
<ipython-input-30-50c934c7fbaf> in <module>()
4 print(a.shape)
5 print(b.shape)
----> 6 print(a.dot(b).shape)
~/miniconda3/lib/python3.6/site-packages/sympy/matrices/matrices.py in dot(self, b)
2389                 mat = mat.T
2390                 b = b.T
-> 2391             prod = flatten((mat * b).tolist())
2392             if len(prod) == 1:
2393                 return prod[0]
~/miniconda3/lib/python3.6/site-packages/sympy/core/decorators.py in binary_op_wrapper(self, other)
130                     else:
131                         return f(self)
--> 132             return func(self, other)
133         return binary_op_wrapper
134     return priority_decorator
~/miniconda3/lib/python3.6/site-packages/sympy/matrices/common.py in __mul__(self, other)
2006             if self.shape[1] != other.shape[0]:
2007                 raise ShapeError("Matrix size mismatch: %s * %s." % (
-> 2008                     self.shape, other.shape))
2009 
2010         # honest sympy matrices defer to their class's routine
ShapeError: Matrix size mismatch: (3, 2) * (4, 3).

这让我感到困惑!

为什么 numpy 和 sympy 之间不一致?

为什么我在 sympy 的文档中找不到这种行为的警告?

如何正确计算符号中两个矩阵的点积?

我可以建议 sympy 的文档有一个关于 numpy 和 sympy 之间语法差异的条目。(我很乐意做出贡献,但我不知道这些差异)

SymPy 中的矩阵积计算为a*b

SymPy 中dot的方法旨在允许计算表示向量的两个矩阵的点积,例如:

>>> sp.Matrix([1, 2]).dot(sp.Matrix([3, 4]))
11

是两个列向量的点积。 这涉及到一个转置。

返回矩阵自和 b 的点积放

宽兼容维度的条件:如果行数或列数与 b 的长度相同,则返回点积。如果 self 是行向量或列向量,则返回标量。否则,将返回结果列表(在这种情况下,self 中的列数必须与 b 的长度匹配)。

我将在这里发布Github上SymPy开发人员的回复:

作为一般规则,在 NumPy 中,所有操作都通过数组进行矢量化。在 SymPy,操作具有通常的数学意义。这意味着 SymPy通常更严格地保持数学上的东西 "纯"。

首先最明显的一个:在 NumPy 中,一切都是数字。函数接受一个数字或数字数组并产生一个数字或 数字数组。在SymPy中,一切都是象征性的。表达式可以 使用默认情况下未计算的符号变量。为 例如,np.exp(np.pi) 生成一个数字,但 sympy.exp(sympy.pi) 生成一个未计算的表达式(可以计算为一个数字 with sympy.exp(sympy.pi).evalf()).

通常,SymPy 函数不适用于 NumPy 数组,NumPy 函数不适用于 SymPy 表达式。如果你想混合 SymPy 和 NumPy,建议使用 lambdify(从 SymPy 开始) 表达式仅使用 SymPy 函数,然后使用 lambdify 对其进行转换 到等效的 NumPy 函数,并在 NumPy 数组上使用它 数字类型)。我已经在StackOverflow上讨论过很多次了。

"*"是矩阵乘法。请注意,@(Python 3.5+)在NumPy和SymPy中都进行矩阵乘法。

辛比。矩阵始终为秩 2。NumPy 数组可以是任何等级。请注意,NumPy 中的 dot/@ 适用于任何排名数组。有一些奇怪的 秩 1 数组上的行为(它基本上将它们视为列或 行向量,具体取决于上下文)。

在 SymPy 中对矩阵调用数学函数(如果有效)将执行该函数的解析矩阵评估。例如 exp(M) 计算矩阵指数。可以使用 Matrix.applyfunc 以元素方式应用函数。在 NumPy 中,exp(A) 取指数 A 的每个元素(使用 scipy.linalg.expm 取一个矩阵 NumPy 数组的指数)。

np.dot 进行矩阵乘法。在 SymPy 中,dot 做一个点积(取两个 1xn 或 nx1 矩阵并产生一个标量)。 sympy.dot 错误(实际上目前在 master 中给出了弃用 警告),如果参数不是 1xn。

1x1 矩阵与 SymPy 中的标量不同。 1 + Matrix([[1]]) 是一个错误。

最新更新