jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def flupai(self, non_negative=False) -> list:
        """
        Fast Linear Unmixing for PhotoAcoustic Imaging (FLUPAI) is based on
        SVD decomposition with a pseudo inverse, which is equivalent to a least squares
        ansatz for linear spectral unmixing of multi-spectral photoacoustic images.

        :return: list with unmixed images containing the chromophore concentration.
        :raise: SystemExit.
        """

        # reshape image data to [number of wavelength, number of pixel]
        dims_raw = np.shape(self.data)
        try:
            reshapedData = np.reshape(self.data, (dims_raw[0], -1))
        except Exception:
            self.logger.critical(f"FLUPAI failed probably caused by wrong input dimensions of {dims_raw}!")
            raise ValueError("Reshaping of input data failed. FLUPAI expects a 4 dimensional numpy array, "
                             "where the first dimension represents the wavelengths and the second, third and fourth "
                             "dimension are representing a single wavelength PA image.")

        # if non_negative is False, matmul of x = PI * b with x chromophore information,
        # PI pseudo inverse with absorber information and b containing the measured pixel,
        # else non-negative least squares is performed.
        try:
            if non_negative:
                output = []
                for i in range(np.shape(reshapedData)[1]):
                    foo, ris = nnls(np.array(self.absorption_matrix), reshapedData[:, i])
                    output.append(foo)

                output = np.swapaxes(output, axis1=0, axis2=1)
            else:
                self.pseudo_inverse_absorption_matrix = s.pinv(self.absorption_matrix)
                output = np.matmul(self.pseudo_inverse_absorption_matrix, reshapedData)

        except Exception as e:
            self.logger.critical(f"Matrix multiplication failed probably caused by mismatching dimensions of absorption"
                                 f"matrix ({len(self.absorption_matrix[1])}) and "
                                 f"input data ({dims_raw[0]})!")
            print(e)
            raise ValueError("Absorption matrix and input data must have matching sizes...")

    # write output into list of images containing the chromophore information
        numberChromophores = np.shape(output)[0]
        chromophores_concentrations = []
        for chromophore in range(numberChromophores):
            chromophores_concentrations.append(np.reshape(output[chromophore, :], (dims_raw[1:])))
        return chromophores_concentrations
//  [python]
def flupai(self, non_negative=False) -> list:
        """
        Fast Linear Unmixing for PhotoAcoustic Imaging (FLUPAI) is based on
        SVD decomposition with a pseudo inverse, which is equivalent to a least squares
        ansatz for linear spectral unmixing of multi-spectral photoacoustic images.

        :return: list with unmixed images containing the chromophore concentration.
        :raise: SystemExit.
        """

        # reshape image data to [number of wavelength, number of pixel]
        dims_raw = np.shape(self.data)
        try:
            reshapedData = np.reshape(self.data, (dims_raw[0], -1))
        except Exception:
            self.logger.critical(f"FLUPAI failed probably caused by wrong input dimensions of {dims_raw}!")
            raise ValueError("Reshaping of input data failed. FLUPAI expects a 4 dimensional numpy array, "
                             "where the first dimension represents the wavelengths and the second, third and fourth "
                             "dimension are representing a single wavelength PA image.")

        # if non_negative is False, matmul of x = PI * b with x chromophore information,
        # PI pseudo inverse with absorber information and b containing the measured pixel,
        # else non-negative least squares is performed.
        try:
            if non_negative:
                output = []
                for i in range(np.shape(reshapedData)[1]):
                    foo, ris = nnls(np.array(self.absorption_matrix), reshapedData[:, i])
                    output.append(foo)

                output = np.swapaxes(output, axis1=0, axis2=1)
            else:
                self.pseudo_inverse_absorption_matrix = linalg.pinv(self.absorption_matrix)
                output = np.matmul(self.pseudo_inverse_absorption_matrix, reshapedData)

        except Exception as e:
            self.logger.critical(f"Matrix multiplication failed probably caused by mismatching dimensions of absorption"
                                 f"matrix ({len(self.absorption_matrix[1])}) and "
                                 f"input data ({dims_raw[0]})!")
            print(e)
            raise ValueError("Absorption matrix and input data must have matching sizes...")

    # write output into list of images containing the chromophore information
        numberChromophores = np.shape(output)[0]
        chromophores_concentrations = []
        for chromophore in range(numberChromophores):
            chromophores_concentrations.append(np.reshape(output[chromophore, :], (dims_raw[1:])))
        return chromophores_concentrations
//  [python]
def regressOut(Y,X):
	"""
	regresses out X from Y
	"""
	Xd = s.pinv(X)
	Y_out = Y-X.dot(Xd.dot(Y))
	return Y_out
//  [python]
def regressOut(Y,X):
	"""
	regresses out X from Y
	"""
	Xd = LA.pinv(X)
	Y_out = Y-X.dot(Xd.dot(Y))
	return Y_out
//  [python]
def vertex_component_analysis(points):
    """ Vertex component analysis algorithm.

    Parameters
    ----------
    points: (N,d)array
        Data points.

    Returns
    -------
    simplex_indices: list of int
        Indices of the VCA simplex's corners.
    """
    dof = len(points[0])
    N_simplex = dof + 1  # Number of vertex in the base simplex

    valid_simplex = False
    while not valid_simplex:
        unit_vectors = generate_random_unit_vectors(dof, N_simplex)
        vertices = []  # List of arrays
        vertices_indices = []   # Indices of vertices
        for i in range(N_simplex):
            unit_vector = unit_vectors[i]

            # If there are more than two vertices: project along the normal direction
            if i >= 2:
                A = (np.array(vertices[1:]) - np.array(vertices[0])).T
                # unit_vector_projected = A.dot(np.linalg.inv(A.T.dot(A))).dot(A.T).dot(unit_vector)
                unit_vector_projected = A.dot(np.linalg.pinv(A)).dot(unit_vector)
                unit_vector = unit_vector - unit_vector_projected
            vertices_indices.append(np.argmax(points.dot(unit_vector)))
            vertices.append(points[vertices_indices[-1]])
        try:
            sciConvexHull(vertices)
            valid_simplex = True
        except Exception as e:
            print(e)
    return vertices_indices
