def matrix_is_psd(M): err = True s, u = eigh(M, lower=True, check_finite=True) eps = _multivariate._eigvalsh_to_eps(s, None, None) if np.min(s) < -eps: err = False return err
def matrix_is_not_singular(M): err = True s, u = eigh(M, lower=True, check_finite=True) eps = _multivariate._eigvalsh_to_eps(s, None, None) d = s[s > eps] if len(d) < len(s): err = False return err
def matrix_is_well_conditioned(M): err = True s, u = eigh(M, lower=True, check_finite=True) eps = _multivariate._eigvalsh_to_eps(s, None, None) if np.min(s) < -eps: err = False d = s[s > eps] if len(d) < len(s): err = False return err
def is_valid_covariance_matrix(cov_matrix): """ Checks if valid covariance matrix. Computes the eigenvalues and checks for negative ones. Also checks if the matrix is singular. Args: cov_matrix: a matrix to be checked. Returns: True if the array is valid covariance matrix and False otherwise. """ # Check for complex elements if np.sum(np.where(np.iscomplex(cov_matrix))) > 0: return False # Check eigenvalues try: eig_values = eigh(cov_matrix, lower=True, check_finite=True)[0] eps = _eigvalsh_to_eps(eig_values, None, None) except ValueError: print(cov_matrix) return False # Singular matrix (too small eigenvalues) if np.min(eig_values) < -eps: return False large_eig_values = eig_values[eig_values > eps] if len(large_eig_values) < len(eig_values): return False # Negative eigenvalues if np.min(eig_values) < 0.0: return False return True
def problematic_hessian(hessian, check_pd=True, check_sing=True, verbose=False): """ Checks if the Hessian (covariance matrix) is problematic. Computes the eigenvalues and checks for negative ones. Also checks if the matrix is singular. Args: hessian: a matrix to be checked. Returns: True if the array is valid covariance matrix and False otherwise. """ if hessian is None: return True # Check for nan and inf if np.isnan(hessian).any(): if verbose: print("Warning: some Hessian elements are not finite...") return True # Check for nan and inf if not np.all(np.isfinite(hessian)): if verbose: print("Warning: some Hessian elements are not finite...") return True # Check for nan and inf if np.any(np.isnan(hessian)): if verbose: print("Warning: some Hessian elements are NaN...") return True # Check for complex elements if np.any(np.iscomplex(hessian)): if verbose: print("Warning: some Hessian elements are complex...") return True # Check for large elements if np.any(np.diag(hessian) > 1e20): if verbose: print("Warning: some Hessian elements are too large...") return True # Singular matrix (too small eigenvalues) # Negative eigenvalues flag = False try: eig_values = eigh(hessian, lower=True, check_finite=True)[0] eps = _eigvalsh_to_eps(eig_values, None, None) if check_sing and (np.abs(eig_values) < eps).any(): flag = True if verbose: print( "Warning: Hessian has very small eigenvalues: {}.".format( np.min(eig_values))) large_eig_values = eig_values[np.abs(eig_values) > eps] if check_sing and len(large_eig_values) < len(eig_values): if verbose: print("Warning: Hessian is illconditioned with eigenvalues:") print(eig_values) flag = True if check_pd and np.min(eig_values) < 0.0: if verbose: neg_eig_values = eig_values[eig_values < 0.0] print("Warning: Hessian has negative eigenvalues: {}".format( neg_eig_values)) flag = True except Exception as e: print(e) raise Warning( "Numerical issues in eigenvalue computations, rejecting.") flag = True return flag