Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Well... This problem (decomposing a matrix as the sum of $p$ matrices with your constraints) can be turned in the search of the ideal of some field defined by a polynomial system :

  • each element of M will be translated as a sum of $p+1$ terms (the corresponding elements of the $p$ matrices minus the corresponding element of M) ;

  • each $(0, 1)$ $r\times c$ matrix (generic term $m$) can be created by nullifying $rc$ $m(m-1)$ polynomials ;

  • each $(0, -1)$ $r\times c$ matrix (generic term $m$) can be created by multiplying a $(0, 1)$ matrix by -1 ;

  • therefore, all the matrices can be given the same form, by multiplying each of them by $s_k,\ k\in1\dots p$ with the additional constraints of nullifying $s_k^2-1$.

This can be implemented as follows :

def solve_system_for(M, Nmat=6):
    """
    Decompose M as a sum of Nmat matrices of the same shape, each of them
    being composed either of 1 and 0 OR -1 and 0
    """
    Nr = M.nrows()
    Nc = M.ncols()
    Nel = Nr*Nc
    # Names for signs of matrices
    sn = ["s%d"%u for u in (1..Nmat)]
    # Names for matrix elements
    mn = [[["m%d%d%d"%(t,u,v)for v in (1..Nc)] for u in (1..Nr)]
          for t in (1..Nmat)]
    # Polynomial ring : must be a field containing -1, 0, 1,
    # with arithmetic compatible with ZZ's ==> QQ
    R1 = PolynomialRing(QQ, sn+flatten(mn))
    R1.inject_variables()
    # Vector of inteterminates related to matrice's signs
    s = R1.gens()[0:Nmat]
    # vector of indeterminates for matrices elements
    a = R1.gens()[Nmat:]
    # List of matrices of indeterminates
    A = [s[u-1]*matrix(R1.gens()[Nmat+u*Nel:Nmat+(u+1)*Nel],
                       nrows=Nr, ncols=Nc)
         for u in range(Nmat)]
    # Matrix of equations to solve
    Eq = sum(A)-M.change_ring(QQ)
    # Constraints on s elements : s ∈ {-1, 1} <==> s in roots of s^2-1 in QQ
    Cs = [u^2-1 for u in s]
    # Constraints on a elements : a ∈ {O, 1} <==> a in roots of a*(a-1) in QQ
    Ca = [u*(u-1) for u in a]
    # Solutions ideal described by :
    J1 = R1.ideal(flatten(Eq.list()) + Cs + Ca)
    # The hard, long part :
    from time import time as stime
    t0 = stime()
    D = J1.dimension()
    t1 = stime()
    if D==0: # Expected case on the basis of finite set of possible values
        t2 = stime()
        S = J1.variety()
        t3 = stime()
        return {"Time for dimension":t1-t0,
                "Time for solution":t3-t2,
                "Dimension":D,
                "Solution(s)":S}
    if D<0: # No solution.
        return {"Time for dimension":t1-t0,
                "Time for solution":t3-t2,
                "Dimension":D,
                "Solution(s)":[]}
    if D>0:
        # Infinite solutions. This shouldn't happen,
        # but I learned the virtues of defensive programming...
        return {"Time for dimension":t1-t0,
                "Time for solution":t3-t2,
                "Dimension":D,
                "Parent ring":R1,
                "Ideal to reprocess":J1}

But I have some serious doubts regarding the usefulness of this implementation :

  • Decomposing your $M$ as the sum of two matrices involves 34 indeterminates and 50 polynomials ; determining the variety of its ideal takes 4.17 seconds (0,3 seconds to check its dimension, 4 s for finding the two elements of its variety).

  • Decomposing it in the sum of 3 matrices involves 51 indeterminates and 67 polynomials, and hasn't finished in about 11 hours.

Combinatorial explosion is fast...

Unless my reasoning or my programming is|are faulty (which is of course possible), I do not realistically contemplate the use of this solution to decompose M in a sum of 6 matrices...

Hoping this non-help helps finding a better solution...