//  [python]
def vertex_component_analysis(points):
    """ Vertex component analysis algorithm.

    Parameters
    ----------
    points: (N,d)array
        Data points.

    Returns
    -------
    simplex_indices: list of int
        Indices of the VCA simplex's corners.
    """
    dof = len(points[0])
    N_simplex = dof + 1  # Number of vertex in the base simplex

    valid_simplex = False
    while not valid_simplex:
        unit_vectors = generate_random_unit_vectors(dof, N_simplex)
        vertices = []  # List of arrays
        vertices_indices = []   # Indices of vertices
        for i in range(N_simplex):
            unit_vector = unit_vectors[i]

            # If there are more than two vertices: project along the normal direction
            if i >= 2:
                A = (np.array(vertices[1:]) - np.array(vertices[0])).T
                # unit_vector_projected = A.dot(np.linalg.inv(A.T.dot(A))).dot(A.T).dot(unit_vector)
                unit_vector_projected = A.dot(scipy.linalg.pinv(A)).dot(unit_vector)
                unit_vector = unit_vector - unit_vector_projected
            vertices_indices.append(np.argmax(points.dot(unit_vector)))
            vertices.append(points[vertices_indices[-1]])
        try:
            sciConvexHull(vertices)
            valid_simplex = True
        except Exception as e:
            print(e)
    return vertices_indices
//  [python]
def test_pinv_D():
    ## Test pseudo-inverse computation of a real double precision distributed matrix
    m, n = 39, 23

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.asfortranarray(gA)

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv2(dA)
    gpinvA = pinvA.to_global_array()

    if rank == 0:
        assert allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        assert allclose(gpinvA, s.pinv(gA)) # compare with scipy result
        if m == n:
            assert allclose(gpinvA, la.inv(gA))
//  [python]
def test_pinv_D():
    ## Test pseudo-inverse computation of a real double precision distributed matrix
    m, n = 39, 23

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.asfortranarray(gA)

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv2(dA)
    gpinvA = pinvA.to_global_array()

    if rank == 0:
        assert allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        assert allclose(gpinvA, la.pinv(gA)) # compare with scipy result
        if m == n:
            assert allclose(gpinvA, la.inv(gA))
//  [python]
def test_pinv_Z():
    ## Test pseudo-inverse computation of a complex double precision distributed matrix
    m, n = 72, 129

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = gA + 1.0J * np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.asfortranarray(gA)

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv2(dA)
    gpinvA = pinvA.to_global_array()

    if rank == 0:
        assert allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        assert allclose(gpinvA, s.pinv(gA)) # compare with scipy result
        if m == n:
            assert allclose(gpinvA, la.inv(gA))
//  [python]
def test_pinv_Z():
    ## Test pseudo-inverse computation of a complex double precision distributed matrix
    m, n = 72, 129

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = gA + 1.0J * np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.asfortranarray(gA)

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv2(dA)
    gpinvA = pinvA.to_global_array()

    if rank == 0:
        assert allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        assert allclose(gpinvA, la.pinv(gA)) # compare with scipy result
        if m == n:
            assert allclose(gpinvA, la.inv(gA))
//  [python]
def TikhonovRegularizationMDSlow(x, DiffOrderOrFilterCoefs, Lambda):
    x = np.array(x)
    if(np.isscalar(DiffOrderOrFilterCoefs) == True):
        l = np.zeros(DiffOrderOrFilterCoefs, dtype=int).tolist()
        l.append(1)
        l.extend(np.zeros(DiffOrderOrFilterCoefs, dtype=int).tolist())
        h = np.diff(l,DiffOrderOrFilterCoefs).tolist()
    else:
        h = DiffOrderOrFilterCoefs
    L = len(h)
    N = x.shape[len(x.shape)-1]

    a = np.zeros(N-L, dtype=int).tolist()
    a.insert(0, h[0])
    b = h.copy()
    b.extend(np.zeros(N-L, dtype=int).tolist())
    
    D = sparse.csr_matrix(linalg.toeplitz(a,b)) 
    F = (Lambda*(D.T*D) + np.eye(N))
    
    # Both ways of performing the matrix right division are equally efficient to my knowledge.
    # If there is any reason to chose one, go for it.
    #y = np.linalg.lstsq(F.T,x.T,rcond=None)[0].T
    y = np.dot(x, np.linalg.pinv(F)) 
    return y
//  [python]
def TikhonovRegularizationMDSlow(x, DiffOrderOrFilterCoefs, Lambda):
    x = np.array(x)
    if(np.isscalar(DiffOrderOrFilterCoefs) == True):
        l = np.zeros(DiffOrderOrFilterCoefs, dtype=int).tolist()
        l.append(1)
        l.extend(np.zeros(DiffOrderOrFilterCoefs, dtype=int).tolist())
        h = np.diff(l,DiffOrderOrFilterCoefs).tolist()
    else:
        h = DiffOrderOrFilterCoefs
    L = len(h)
    N = x.shape[len(x.shape)-1]

    a = np.zeros(N-L, dtype=int).tolist()
    a.insert(0, h[0])
    b = h.copy()
    b.extend(np.zeros(N-L, dtype=int).tolist())
    
    D = sparse.csr_matrix(linalg.toeplitz(a,b)) 
    F = (Lambda*(D.T*D) + np.eye(N))
    
    # Both ways of performing the matrix right division are equally efficient to my knowledge.
    # If there is any reason to chose one, go for it.
    #y = np.linalg.lstsq(F.T,x.T,rcond=None)[0].T
    y = np.dot(x, linalg.pinv(F)) 
    return y
//  [python]
def __init__(self, A):
        # A is a collection of column vectors
        [self.dim, _] = A.shape
        self.A = A
        self.P = la.inv(A.T @ A) @ A.T @ A
#        self.P = A @ la.inv(A.T @ A) @ A.T
        self.N = la.null_space(A.T)
//  [python]
def __init__(self, A):
        # A is a collection of column vectors
        [self.dim, _] = A.shape
        self.A = A
        self.P = la.pinv(A) @ A
#        self.P = A @ la.inv(A.T @ A) @ A.T
        self.N = la.null_space(A.T)
//  [python]
def get_vec(p1, cam_ob):
    #using blender cam (img plane corresponds to view through blender cam in gui)
    #[0,0] right top img plane
    #[640,0] left top img plane
    #[640,640] left bottom
    #[0, 640] right bottom
    #[320, 640] bottom middle
    P, K, RT = get_3x4_P_matrix_from_blender(cam_ob)

    X = np.dot(s.pinv(P), p1)
    X = X / X[3]
    XX = np.copy(X[0:3])

    return XX
