Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Finding Permutation Matrix with NumPy

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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]])

Rounding to a single decimal place reveals that this is indeed the correct permutation matrix:

In [5]: np.round(b @ np.linalg.inv(a))
Out[5]:
array([[-0., -0.,  1., -0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0., -0.,  1.],
       [ 1., -0.,  0.,  0.]])

If you’re like me, negative zero makes you uneasy, so cast to int if you want:

In [6]: np.round(b @ np.linalg.inv(a)).astype(int)
Out[6]:
array([[0, 0, 1, 0],
       [0, 1, 0, 0],
       [0, 0, 0, 1],
       [1, 0, 0, 0]])

As @Mad Physicist points out, you can also use > 0.5 to convert the matrix 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]])
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading