pythonnumpyone-liner

Skip over numpy.linalg.LinAlg error : Singular matrix in a one liner


I have a dictionary whose values are matrices. I want to invert these matrices but some of them are singular, hence I get thrown the Singular matrix error when running the program. Here is a minimum reproducible example :

import numpy as np
N = 10

x = np.arange(N)

def matrix(z):
    return np.array([[z*(z+1), z*(z+2)], [(z+2)*(z+3), (z+3)*(z+4)]])
    

example_dict = dict(zip(map(str,x), map(matrix, x)))

{k:np.linalg.inv(v) for k,v in example_dict.items()}

The error message is :

raise LinAlgError("Singular matrix")
numpy.linalg.LinAlgError: Singular matrix

Is there a way I can rectify this in the single line itself? I can rewrite the code as a full for loop block and catch this, but I am looking for a more elegant solution.


Solution

  • If by "elegant" you mean comprehensions, the feature you want was rejected ten years ago: https://peps.python.org/pep-0463/

    Your best bet is to do this with a for loop, or wrap the operation in a function:

    def true_inv(v):                                                                                                       
        try:                                                                                                              
            return np.linalg.inv(v)                                                                                       
        except np.linalg.LinAlgError:                                                                                     
            print("Matrix doesn't have inverse. Moving to next...")                                                       
            return None                                                                                       
                                                                                                                          
                                                                                                                          
                                                                                                                          
    {k:true_inv(v) for k, v in example_dict.items()}