数组除法 - 从 MATLAB 转换为 Python
-
05-07-2019 - |
题
我在 MATLAB 中有这行由其他人编写的代码:
c=a.'/b
我需要将它翻译成Python。a、b、c 都是数组。我当前用于测试代码的维度是:
A:18x1,
乙:25x18,
这给了我尺寸为 1x25 的 c。
数组不是方形的,但如果是方形的,我不希望代码失败。有人能准确解释一下这条线在做什么(数学上),以及如何在Python中做到这一点吗?(即,如果 Python 中存在内置 mrdivide 函数,那么它与 MATLAB 中的内置 mrdivide 函数等效吗?)
解决方案
该行
c = a.' / b
计算 c 的等式 c b = a T 的解。 Numpy没有直接执行此操作的运算符。相反,你应该解决 b T c T = a c T 并转置结果:
c = numpy.linalg.lstsq(b.T, a.T)[0].T
其他提示
符号 /
是MATLAB中的矩阵右除法运算符,它调用 mrdivide
功能。从文档中,矩阵右分区与矩阵左分区有关。以下方式:
B/A = (A'\B')'
如果 A
是方阵, B / A
大致等于 B * inv(A)
(尽管它是在不同的,更健壮的方式)。否则, x = B / A
是最小二乘意义上的解决方案,用于欠定义或过度确定的方程组 x * A = B
。有关用于求解方程组的算法的更多细节,请参见这里。通常是 LAPACK 或 BLAS 在引擎盖下使用。
Python的 NumPy软件包包含一个例程 lstsq
方程组的解。这个例程可能会给你在MATLAB中使用 mrdivide
函数的可比结果,但它不太可能是 exact 。每个函数使用的基础算法的任何差异都可能导致答案彼此略有不同(即,一个可以返回值1.0,而另一个可以返回0.999的值)。此错误的相对大小最终会变大,这在很大程度上取决于您要解决的特定方程组。
要使用 lstsq
,您可能需要稍微调整一下您的问题。您似乎想要解决 cB = a 形式的等式,其中 B 为25 x 18, a 为1- by-18, c 是1乘25。将转置应用于双方为您提供等式 B T c T = a T ,这是一种更标准的形式(即 Ax = b )。 lstsq
的参数应该是(按此顺序) B T (一个18乘25的数组)和 a T (18元素阵列)。 lstsq
应该返回一个25个元素的数组( c T )。
注意:虽然NumPy没有对1-by-N或N-by-1数组进行任何区分,但MATLAB当然会这样做,如果你没有使用正确的数组,它会对你大喊大叫。
在Matlab中, A.'
表示A矩阵的转置。所以从数学上来说,代码中实现的是A时间/B。
如何在 Python(或任何语言)中实现矩阵除法 (笔记:我们来简单看一下表格的划分 A/B
;对于你的例子,你需要做 A时间 首先然后是A时间/B 接下来,在 Python 中执行转置操作非常容易 |left-as-an-exercise :)|)
您有一个矩阵方程c*b = a(您想找到C作为A/B)
右除 (/) 如下:
C*
(乙*
乙时间)=A*
乙时间
然后通过反转 (B*
乙时间)
IE。,
C = A*
乙时间*
(乙*
乙时间)' ----- [1]
因此,要在Python(或任何语言)中实现矩阵除法,可以得到以下三种方法。
- 矩阵乘法
- 矩阵转置
- 矩阵逆
然后迭代应用它们以实现除法,如[1]中所示。
只是,你需要做A时间/B,因此实现这三个基本方法后你的最终操作应该是:
A时间*
乙时间*
(乙*
乙时间)'
笔记:不要忘记运算符优先级的基本规则:)
[编辑]正如Suvesh指出的那样,我之前完全错了。然而,numpy仍然可以轻松地完成他在帖子中提供的程序:
A = numpy.matrix(numpy.random.random((18, 1))) # as noted by others, your dimensions are off
B = numpy.matrix(numpy.random.random((25, 18)))
C = A.T * B.T * (B * B.T).I
你也可以使用 B
的伪逆来解决这个问题,然后将结果与 A
相乘。尝试使用 numpy.linalg.pinv 代码>
然后通过 <将其与矩阵乘法相结合代码> numpy.dot 代码> :
c = numpy.dot(a, numpy.linalg.pinv(b))