Search code examples
matrixsympymatrix-multiplication

Iterating through and operating on Sympy Matrices


My modified block of code from here works for XOR'ing python lists via using functions (XOR and AND) of the Sympy library (first block of code below). However, I am stumped on how to iterate via sympy matrices (second block of code below).

The python lists code that works is:

from sympy import And, Xor
from sympy.logic import SOPform, simplify_logic
from sympy import symbols
def LogMatrixMult (A, B):
    rows_A = len(A)
    cols_A = len(A[0])
    rows_B = len(B)
    cols_B = len(B[0])

    if cols_A != rows_B:
      print ("Cannot multiply the two matrices. Incorrect dimensions.")
      return

    # Create the result matrix
    # Dimensions would be rows_A x cols_B
    C = [[0 for row in range(cols_B)] for col in range(rows_A)]
    for i in range(rows_A):
        for j in range(cols_B):
            for k in range(cols_A):
                # I can add Sympy's in simplify_logic(-)
                C[i][j] = Xor(C[i][j], And(A[i][k], B[k][j]))
    return C
b, c, d, e, f, w, x, y, z = symbols('b c d e f w x y z')
m1 = [[b,c,d,e]]
m2 = [[w,x],[x,z],[y,z],[z,w]]

result = simplify_logic(LogMatrixMult(m1, m2)[0][0])
print(result)

In the block below using Sympy matrices note that the i,j,k and C, A, B definitions is from me trying to modify to use the iterator, I don't know if this needed or correct.

from sympy import And, Xor
from sympy.matrices import Matrix
from sympy.logic import SOPform, simplify_logic
from sympy import symbols, IndexedBase, Idx
from sympy import symbols

def LogMatrixMultArr (A, B):
    rows_A = A.rows
    cols_A = A.cols
    rows_B = B.rows
    cols_B = B.cols
    i,j,k = symbols('i j k', cls=Idx)
    C = IndexedBase('C')
    A = IndexedBase('A')
    B = IndexedBase('B')

    if cols_A != rows_B:
      print ("Cannot multiply the two matrices. Incorrect dimensions.")
      return

    # Create the result matrix
    # Dimensions would be rows_A x cols_B
    C = [[0 for row in range(cols_B)] for col in range(rows_A)]
    for i in range(rows_A):
        for j in range(cols_B):
            for k in range(cols_A):
                # I can add Sympy's in simplify_logic(-)
                C[i,j] = Xor(C[i,j], And(A[i,k], B[k,j]))
                # C[i][j] = Xor(C[i][j],And(A[i][k],B[k][j]))
    return C
b, c, d, e, f, w, x, y, z = symbols('b c d e f w x y z')
P = Matrix([w,x]).reshape(1,2)
Q = Matrix([y,z])
print(LogMatrixMultArr(P,Q))

The error I get is: TypeError: list indices must be integers or slices, not tuple

C[i,j] = Xor(C[i,j], And(A[i,k], B[k,j]))

Now I believe I have to do something with some special way of sympy's iterating but am stuck on how to get it to work in the code - if I do even need this methodology.

Also, if anyone knows how to do something such as the above using XOR and And (non-bitwise) instead of + and * operators in a faster way, please do share.

Thanks.


Solution

  • I think the problem is with IndexedBase objects. I'm not competent on these but it seems you do not use them right. If you replace

        i,j,k = symbols('i j k', cls=Idx)
        C = IndexedBase('C')
        A = IndexedBase('A')
        B = IndexedBase('B')
    

    by

        C = zeros(rows_A, cols_B)
    

    and remove C = [[0 for row in range(cols_B)] for col in range(rows_A)], then it works.