//  [python]
def get_vec(p1, cam_ob):
    #using blender cam (img plane corresponds to view through blender cam in gui)
    #[0,0] right top img plane
    #[640,0] left top img plane
    #[640,640] left bottom
    #[0, 640] right bottom
    #[320, 640] bottom middle
    P, K, RT = get_3x4_P_matrix_from_blender(cam_ob)

    X = np.dot(lin.pinv(P), p1)
    X = X / X[3]
    XX = np.copy(X[0:3])

    return XX
//  [python]
def ridge(X, y, lmbda):
    '''
    RIDGE Ridge Regression.

      INPUT:  X: training sample features, P-by-N matrix.
              y: training sample labels, 1-by-N row vector.
              lmbda: regularization parameter.

      OUTPUT: w: learned parameters, (P+1)-by-1 column vector.

    NOTE: You can use pinv() if the matrix is singular.
    '''
    P, N = X.shape
    w = np.zeros((P + 1, 1))
    # YOUR CODE HERE
    # begin answer
    X = np.concatenate((np.ones((1, N)), X), axis = 0)
    regular = np.identity(P + 1)
    regular[0][0] = 0
    w = np.matmul(np.matmul(np.linalg.pinv(np.matmul(X, X.T) + lmbda * regular), X), y.T)
    # end answer
    return w
//  [python]
def ridge(X, y, lmbda):
    '''
    RIDGE Ridge Regression.

      INPUT:  X: training sample features, P-by-N matrix.
              y: training sample labels, 1-by-N row vector.
              lmbda: regularization parameter.

      OUTPUT: w: learned parameters, (P+1)-by-1 column vector.

    NOTE: You can use pinv() if the matrix is singular.
    '''
    P, N = X.shape
    w = np.zeros((P + 1, 1))
    # YOUR CODE HERE
    # begin answer
    X = np.concatenate((np.ones((1, N)), X), axis = 0)
    regular = np.identity(P + 1)
    regular[0][0] = 0
    w = np.matmul(np.matmul(scipy.linalg.pinv(np.matmul(X, X.T) + lmbda * regular), X), y.T)
    # end answer
    return w
//  [python]
def _invert_sig_t(sig_t: np.ndarray, lamb: float, rtol: float) -> np.ndarray:
        """Invert the correlation matrix. If the provided regularization values are not enough to stabilize the inversion process for the given matrix, the function calls itself recursively, increasing lamb and rtol by 10%.

        Args:
            sig_t (np.ndarray): the correlation matrix
            lamb (float): regularization term added to the diagonal of the sig_t matrix
            rtol (float): threshold to filter eigenvector with a eigenvalue under rtol make inversion biased but much more numerically robust

        Returns:
            np.ndarray: the inverse of the correlation matrix
        """
        try:
            np.fill_diagonal(sig_t, (1 + lamb))
            sig_t_inv = np.linalg.pinv(sig_t, rtol=rtol)
            return sig_t_inv
        except np.linalg.LinAlgError:
            return SummaryStatisticsImputation._invert_sig_t(
                sig_t, lamb * 1.1, rtol * 1.1
            )
//  [python]
def _invert_sig_t(sig_t: np.ndarray, lamb: float, rtol: float) -> np.ndarray:
        """Invert the correlation matrix. If the provided regularization values are not enough to stabilize the inversion process for the given matrix, the function calls itself recursively, increasing lamb and rtol by 10%.

        Args:
            sig_t (np.ndarray): the correlation matrix
            lamb (float): regularization term added to the diagonal of the sig_t matrix
            rtol (float): threshold to filter eigenvector with a eigenvalue under rtol make inversion biased but much more numerically robust

        Returns:
            np.ndarray: the inverse of the correlation matrix
        """
        try:
            np.fill_diagonal(sig_t, (1 + lamb))
            sig_t_inv = scipy.linalg.pinv(sig_t, rtol=rtol, atol=0)
            return sig_t_inv
        except np.linalg.LinAlgError:
            return SummaryStatisticsImputation._invert_sig_t(
                sig_t, lamb * 1.1, rtol * 1.1
            )
//  [python]
def FeCalc(self, Aoptimality=True):
        """
        Compute estimation efficiency.

        :param Aoptimality: Kind of optimality to optimize, A- or D-optimality
        :type Aoptimality: boolean
        """
        try:
            invM = scipy.linalg.inv(self.X)
        except scipy.linalg.LinAlgError:
            try:
                invM = np.linalg.pinv(self.X)
            except np.linalg.linalg.LinAlgError:
                invM = np.nan

        invM = np.array(invM)
        st1 = np.dot(self.CX, invM)
        CMC = np.dot(st1, t(self.CX))
        if Aoptimality is True:
            self.Fe = float(self.CX.shape[0] / np.matrix.trace(CMC))
        else:
            self.Fe = float(np.linalg.det(CMC) ** (-1 / len(self.C)))
        self.Fe = self.Fe / self.experiment.FeMax
        return self
//  [python]
def FeCalc(self, Aoptimality=True):
        """
        Compute estimation efficiency.

        :param Aoptimality: Kind of optimality to optimize, A- or D-optimality
        :type Aoptimality: boolean
        """
        try:
            invM = scipy.linalg.inv(self.X)
        except scipy.linalg.LinAlgError:
            try:
                invM = scipy.linalg.pinv(self.X)
            except np.linalg.linalg.LinAlgError:
                invM = np.nan

        invM = np.array(invM)
        st1 = np.dot(self.CX, invM)
        CMC = np.dot(st1, t(self.CX))
        if Aoptimality is True:
            self.Fe = float(self.CX.shape[0] / np.matrix.trace(CMC))
        else:
            self.Fe = float(np.linalg.det(CMC) ** (-1 / len(self.C)))
        self.Fe = self.Fe / self.experiment.FeMax
        return self
//  [python]
def FdCalc(self, Aoptimality=True):
        """
        Compute detection power.

        :param Aoptimality: Kind of optimality to optimize: A- or D-optimality
        :type Aoptimality: boolean
        """
        try:
            invM = scipy.linalg.inv(self.Z)
        except scipy.linalg.LinAlgError:
            try:
                invM = np.linalg.pinv(self.Z)
            except np.linalg.linalg.LinAlgError:
                invM = np.nan

        invM = np.array(invM)
        CMC = np.matrix(self.C) * invM * np.matrix(t(self.C))
        if Aoptimality is True:
            self.Fd = float(len(self.C) / np.matrix.trace(CMC))
        else:
            self.Fd = float(np.linalg.det(CMC) ** (-1 / len(self.C)))
        self.Fd = self.Fd / self.experiment.FdMax
        return self
