我在 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))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top