7

我在 MATLAB 中有这行代码,由其他人编写:

c=a.'/b

我需要把它翻译成 Python。a、b 和 c 都是数组。我目前用于测试代码的维度是:

a: 18x1,
b: 25x18,

这给了我尺寸为 1x25 的 c。

数组不是正方形的,但如果它们是,我不希望代码失败。有人可以准确地解释这条线在做什么(数学上),以及如何在 Python 中做到这一点?(即,如果它存在于 Python 中,则它与 MATLAB 中的内置 mrdivide 函数等效?)

4

5 回答 5

9

符号/是MATLAB中的矩阵右除运算符,调用mrdivide函数。从文档中可以看出,矩阵右除与矩阵左除的关系如下:

B/A = (A'\B')'

IfA是一个方阵,B/A大致等于B*inv(A)(尽管它以不同的、更稳健的方式计算)。否则,x = B/A是在最小二乘意义上对欠定或超定方程组的解x*A = B。有关用于求解方程组的算法的更多详细信息,请参见此处。通常在引擎盖下使用LAPACKBLAS等软件包。

Python的NumPy 包包含一个lstsq用于计算方程组的最小二乘解的例程。此例程可能会给您提供与mrdivide在 MATLAB 中使用该函数相当的结果,但不太可能是精确的。每个函数使用的底层算法的任何差异都可能导致答案彼此略有不同(即一个可能返回值 1.0,而另一个可能返回值 0.999)。此错误的相对大小最终可能会更大,这在很大程度上取决于您正在求解的特定方程组。

要使用lstsq,您可能需要稍微调整您的问题。您似乎想要求解cB = a形式的方程,其中B是 25×18,a是 1×18,c是 1×25。对两边应用转置可以得到方程B T c T = a T,这是一种更标准的形式(即Ax = b)。的参数lstsq应该是(按此顺序)B T(一个 18×25 数组)和一个T(一个 18 元素数组)。lstsq应该返回一个 25 元素的数组 ( c T )。

注意:虽然 NumPy 对 1×N 或 N×1 数组没有任何区别,但 MATLAB 肯定会这样做,如果你不使用正确的数组,它会骂你。

于 2009-06-16T14:07:57.420 回答
9

线

c = a.' / b

计算方程cb = a T对于c的解。Numpy 没有直接执行此操作的运算符。相反,您应该解决b T c T = a for c T并转置结果:

c = numpy.linalg.lstsq(b.T, a.T)[0].T
于 2009-06-17T18:41:38.080 回答
5

在 Matlab 中,A.'意味着转置 A 矩阵。所以从数学上讲,代码中实现的是A T / B。


如何在 Python(或任何语言)中实现矩阵除法 (注意:让我们看一下表格的简单除法A/B;对于您的示例,您需要先执行 A T,然后执行 A T /B,这很容易在 Python 中进行转置操作 |left-as-an-exercise :)|)

你有一个矩阵方程 C*B=A (你想找到 C 作为 A/B)

右除(/)如下:

C *(B *B T )=A *B T

*然后通过反转 (B B T )来隔离 C

IE,

C = A *B T* (B *B T )' ----- [1]

因此,要在Python(或任何语言)中实现矩阵除法,得到以下三种方法。

  • 矩阵乘法
  • 矩阵转置
  • 矩阵逆

然后迭代地应用它们以实现如 [1] 中的划分。

只是,您需要做A T / B,因此您在实现三个基本方法后的最终操作应该是:

A T* B T* (B *B T )'

注意:不要忘记运算符优先级的基本规则 :)

于 2009-06-16T14:07:05.643 回答
1

[已编辑] 正如 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
于 2009-06-16T14:34:35.387 回答
1

您也可以使用伪逆B然后将该结果与A. 尝试使用numpy.linalg.pinv然后将其与矩阵乘法结合使用numpy.dot

c = numpy.dot(a, numpy.linalg.pinv(b))
于 2018-03-07T16:20:31.167 回答