//  [python]
def FdCalc(self, Aoptimality=True):
        """
        Compute detection power.

        :param Aoptimality: Kind of optimality to optimize: A- or D-optimality
        :type Aoptimality: boolean
        """
        try:
            invM = scipy.linalg.inv(self.Z)
        except scipy.linalg.LinAlgError:
            try:
                invM = scipy.linalg.pinv(self.Z)
            except np.linalg.linalg.LinAlgError:
                invM = np.nan

        invM = np.array(invM)
        CMC = np.matrix(self.C) * invM * np.matrix(t(self.C))
        if Aoptimality is True:
            self.Fd = float(len(self.C) / np.matrix.trace(CMC))
        else:
            self.Fd = float(np.linalg.det(CMC) ** (-1 / len(self.C)))
        self.Fd = self.Fd / self.experiment.FdMax
        return self
//  [python]
def invert_L1_norm(R, Alpha, y, max_iter=100, smoothing_facor=0.0):

    ifg = np.zeros(y.shape, np.float32)
    if smoothing_facor > 0:
        ifg = np.concatenate([y, ifg], dtype=np.float32).flatten()
        G = np.concatenate([R, Alpha], dtype=np.float32)
    else:
        ifg[:] = y[:]
    W = np.eye((ifg.shape[0]), dtype=np.float32)
    inv_Q = s.pinv(np.linalg.multi_dot([G.T, W, G])).astype(np.float32)
    Coef = np.linalg.multi_dot([G.T, W, ifg]).astype(np.float32)
    X = np.matmul(inv_Q, Coef).astype(np.float32)

    res = np.abs(ifg - np.matmul(G, X)).astype(np.float32)
    res[res < 1e-5] = 1e-5
    res1 = np.empty(res.shape, dtype=np.float32)
    res2 = np.empty(res.shape, dtype=np.float32)
    res1[:] = res[:]
    res2[:] = 1
    diff_res = np.max(np.abs(res1 - res2))

    for ii in range(max_iter):
        if diff_res <= 1e-3:
            break
        res1[:] = res2[:]
        W = np.diag(1/res.flatten())
        W = W / np.max(W)
        inv_Q = s.pinv(np.linalg.multi_dot([G.T, W, G])).astype(np.float32)
        Coef = np.linalg.multi_dot([G.T, W, ifg]).astype(np.float32)
        X = np.matmul(inv_Q, Coef).astype(np.float32)
        res = np.abs(ifg - np.matmul(G, X)).astype(np.float32)
        res[res < 1e-5] = 1e-5
        res2[:] = res[:]
        diff_res = np.max(np.abs(res1 - res2))
        if np.any(np.isnan(res)):
            break
    e1 = np.sum(res)

    X = X.reshape(-1, 1)
    return X, e1
//  [python]
def inverse_laplacian_matrix(  # pytype: disable=annotation-type-mismatch  # numpy-scalars
    shape: Sequence[int],
    grid_lengths: Optional[Sequence[float]] = None,
    boundary_conditions: Optional[BoundaryConditionsSpec] = None,
    dtype: np.dtype = _NP_DTYPE,
    use_pinv: bool = False) -> np.ndarray:
  """Returns the inverse Laplacian matrix for the given boundary conditions.

  Args:
    shape: The grid shape.
    grid_lengths: The grid lengths (the default value is 1).
    boundary_conditions: The boundary connditins (the default values are
      Dirichlet-0 values).
    dtype: The dtype (the default value is float32).
    use_pinv: The pseudo-inverse needs to be used in the all-Neumann case. It is
      not normally used in other cases. This argument is used by unit tests to
      demonstrate that the pseudo-inverse can be less accurate than `inv`.

  Returns:
    The inverse of the Laplacian matrix. In the all-Neumann case, or if
    `use_pinv` is `True`, the pseudo-inverse is returned.
  """
  lap = laplacian_matrix(shape, grid_lengths, boundary_conditions, dtype)
  # `pinv` needs to be used in the all-Neumann case. In all other cases, `inv`
  # is used. It can be more accurate.
  if use_pinv or boundary_conditions_all_neumann(boundary_conditions):
    return sp.linalg.pinv2(lap)
  else:
    return sp.linalg.inv(lap)
//  [python]
def inverse_laplacian_matrix(  # pytype: disable=annotation-type-mismatch  # numpy-scalars
    shape: Sequence[int],
    grid_lengths: Optional[Sequence[float]] = None,
    boundary_conditions: Optional[BoundaryConditionsSpec] = None,
    dtype: np.dtype = _NP_DTYPE,
    use_pinv: bool = False) -> np.ndarray:
  """Returns the inverse Laplacian matrix for the given boundary conditions.

  Args:
    shape: The grid shape.
    grid_lengths: The grid lengths (the default value is 1).
    boundary_conditions: The boundary connditins (the default values are
      Dirichlet-0 values).
    dtype: The dtype (the default value is float32).
    use_pinv: The pseudo-inverse needs to be used in the all-Neumann case. It is
      not normally used in other cases. This argument is used by unit tests to
      demonstrate that the pseudo-inverse can be less accurate than `inv`.

  Returns:
    The inverse of the Laplacian matrix. In the all-Neumann case, or if
    `use_pinv` is `True`, the pseudo-inverse is returned.
  """
  lap = laplacian_matrix(shape, grid_lengths, boundary_conditions, dtype)
  # `pinv` needs to be used in the all-Neumann case. In all other cases, `inv`
  # is used. It can be more accurate.
  if use_pinv or boundary_conditions_all_neumann(boundary_conditions):
    return sp.linalg.pinv(lap)
  else:
    return sp.linalg.inv(lap)
//  [python]
memMat = sp.matrix(memories).T
isingJ = sp.triu(memMat * sp.linalg.pinv2(memMat))
//  [python]
memMat = sp.matrix(memories).T
isingJ = sp.triu(memMat * sp.linalg.pinv(memMat))
//  [python]
def hypergeom_quasi_inverse(N, n):
    return scipy.linalg.pinv2(hypergeom_mat(N, n))
//  [python]
def hypergeom_quasi_inverse(N, n):
    return scipy.linalg.pinv(hypergeom_mat(N, n))
