Python 用numpy计算nullspace的有理基

Python 用numpy计算nullspace的有理基,python,matlab,numpy,linear-algebra,Python,Matlab,Numpy,Linear Algebra,我试图计算矩阵零空间的有理基。关于如何使用Python/numpy计算nullspace,已经有很多帖子了,但是他们是针对正交基而不是rational基来计算的。以下是如何在MATLAB中实现这一点: ns=null(A,'r') 当我看源代码时,我看到它是这样计算的: function Z = null(A,how) [m,n] = size(A) %... [R,pivcol] = rref(A); r = length(pivcol); nopiv = 1:n; nopiv(pivcol)

我试图计算矩阵零空间的有理基。关于如何使用Python/numpy计算nullspace,已经有很多帖子了,但是他们是针对正交基而不是rational基来计算的。以下是如何在MATLAB中实现这一点:

ns=null(A,'r')

当我看源代码时,我看到它是这样计算的:

function Z = null(A,how)
[m,n] = size(A)
%...
[R,pivcol] = rref(A);
r = length(pivcol);
nopiv = 1:n;
nopiv(pivcol) = [];
Z = zeros(n,n-r,class(A));
if n > r
  Z(nopiv,:) = eye(n-r,n-r,class(A));
  if r > 0
     Z(pivcol,:) = -R(1:r,nopiv);
  end
end
%...

function [A,jb] = rref(A,tol)
%...
[m,n] = size(A);

[num, den] = rat(A);
rats = isequal(A,num./den);

if (nargin < 2), tol = max(m,n)*eps(class(A))*norm(A,'inf'); end

i = 1;
j = 1;
jb = [];
while (i <= m) && (j <= n)

   [p,k] = max(abs(A(i:m,j))); k = k+i-1;
   if (p <= tol)

      A(i:m,j) = zeros(m-i+1,1);
      j = j + 1;
   else

      jb = [jb j];

      A([i k],j:n) = A([k i],j:n);

      A(i,j:n) = A(i,j:n)/A(i,j);

      for k = [1:i-1 i+1:m]
         A(k,j:n) = A(k,j:n) - A(k,j)*A(i,j:n);
      end
      i = i + 1;
      j = j + 1;
   end
end

if rats
    [num,den] = rat(A);
    A=num./den;
end
有两件事我不知道。首先,我不知道如何将比率部分添加到
rref
函数中。其次,我不确定我的索引是否正确,因为MATLAB的索引是从1开始的,并且在选择切片时索引包括最后一个元素(即1:5同时包括1和5)。

这样做是开箱即用的,尽管(在Python中是符号化的)速度不如NumPy或Scipy快。浮点输入示例:

from sympy import Matrix, S, nsimplify
M = Matrix([[2.75, -1.2, 0, 3.2], [8.29, -4.8, 7, 0.01]])
print(nsimplify(M, rational=True).nullspace())
打印两列向量的列表,表示为一列矩阵

[Matrix([
[  700/271],
[9625/1626],
[        1],
[        0]]), Matrix([
[  -1279/271],
[-17667/2168],
[          0],
[          1]])]
有必要使用
nsimplify
将浮动转换为它们所代表的理性。如果矩阵被创建为整数/有理项的矩阵,则不需要这样做

M = Matrix([[1, 2, 3, 5, 9], [9, -3, 0, 2, 4], [S(3)/2, 0, -1, 2, 0]])
print(M.nullspace())

[Matrix([
[ -74/69],
[-176/69],
[   9/23],
[      1],
[      0]]), Matrix([
[ -70/69],
[-118/69],
[ -35/23],
[      0],
[      1]])]

这里,使用
S(3)/2
代替'3/2',以强制创建SymPy对象,而不是浮点计算

在版本1.1中,scipy将具有
null
命令。你可以在githubI上从当前的开发版本中获取定义,我会检查的,谢谢!
M = Matrix([[1, 2, 3, 5, 9], [9, -3, 0, 2, 4], [S(3)/2, 0, -1, 2, 0]])
print(M.nullspace())

[Matrix([
[ -74/69],
[-176/69],
[   9/23],
[      1],
[      0]]), Matrix([
[ -70/69],
[-118/69],
[ -35/23],
[      0],
[      1]])]