python内置函数来做矩阵缩减

use*_*102 20 python matrix scipy

python是否有内置函数将矩阵转换为行梯形形式(也称为上三角形)?

NPE*_*NPE 27

如果可以使用sympy,Matrix.rref()可以这样做:

In [8]: sympy.Matrix(np.random.random((4,4))).rref()
Out[8]: 
([1, 1.42711055402454e-17, 0, -1.38777878078145e-17]
[0,                  1.0, 0,  2.22044604925031e-16]
[0, -2.3388341405089e-16, 1, -2.22044604925031e-16]
[0, 3.65674099486992e-17, 0,                   1.0],
 [0, 1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

  • 手动,约 5-10 分钟。同情,1.13 毫秒:-3 (4认同)
  • 没关系,`np.array(result [0] .tolist(),dtype = float)`更简单. (4认同)

Ste*_*joa 6

是的。在 中scipy.linalgluLU 分解是否会从本质上获得行梯队形式。

还有其他的因式分解,例如qrrqsvd,和更多的,如果你有兴趣。

文档。

  • LU 分解与行梯形形式不同。见 http://math.stackexchange.com/a/1614952 (2认同)
  • 是的,可以从这些函数计算减少的行梯队,但为什么要让用户跳过这些障碍。大多数实用的应用程序(例如 scilab、Matlab、Mathematica 等)都内置了这些功能。相反,Python 的使用必须经过符号代数库。 (2认同)

Win*_*ert 5

http://mail.scipy.org/pipermail/numpy-discussion/2008-November/038705.html

基本上:不要这样做。

rref 算法在计算机上实现时会产生太多的不准确性。所以你要么想以另一种方式解决问题,要么使用@aix 建议的符号。

  • 只需将您的数字包装在一个有理数数据类型中,例如 python 的 `fraction.Fraction`,它已经为算术运算重载了。您甚至可以使用 numpy 向量化构造函数,即`VecFraction = np.vectorize(fraction.Fraction)` 和`rational_array = VecFraction(numeric_array)`。计算机没有理由不能执行精确的 RREF。 (2认同)
  • “或者使用 @aix 建议的符号”,这写在哪里? (2认同)

rth*_*rth 5

我同意@Mile对@WinstonEwert 回答 的评论 没有理由计算机无法以给定的精度执行 RREF 。

RREF的实现应该不是很复杂,matlab不知怎么的就搞定了这个功能,所以numpy应该也有。

我做了一个非常简单直接的实现,效率很低。但是对于简单的矩阵,它工作得很好:

from numpy import *

def rref(mat,precision=0,GJ=False):
    m,n = mat.shape
    p,t = precision, 1e-1**precision
    A = around(mat.astype(float).copy(),decimals=p )
    if GJ:
        A = hstack((A,identity(n)))
    pcol = -1 #pivot colum
    for i in xrange(m):
        pcol += 1
        if pcol >= n : break
        #pivot index
        pid = argmax( abs(A[i:,pcol]) )
        #Row exchange
        A[i,:],A[pid+i,:] = A[pid+i,:].copy(),A[i,:].copy()
        #pivot with given precision
        while pcol < n and abs(A[i,pcol]) < t:
            #pivot index
            pid = argmax( abs(A[i:,pcol]) )
            #Row exchange
            A[i,:],A[pid+i,:] = A[pid+i,:].copy(),A[i,:].copy()
            pcol += 1
        if pcol >= n : break
        pivot = float(A[i,pcol])
        for j in xrange(m):
            if j == i: continue
            mul = float(A[j,pcol])/pivot
            A[j,:] = around(A[j,:] - A[i,:]*mul,decimals=p)
        A[i,:] /= pivot
        A[i,:] = around(A[i,:],decimals=p)
        
    if GJ:
        return A[:,:n].copy(),A[:,n:].copy()
    else:
        return A   
Run Code Online (Sandbox Code Playgroud)

这里有一些简单的测试

print "/*--------------------------------------/"
print "/             Simple TEST               /"
print "/--------------------------------------*/"
A = array([[1,2,3],[4,5,6],[-7,8,9]])
print "A:\n",R
R = rref(A,precision=6)
print "R:\n",R
print
print "With GJ "
R,E =   rref(A,precision=6,GJ=True)
print "R:\n",R
print "E:\n",E
print "AdotE:\n",around( dot(A,E),decimals=0)

/*--------------------------------------/
/             Simple TEST               /
/--------------------------------------*/
A:
[[ 1.  0.  1.]
 [-0.  1.  1.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]]
R:
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]

With GJ 
R:
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]
E:
[[-0.071428  0.142857 -0.071429]
 [-1.857142  0.714285  0.142857]
 [ 1.595237 -0.523809 -0.071428]]
AdotE:
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [-0.  0.  1.]]

print "/*--------------------------------------/"
print "/        Not Invertable TEST            /"
print "/--------------------------------------*/"
A = array([
    [2,2,4, 4],
    [3,1,6, 2],
    [5,3,10,6]])
print "A:\n",A
R = rref(A,precision=2)
print "R:\n",R
print
print "A^{T}:\n",A.T
R = rref(A.T,precision=10)
print "R:\n",R
/*--------------------------------------/
/        Not Invertable TEST            /
/--------------------------------------*/
A:
[[ 2  2  4  4]
 [ 3  1  6  2]
 [ 5  3 10  6]]
R:
[[ 1.  0.  2.  0.]
 [-0.  1. -0.  2.]
 [ 0.  0.  0.  0.]]

A^{T}:
[[ 2  3  5]
 [ 2  1  3]
 [ 4  6 10]
 [ 4  2  6]]
R:
[[ 1.  0.  1.]
 [-0.  1.  1.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]]
Run Code Online (Sandbox Code Playgroud)