//  [python]
def mat_inv(A):
    B = scipy.linalg.pinv2(A)
    return B
//  [python]
def mat_inv(A):
#     I = numpy.eye(A.shape[0], A.shape[1])
    # B = scipy.linalg.pinv2(A)
    B = scipy.linalg.pinv(A)
    return B
//  [python]
def niqe(inputImgData):
    patch_size = 96
    module_path = dirname(__file__)

    # TODO: memoize
    params = scipy.io.loadmat(join(module_path, 'niqe_image_params.mat'))
    pop_mu = np.ravel(params["pop_mu"])
    pop_cov = params["pop_cov"]

    inputImgData = inputImgData.astype('float32')
    M, N = inputImgData.shape

    # assert C == 1, "niqe called with videos containing %d channels. Please supply only the luminance channel" % (C,)
    assert M > (
                patch_size * 2 + 1), "niqe called with small frame size, requires > 192x192 resolution video using current training parameters"
    assert N > (
                patch_size * 2 + 1), "niqe called with small frame size, requires > 192x192 resolution video using current training parameters"

    feats = get_patches_test_features(inputImgData, patch_size)
    sample_mu = np.mean(feats, axis=0)
    sample_cov = np.cov(feats.T)

    X = sample_mu - pop_mu
    covmat = ((pop_cov + sample_cov) / 2.0)
    pinvmat = scipy.linalg.pinv(covmat)
    niqe_score = np.sqrt(np.dot(np.dot(X, pinvmat), X))

    return niqe_score
//  [python]
def mlr(x,y,order):
	"""Multiple linear regression fit of the columns of matrix x
	(dependent variables) to constituent vector y (independent variables)
	order -     order of a smoothing polynomial, which can be included
	in the set of independent variables. If order is
	not specified, no background will be included.
	b -         fit coeffs
	f -         fit result (m x 1 column vector)
	r -         residual   (m x 1 column vector)
	"""
	if order > 0:
		s=scipy.ones((len(y),1))
		for j in range(order):
			s=scipy.concatenate((s,(scipy.arange(0,1+(1.0/(len(y)-1))-0.5/(len(y)-1),1.0/(len(y)-1))**j)[:,nA]),1)
		X=scipy.concatenate((x, s),1)
	else:
		X = x
	b = scipy.dot(scipy.dot(scipy.linalg.inv(scipy.dot(scipy.transpose(X),X)),scipy.transpose(X)),y)
	f = scipy.dot(X,b)
	r = y - f
	return b,f,r
//  [python]
def mlr(x,y,order):
	"""Multiple linear regression fit of the columns of matrix x
	(dependent variables) to constituent vector y (independent variables)
	order -     order of a smoothing polynomial, which can be included
	in the set of independent variables. If order is
	not specified, no background will be included.
	b -         fit coeffs
	f -         fit result (m x 1 column vector)
	r -         residual   (m x 1 column vector)
	"""
	if order > 0:
		s=scipy.ones((len(y),1))
		for j in range(order):
			s=scipy.concatenate((s,(scipy.arange(0,1+(1.0/(len(y)-1))-0.5/(len(y)-1),1.0/(len(y)-1))**j)[:,nA]),1)
		X=scipy.concatenate((x, s),1)
	else:
		X = x
	b = scipy.dot(scipy.dot(scipy.linalg.pinv(scipy.dot(scipy.transpose(X),X)),scipy.transpose(X)),y)
	f = scipy.dot(X,b)
	r = y - f
	return b,f,r
//  [python]
def calc_bvec_list(self):
        self.bvec = np.zeros([self.nb, 3])
        self.bvec_crys = np.zeros([self.nb, 3])
        self.wb = np.zeros([self.nb])
        for i in range(self.nb):
            self.bvec[i,:] = self.calc_bvec( self.nnkpts[0,i,:] )
            self.bvec_crys[i,:] = self.k_cart2crys( self.bvec[i,:] )
            #k = self.nnkp.kpoints[self.nnkp.nnkpts[0,i,0]-1]
            #kb = self.nnkp.kpoints[self.nnkp.nnkpts[0,i,1]-1]
            #self.bvec[i,:] = kb - k + np.array(self.nnkp.nnkpts[0,i,2:5])

        #self.bvec = np.matmul(self.bvec, self.nnkp.b)  # crystal coordinate -> cartesian
        #for i in range(self.nb):
        #    self.wb[i] = 3/self.nb/np.linalg.norm(self.bvec[i,:])**2
        bmat = np.zeros([self.nb, 9])
        for i in range(self.nb):
            bmat[i,:] = [ self.bvec[i,a]*self.bvec[i,b] for a,b in itertools.product(range(3), range(3)) ]
        delta_ab =  np.array([ a==b for a,b in itertools.product(range(3), range(3)) ]).astype(int)
        self.wb = np.matmul(delta_ab, np.linalg.pinv(bmat))
//  [python]
def calc_bvec_list(self):
        self.bvec = np.zeros([self.nb, 3])
        self.bvec_crys = np.zeros([self.nb, 3])
        self.wb = np.zeros([self.nb])
        for i in range(self.nb):
            self.bvec[i,:] = self.calc_bvec( self.nnkpts[0,i,:] )
            self.bvec_crys[i,:] = self.k_cart2crys( self.bvec[i,:] )
            #k = self.nnkp.kpoints[self.nnkp.nnkpts[0,i,0]-1]
            #kb = self.nnkp.kpoints[self.nnkp.nnkpts[0,i,1]-1]
            #self.bvec[i,:] = kb - k + np.array(self.nnkp.nnkpts[0,i,2:5])

        #self.bvec = np.matmul(self.bvec, self.nnkp.b)  # crystal coordinate -> cartesian
        #for i in range(self.nb):
        #    self.wb[i] = 3/self.nb/np.linalg.norm(self.bvec[i,:])**2
        bmat = np.zeros([self.nb, 9])
        for i in range(self.nb):
            bmat[i,:] = [ self.bvec[i,a]*self.bvec[i,b] for a,b in itertools.product(range(3), range(3)) ]
        delta_ab =  np.array([ a==b for a,b in itertools.product(range(3), range(3)) ]).astype(int)
        self.wb = np.matmul(delta_ab, scipy.linalg.pinv(bmat))
