Finding Permutation Matrix with NumPy

Question:

I am looking for the correct permutation matrix that would take matrix a and turn it into matrix b given

a = np.array([[1,4,7,-2],[3,0,-2,-1],[-4,2,1,0],[-8,-3,-1,2]])
b = np.array([[-4,2,1,0],[3,0,-2,-1],[-8,-3,-1,2],[1,4,7,-2]])

I tried

x = np.linalg.solve(a,b)

However, I know this is incorrect and it should be

np.array([[0,0,1,0],[0,1,0,0],[0,0,0,1],[1,0,0,0]])

What numpy code would deliver this matrix from the other two?

Asked By: talkingtoducks

||

Answers:

Generally, if you have some PA = B and you want P then you need to solve the equation for P. Matrix multiplication is not commutative, so you have to right multiply both sides by the inverse of A. With numpy, the function to get the inverse of a matrix is np.linalg.inv().

Using the matrix multiplication operator @, you can right-multiply with b to get P, taking note that you will end up with floating point precision errors:

In [4]: b @ np.linalg.inv(a)
Out[4]:
array([[-1.38777878e-16, -3.05311332e-16,  1.00000000e+00,
        -1.31838984e-16],
       [ 0.00000000e+00,  1.00000000e+00,  6.93889390e-17,
         0.00000000e+00],
       [ 0.00000000e+00,  0.00000000e+00, -1.11022302e-16,
         1.00000000e+00],
       [ 1.00000000e+00, -4.44089210e-16,  5.55111512e-17,
         0.00000000e+00]])

As @Mad Physicist points out, you can compare this matrix with > 0.5 to convert it to a boolean matrix:

In [7]: bool_P = (b @ np.linalg.inv(a)) > 0.5

In [8]: bool_P @ a
Out[8]:
array([[-4,  2,  1,  0],
       [ 3,  0, -2, -1],
       [-8, -3, -1,  2],
       [ 1,  4,  7, -2]])

In [9]: bool_P @ a == b  # our original equation, PA = B
Out[9]:
array([[ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True]])
Answered By: ddejohn

solve computes x in the equation Ax = B. You can use it, but the arguments have to match.

Your equation is XA = B. You can take the transpose of both sides to get ATXT = BT, which has the correct form. So you can get the result from

np.linalg.solve(A.T, B.T).T

To get a boolean result that’s guaranteed to be zeros and ones, you can apply a threshold:

np.linalg.solve(A.T, B.T).T > 0.5
Answered By: Mad Physicist
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.