Matrix 计算符号二进制矩阵的调整门或逆的单个元素

Matrix 计算符号二进制矩阵的调整门或逆的单个元素,matrix,binary,sympy,sparse-matrix,inverse,Matrix,Binary,Sympy,Sparse Matrix,Inverse,我试图得到一个矩阵aa的一个附加元素a_adj,这两个元素都需要是符号表达式,其中符号x_I是二进制的,矩阵a是对称的和稀疏的。Python的sympy非常适合解决小问题: from sympy import zeros, symbols size = 4 A = zeros(size,size) x_i = [x for x in symbols(f'x0:{size}')] for i in range(size-1): A[i,i] += 0.5*x_i[i] A[i+

我试图得到一个矩阵a
a
的一个附加元素a_adj,这两个元素都需要是符号表达式,其中符号x_I是二进制的,矩阵a是对称的和稀疏的。Python的
sympy
非常适合解决小问题:

from sympy import zeros, symbols

size = 4
A = zeros(size,size)
x_i = [x for x in symbols(f'x0:{size}')]

for i in range(size-1):
    A[i,i] += 0.5*x_i[i]
    A[i+1,i+1] += 0.5*x_i[i]
    A[i,i+1] = A[i+1,i] = -0.3*(i+1)*x_i[i]

A_adj_0 = A[1:,1:].det()

A_adj_0
这计算了余因子矩阵(对应的)的第一个元素A_adj_0,并正确地给出了0.125x_0x_1x_2-0.28x_2x_2^2-0.055x_1^2x_2-0.28x_1x_2^2,这是我需要的表达式,但有两个问题:

  • 这对于较大的矩阵是完全不可行的(对于~100的
    size
    s,我需要它)
  • x_i
    是二进制变量(即0或1),而
    sympy
    似乎无法简化二进制变量的表达式,即简化多项式x_i^n=x_i
  • 第一个问题可以部分地通过求解线性方程组
    Ay=b
    来解决,其中
    b
    被设置为第一个基向量
    [1,0,0,0]
    ,使得
    y
    a
    的倒数的第一列。
    y
    的第一个条目是
    A
    逆的第一个元素:

    b = zeros(size,1)
    b[0] = 1
    
    y = A.LUsolve(b)
    
    s = {x_i[i]: 1 for i in range(size)}
    
    print(y[0].subs(s) * A.subs(s).det())
    print(A_adj_0.subs(s))
    
    这里的问题是
    y
    的第一个元素的表达式极其复杂,即使使用了
    simplify()
    等等。这将是一个非常简单的表达式,并简化了上面第2点提到的二进制表达式。这是一种更快的方法,但对于较大的矩阵仍然不可行

    这归结为我的实际问题:

    是否有一种有效的方法来计算稀疏对称符号矩阵的附加元素的单个元素,其中符号是二进制值

    我也愿意使用其他软件

    附录1:
    通过一个我不知道的简单的自定义替换,似乎可以简化
    sympy
    中的二进制表达式:

    A_subs = A_adj_0
    
    for i in range(size):
        A_subs = A_subs.subs(x_i[i]*x_i[i], x_i[i])
    
    A_subs
    

    您应该确保在sympy中使用Rational而不是float,因此
    S(1)/2
    Rational(1,2)
    而不是
    0.5

    Symphy中有一个新的矩阵实现(未记录,目前是内部的),称为DomainMatrix。对于这样的问题,它可能要快得多,并且总是以完全展开的形式生成多项式结果。我预计这类问题的处理速度会快得多,但处理这类问题的速度似乎仍然相当慢,因为它在内部并不稀疏(但在下一版本中可能会发生变化),而且它没有利用二进制值符号的简化。可以使其在
    GF(2)
    上工作,但不能使用假定在
    GF(2)
    中的符号,这是不同的

    如果有帮助,尽管这是您在sympy 1.7.1中使用它的方式:

    from sympy import zeros, symbols, Rational
    from sympy.polys.domainmatrix import DomainMatrix
    
    
    size = 10
    A = zeros(size,size)
    x_i = [x for x in symbols(f'x0:{size}')]
    
    for i in range(size-1):
        A[i,i] += Rational(1, 2)*x_i[i]
        A[i+1,i+1] += Rational(1, 2)*x_i[i]
        A[i,i+1] = A[i+1,i] = -Rational(3, 10)*(i+1)*x_i[i]
    
    # Convert to DomainMatrix:
    dM = DomainMatrix.from_list_sympy(size-1, size-1, A[1:, 1:].tolist())
    
    # Compute determinant and convert back to normal sympy expression:
    # Could also use dM.det().as_expr() although it might be slower
    A_adj_0 = dM.charpoly()[-1].as_expr()
    
    # Reduce powers:
    A_adj_0 = A_adj_0.replace(lambda e: e.is_Pow, lambda e: e.args[0])
    
    print(A_adj_0)
    

    这些都是很好的提示,谢谢!这肯定是一个问题,它会进一步出现,但不幸的是,在我目前的问题中,系数是真实的。因此,如果我理解正确的话,计算就不能在有限域上进行。我只是在一个更大的问题上用实值测试了这个,它看起来很有效,而且比其他方法快得多。这简直就是魔法。我不能低估我对你的时间的感激。非常感谢。