//  [python]
def preProcess(u,y,NumDict):
    
    NumInputs = u.shape[0]
    NumOutputs = y.shape[0]
    NumRows = NumDict['Rows']
    NumCols = NumDict['Columns']
    NSig = NumDict['Dimension']
    UPast,UFuture = getHankelMatrices(u,NumRows,NumCols)
    YPast,YFuture = getHankelMatrices(y,NumRows,NumCols)
    Data = np.vstack((UPast,UFuture,YPast))
    L = la.lstsq(Data.T,YFuture.T)[0].T
    Z = np.dot(L,Data)
    DataShift = np.vstack((UPast,UFuture[NumInputs:],YPast))
    LShift = la.lstsq(DataShift.T,YFuture[NumOutputs:].T)[0].T
    ZShift = np.dot(LShift,DataShift)

    L1 = L[:,:NumInputs*NumRows]
    L3 = L[:,2*NumInputs*NumRows:]

    LPast = np.hstack((L1,L3))
    DataPast = np.vstack((UPast,YPast))

    U, S, Vt = la.svd(np.dot(LPast,DataPast))
    
    Sig = np.diag(S[:NSig])
    SigRt = np.diag(np.sqrt(S[:NSig]))
    Gamma = np.dot(U[:,:NSig],SigRt)
    GammaLess = Gamma[:-NumOutputs]

    GammaPinv = s.pinv(Gamma)
    GammaLessPinv = s.pinv(GammaLess)

    GamShiftSolve = la.lstsq(GammaLess,ZShift)[0]


    GamSolve = la.lstsq(Gamma,Z)[0]
    GamData = np.vstack((GamSolve,UFuture))

    GamYData = np.vstack((GamShiftSolve,YFuture[:NumOutputs]))
    # Should probably move to a better output structure
    # One that doesn't depent so heavily on ordering

    GammaDict = {'Data':GamData,
                 'DataLess':GammaLess,
                 'DataY':GamYData,
                 'Pinv': GammaPinv,
                 'LessPinv': GammaLessPinv}
    return GammaDict,S
//  [python]
def preProcess(u,y,NumDict):
    
    NumInputs = u.shape[0]
    NumOutputs = y.shape[0]
    NumRows = NumDict['Rows']
    NumCols = NumDict['Columns']
    NSig = NumDict['Dimension']
    UPast,UFuture = getHankelMatrices(u,NumRows,NumCols)
    YPast,YFuture = getHankelMatrices(y,NumRows,NumCols)
    Data = np.vstack((UPast,UFuture,YPast))
    L = la.lstsq(Data.T,YFuture.T)[0].T
    Z = np.dot(L,Data)
    DataShift = np.vstack((UPast,UFuture[NumInputs:],YPast))
    LShift = la.lstsq(DataShift.T,YFuture[NumOutputs:].T)[0].T
    ZShift = np.dot(LShift,DataShift)

    L1 = L[:,:NumInputs*NumRows]
    L3 = L[:,2*NumInputs*NumRows:]

    LPast = np.hstack((L1,L3))
    DataPast = np.vstack((UPast,YPast))

    U, S, Vt = la.svd(np.dot(LPast,DataPast))
    
    Sig = np.diag(S[:NSig])
    SigRt = np.diag(np.sqrt(S[:NSig]))
    Gamma = np.dot(U[:,:NSig],SigRt)
    GammaLess = Gamma[:-NumOutputs]

    GammaPinv = la.pinv(Gamma)
    GammaLessPinv = la.pinv(GammaLess)

    GamShiftSolve = la.lstsq(GammaLess,ZShift)[0]


    GamSolve = la.lstsq(Gamma,Z)[0]
    GamData = np.vstack((GamSolve,UFuture))

    GamYData = np.vstack((GamShiftSolve,YFuture[:NumOutputs]))
    # Should probably move to a better output structure
    # One that doesn't depent so heavily on ordering

    GammaDict = {'Data':GamData,
                 'DataLess':GammaLess,
                 'DataY':GamYData,
                 'Pinv': GammaPinv,
                 'LessPinv': GammaLessPinv}
    return GammaDict,S
//  [python]
def _firls_even(numtaps, bands, desired):
    
    bands.shape = (-1, 2)
    desired.shape = (-1, 2)
    weights = np.ones(len(desired))
    M = int(numtaps / 2)
    
    # Compute M x M matrix Q (actually twice Q).
    n = np.arange(numtaps)[:, np.newaxis, np.newaxis]
    q = np.dot(np.diff(np.sinc(bands * n) * bands, axis=2)[:, :, 0], weights)
    Q1 = linalg.toeplitz(q[:M])
    Q2 = linalg.hankel(q[1:M + 1], q[M:])
    Q = Q1 + Q2
    
    # Compute M-vector b.
    k = np.arange(M) + .5
    e = bands[1]
    b = np.diff(e * np.sinc(e * k[:, np.newaxis])).reshape(-1)
    
    # Compute a (actually half a).
    a = np.dot(linalg.pinv(Q), b)
    
    # Compute h.
    h = np.concatenate((np.flipud(a), a))
    
    return h
//  [python]
def _firls_even(numtaps, bands, desired):
    
    # This function implements an algorithm similar to the one of the
    # SciPy `firls` function, but for even-length filters rather than
    # odd-length ones. See paper notes entitled "Least squares FIR
    # filter design for even N" for derivation. The derivation is
    # similar to that of Ivan Selesnick's "Linear-Phase FIR Filter
    # Design By Least Squares" (available online at
    # http://cnx.org/contents/eb1ecb35-03a9-4610-ba87-41cd771c95f2@7),
    # with due alteration of detail for even filter lengths.
    
    bands.shape = (-1, 2)
    desired.shape = (-1, 2)
    weights = np.ones(len(desired))
    M = int(numtaps / 2)
    
    # Compute M x M matrix Q (actually twice Q).
    n = np.arange(numtaps)[:, np.newaxis, np.newaxis]
    q = np.dot(np.diff(np.sinc(bands * n) * bands, axis=2)[:, :, 0], weights)
    Q1 = linalg.toeplitz(q[:M])
    Q2 = linalg.hankel(q[1:M + 1], q[M:])
    Q = Q1 + Q2
    
    # Compute M-vector b.
    k = np.arange(M) + .5
    e = bands[1]
    b = np.diff(e * np.sinc(e * k[:, np.newaxis])).reshape(-1)
    
    # Compute a (actually half a).
    a = np.dot(linalg.pinv(Q), b)
    
    # Compute h.
    h = np.concatenate((np.flipud(a), a))
    
    return h
//  [python]
def test_pinv_D():
    ## Test pseudo-inverse computation of a real double precision distributed matrix
    m, n = 9, 23

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.asfortranarray(gA)

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv(dA)
    gpinvA = pinvA.to_global_array()
    gpinvA = gpinvA[:n, :]

    if rank == 0:
        assert allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        assert allclose(gpinvA, s.pinv(gA)) # compare with scipy result
        if m == n:
            assert allclose(gpinvA, la.inv(gA))
//  [python]
def test_pinv_D():
    ## Test pseudo-inverse computation of a real double precision distributed matrix
    m, n = 9, 23

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.asfortranarray(gA)

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv(dA)
    gpinvA = pinvA.to_global_array()
    gpinvA = gpinvA[:n, :]

    if rank == 0:
        assert allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        assert allclose(gpinvA, la.pinv(gA)) # compare with scipy result
        if m == n:
            assert allclose(gpinvA, la.inv(gA))
//  [python]
def test_pinv_Z():
    ## Test pseudo-inverse computation of a complex double precision distributed matrix
    m, n = 7, 9

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = gA + 1.0J * np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.asfortranarray(gA)

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv(dA)
    gpinvA = pinvA.to_global_array()
    gpinvA = gpinvA[:n, :]

    if rank == 0:
        assert allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        assert allclose(gpinvA, la.pinv(gA)) # compare with scipy result
        if m == n:
            assert allclose(gpinvA, la.inv(gA))
//  [python]
def test_pinv_Z_alt():
    ## Test pseudo-inverse computation of a complex double precision distributed matrix
    m, n = 7, 4

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = gA + 1.0J * np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.dot(gA, gA.T.conj())
    assert np.linalg.matrix_rank(gA) < gA.shape[0] # no full rank
    gA = np.asfortranarray(gA)

    m, n = gA.shape

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv(dA)
    gpinvA = pinvA.to_global_array()
    gpinvA = gpinvA[:n, :]

    if rank == 0:
        assert not allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert not allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        spinvA = la.pinv2(gA)
        assert allclose(gA, np.dot(gA, np.dot(spinvA, gA)))
        assert allclose(spinvA, np.dot(spinvA, np.dot(gA, spinvA)))
        assert not allclose(gpinvA, la.pinv2(gA))
//  [python]
def test_pinv_Z_alt():
    ## Test pseudo-inverse computation of a complex double precision distributed matrix
    m, n = 7, 4

    gA = np.random.standard_normal((m, n)).astype(np.float64)
    gA = gA + 1.0J * np.random.standard_normal((m, n)).astype(np.float64)
    gA = np.dot(gA, gA.T.conj())
    assert np.linalg.matrix_rank(gA) < gA.shape[0] # no full rank
    gA = np.asfortranarray(gA)

    m, n = gA.shape

    dA = core.DistributedMatrix.from_global_array(gA, rank=0)

    pinvA = rt.pinv(dA)
    gpinvA = pinvA.to_global_array()
    gpinvA = gpinvA[:n, :]

    if rank == 0:
        assert not allclose(gA, np.dot(gA, np.dot(gpinvA, gA)))
        assert not allclose(gpinvA, np.dot(gpinvA, np.dot(gA, gpinvA)))
        spinvA = la.pinv(gA)
        assert allclose(gA, np.dot(gA, np.dot(spinvA, gA)))
        assert allclose(spinvA, np.dot(spinvA, np.dot(gA, spinvA)))
        assert not allclose(gpinvA, la.pinv(gA))
//  [python]
def jacobian_cond(m=None, scaled=True, order=None, pinv=False, jac=None):
    """
    Get the condition number of the scaled or unscaled Jacobian matrix of a model.

    Args:
        m: calculate the condition number of the Jacobian from this model.
        scaled: if True use scaled Jacobian, else use unscaled
        order: norm order, None = Frobenius, see scipy.sparse.linalg.norm for more
        pinv: Use pseudoinverse, works for non-square matrices
        jac: (optional) previously calculated Jacobian

    Returns:
        (float) Condition number
    """
    if jac is None:
        jac, _ = get_jacobian(m, scaled)
    jac = jac.tocsc()
    if jac.shape[0] != jac.shape[1] and not pinv:
        _log.warning("Nonsquare Jacobian using pseudo inverse")
        pinv = True
    if not pinv:
        jac_inv = spla.inv(jac)
        return spla.norm(jac, order) * spla.norm(jac_inv, order)
    else:
        jac_inv = spla.pinv(jac)
        return spla.norm(jac, order) * la.norm(jac_inv, order)
//  [python]
def jacobian_cond(m=None, scaled=True, order=None, pinv=False, jac=None):
    """
    Get the condition number of the scaled or unscaled Jacobian matrix of a model.

    Args:
        m: calculate the condition number of the Jacobian from this model.
        scaled: if True use scaled Jacobian, else use unscaled
        order: norm order, None = Frobenius, see scipy.sparse.linalg.norm for more
        pinv: Use pseudoinverse, works for non-square matrices
        jac: (optional) previously calculated Jacobian

    Returns:
        (float) Condition number
    """
    if jac is None:
        jac, _ = get_jacobian(m, scaled)
    jac = jac.tocsc()
    if jac.shape[0] != jac.shape[1] and not pinv:
        _log.warning("Nonsquare Jacobian using pseudo inverse")
        pinv = True
    if not pinv:
        jac_inv = spla.inv(jac)
        return spla.norm(jac, order) * spla.norm(jac_inv, order)
    else:
        jac_inv = la.pinv(jac.toarray())
        return spla.norm(jac, order) * la.norm(jac_inv, order)
//  [python]
def _calc_Hpinv(H: np.ndarray) -> np.ndarray:
    """Compute Moore-Penrose pseudoinverse of ``H``."""
    return s.pinv(H)
//  [python]
def _calc_Hpinv(H: np.ndarray) -> np.ndarray:
    """Compute Moore-Penrose pseudoinverse of ``H``."""
    return linalg.pinv(H)
//  [python]
def baseline(y, deg=None, max_it=None, tol=None):
    """
    Computes the baseline of a given data.

    Iteratively performs a polynomial fitting in the data to detect its
    baseline. At every iteration, the fitting weights on the regions with
    peaks are reduced to identify the baseline only.

    Parameters
    ----------
    y : ndarray
        Data to detect the baseline.
    deg : int (default: 3)
        Degree of the polynomial that will estimate the data baseline. A low
        degree may fail to detect all the baseline present, while a high
        degree may make the data too oscillatory, especially at the edges.
    max_it : int (default: 100)
        Maximum number of iterations to perform.
    tol : float (default: 1e-3)
        Tolerance to use when comparing the difference between the current
        fit coefficients and the ones from the last iteration. The iteration
        procedure will stop when the difference between them is lower than
        *tol*.

    Returns
    -------
    ndarray
        Array with the baseline amplitude for every original point in *y*
    """
    # for not repeating ourselves in `envelope`
    if deg is None: deg = 3
    if max_it is None: max_it = 100
    if tol is None: tol = 1e-3
    
    order = deg + 1
    coeffs = np.ones(order)

    # try to avoid numerical issues
    cond = math.pow(abs(y).max(), 1. / order)
    x = np.linspace(0., cond, y.size)
    base = y.copy()

    vander = np.vander(x, order)
    vander_pinv = np.linalg.pinv(vander)

    for _ in range(max_it):
        coeffs_new = np.dot(vander_pinv, y)

        if LA.norm(coeffs_new - coeffs) / LA.norm(coeffs) < tol:
            break

        coeffs = coeffs_new
        base = np.dot(vander, coeffs)
        y = np.minimum(y, base)

    return base
//  [python]
def pinv(M: np.ndarray, var: Variable) -> np.ndarray:
    '''Computes np.linalg.pinv but it also saves the array that crashed it if
    it crashes.

    Parameters
    ----------
    M : nxn matrix (np.ndarray, scipy.sparse)
        Matrix to invert
    var : pl.variable.Variable subclass
        This is the variable that `pinv` was called from

    Returns
    -------
    np.ndarray
        Inverse of the matrix
    '''
    if scipy.sparse.issparse(M):
        M_ = np.zeros(shape=M.shape)
        M.toarray(out=M_)
        M = M_
    try:
        try:
            return np.linalg.pinv(M)
        except:
            try:
                return scipy.linalg.pinv2(M)
            except:
                return scipy.linalg.inv(M)
    except:
        try:
            sample_iter = var.sample_iter
        except:
            sample_iter = None
        filename = 'crashes/pinv_error_iter{}_var{}pinv_{}.npy'.format(
            sample_iter, var.name, var.G.name)
        logger.critical('\n\n\n\n\n\n\n\nSaved array at "{}" - now crashing\n\n\n'.format(
                filename))
        os.makedirs('crashes/', exist_ok=True)
        np.save(filename, M)
        raise
//  [python]
def pinv(M: np.ndarray, var: Variable) -> np.ndarray:
    '''Computes np.linalg.pinv but it also saves the array that crashed it if
    it crashes.

    Parameters
    ----------
    M : nxn matrix (np.ndarray, scipy.sparse)
        Matrix to invert
    var : pl.variable.Variable subclass
        This is the variable that `pinv` was called from

    Returns
    -------
    np.ndarray
        Inverse of the matrix
    '''
    if scipy.sparse.issparse(M):
        M_ = np.zeros(shape=M.shape)
        M.toarray(out=M_)
        M = M_
    try:
        try:
            return np.linalg.pinv(M)
        except:
            try:
                return scipy.linalg.pinv(M)
            except:
                return scipy.linalg.inv(M)
    except:
        try:
            sample_iter = var.sample_iter
        except:
            sample_iter = None
        filename = 'crashes/pinv_error_iter{}_var{}pinv_{}.npy'.format(
            sample_iter, var.name, var.G.name)
        logger.critical('\n\n\n\n\n\n\n\nSaved array at "{}" - now crashing\n\n\n'.format(
                filename))
        os.makedirs('crashes/', exist_ok=True)
        np.save(filename, M)
        raise
//  [python]
def niqe(inputImgData):

    patch_size = 96
    module_path = dirname(__file__)

    # TODO: memoize
    params = scipy.io.loadmat(
        join(module_path, 'modelparameters.mat'))
    pop_mu = np.ravel(params['mu_prisparam'])
    pop_cov = params['cov_prisparam']
    # pop_mu = np.ravel(params["pop_mu"])
    # pop_cov = params["pop_cov"]

    if inputImgData.ndim == 3:
        inputImgData = cv2.cvtColor(inputImgData, cv2.COLOR_BGR2GRAY)
    M, N = inputImgData.shape

    # assert C == 1, "niqe called with videos containing %d channels. Please supply only the luminance channel" % (C,)
    assert M > (patch_size*2+1), "niqe called with small frame size, requires > 192x192 resolution video using current training parameters"
    assert N > (patch_size*2+1), "niqe called with small frame size, requires > 192x192 resolution video using current training parameters"

    feats = get_patches_test_features(inputImgData, patch_size)
    sample_mu = np.mean(feats, axis=0)
    sample_cov = np.cov(feats.T)

    X = sample_mu - pop_mu
    covmat = ((pop_cov+sample_cov)/2.0)
    pinvmat = scipy.linalg.pinv2(covmat)
    niqe_score = np.sqrt(np.dot(np.dot(X, pinvmat), X))

    return niqe_score
//  [python]
def niqe(inputImgData):

    patch_size = 96
    module_path = dirname(__file__)

    # TODO: memoize
    params = scipy.io.loadmat(
        join(module_path, 'modelparameters.mat'))
    pop_mu = np.ravel(params['mu_prisparam'])
    pop_cov = params['cov_prisparam']
    # pop_mu = np.ravel(params["pop_mu"])
    # pop_cov = params["pop_cov"]

    if inputImgData.ndim == 3:
        inputImgData = cv2.cvtColor(inputImgData, cv2.COLOR_BGR2GRAY)
    M, N = inputImgData.shape

    # assert C == 1, "niqe called with videos containing %d channels. Please supply only the luminance channel" % (C,)
    assert M > (patch_size*2+1), "niqe called with small frame size, requires > 192x192 resolution video using current training parameters"
    assert N > (patch_size*2+1), "niqe called with small frame size, requires > 192x192 resolution video using current training parameters"

    feats = get_patches_test_features(inputImgData, patch_size)
    sample_mu = np.mean(feats, axis=0)
    sample_cov = np.cov(feats.T)

    X = sample_mu - pop_mu
    covmat = ((pop_cov+sample_cov)/2.0)
    pinvmat = scipy.linalg.pinv(covmat)
    niqe_score = np.sqrt(np.dot(np.dot(X, pinvmat), X))

    return niqe_score