(circuit, nqubits, identity_only, eps=1e-11)
Checks if a given scipy.sparse matrix is a scalar matrix.

    A scalar matrix is such that B = bI, where B is the scalar
    matrix, b is some scalar multiple, and I is the identity
    matrix.  A scalar matrix would have only the element b along
    it's main diagonal and zeroes elsewhere.

    Parameters
    ==========

    circuit : Gate tuple
        Sequence of quantum gates representing a quantum circuit
    nqubits : int
        Number of qubits in the circuit
    identity_only : bool
        Check for only identity matrices
    eps : number
        The tolerance value for zeroing out elements in the matrix.
        Values in the range [-eps, +eps] will be changed to a zero.
Checks if a given scipy.sparse matrix is a scalar matrix.
Checks if a given scipy . sparse matrix is a scalar matrix .
def is_scalar_sparse_matrix(circuit, nqubits, identity_only, eps=1e-11):
    """Checks if a given scipy.sparse matrix is a scalar matrix.

    A scalar matrix is such that B = bI, where B is the scalar
    matrix, b is some scalar multiple, and I is the identity
    matrix.  A scalar matrix would have only the element b along
    it's main diagonal and zeroes elsewhere.

    Parameters
    ==========

    circuit : Gate tuple
        Sequence of quantum gates representing a quantum circuit
    nqubits : int
        Number of qubits in the circuit
    identity_only : bool
        Check for only identity matrices
    eps : number
        The tolerance value for zeroing out elements in the matrix.
        Values in the range [-eps, +eps] will be changed to a zero.
    """

    if not np or not scipy:
        pass

    matrix = represent(Mul(*circuit), nqubits=nqubits,
                       format='scipy.sparse')

    # In some cases, represent returns a 1D scalar value in place
    # of a multi-dimensional scalar matrix
    if (isinstance(matrix, int)):
        return matrix == 1 if identity_only else True

    # If represent returns a matrix, check if the matrix is diagonal
    # and if every item along the diagonal is the same
    else:
        # Due to floating pointing operations, must zero out
        # elements that are "very" small in the dense matrix
        # See parameter for default value.

        # Get the ndarray version of the dense matrix
        dense_matrix = matrix.todense().getA()
        # Since complex values can't be compared, must split
        # the matrix into real and imaginary components
        # Find the real values in between -eps and eps
        bool_real = np.logical_and(dense_matrix.real > -eps,
                                   dense_matrix.real < eps)
        # Find the imaginary values between -eps and eps
        bool_imag = np.logical_and(dense_matrix.imag > -eps,
                                   dense_matrix.imag < eps)
        # Replaces values between -eps and eps with 0
        corrected_real = np.where(bool_real, 0.0, dense_matrix.real)
        corrected_imag = np.where(bool_imag, 0.0, dense_matrix.imag)
        # Convert the matrix with real values into imaginary values
        corrected_imag = corrected_imag * np.complex(1j)
        # Recombine the real and imaginary components
        corrected_dense = corrected_real + corrected_imag

        # Check if it's diagonal
        row_indices = corrected_dense.nonzero()[0]
        col_indices = corrected_dense.nonzero()[1]
        # Check if the rows indices and columns indices are the same
        # If they match, then matrix only contains elements along diagonal
        bool_indices = row_indices == col_indices
        is_diagonal = bool_indices.all()

        first_element = corrected_dense[0][0]
        # If the first element is a zero, then can't rescale matrix
        # and definitely not diagonal
        if (first_element == 0.0 + 0.0j):
            return False

        # The dimensions of the dense matrix should still
        # be 2^nqubits if there are elements all along the
        # the main diagonal
        trace_of_corrected = (corrected_dense/first_element).trace()
        expected_trace = pow(2, nqubits)
        has_correct_trace = trace_of_corrected == expected_trace

        # If only looking for identity matrices
        # first element must be a 1
        real_is_one = abs(first_element.real - 1.0) < eps
        imag_is_zero = abs(first_element.imag) < eps
        is_one = real_is_one and imag_is_zero
        is_identity = is_one if identity_only else True
        return bool(is_diagonal and has_correct_trace and is_identity)
def is_scalar_sparse_matrix ( circuit , nqubits , identity_only , eps = 1e-11 ) : if not np or not scipy : pass matrix = represent ( Mul ( * circuit ) , nqubits = nqubits , format = 'scipy.sparse' ) # In some cases, represent returns a 1D scalar value in place # of a multi-dimensional scalar matrix if ( isinstance ( matrix , int ) ) : return matrix == 1 if identity_only else True # If represent returns a matrix, check if the matrix is diagonal # and if every item along the diagonal is the same else : # Due to floating pointing operations, must zero out # elements that are "very" small in the dense matrix # See parameter for default value. # Get the ndarray version of the dense matrix dense_matrix = matrix . todense ( ) . getA ( ) # Since complex values can't be compared, must split # the matrix into real and imaginary components # Find the real values in between -eps and eps bool_real = np . logical_and ( dense_matrix . real > - eps , dense_matrix . real < eps ) # Find the imaginary values between -eps and eps bool_imag = np . logical_and ( dense_matrix . imag > - eps , dense_matrix . imag < eps ) # Replaces values between -eps and eps with 0 corrected_real = np . where ( bool_real , 0.0 , dense_matrix . real ) corrected_imag = np . where ( bool_imag , 0.0 , dense_matrix . imag ) # Convert the matrix with real values into imaginary values corrected_imag = corrected_imag * np . complex ( 1j ) # Recombine the real and imaginary components corrected_dense = corrected_real + corrected_imag # Check if it's diagonal row_indices = corrected_dense . nonzero ( ) [ 0 ] col_indices = corrected_dense . nonzero ( ) [ 1 ] # Check if the rows indices and columns indices are the same # If they match, then matrix only contains elements along diagonal bool_indices = row_indices == col_indices is_diagonal = bool_indices . all ( ) first_element = corrected_dense [ 0 ] [ 0 ] # If the first element is a zero, then can't rescale matrix # and definitely not diagonal if ( first_element == 0.0 + 0.0j ) : return False # The dimensions of the dense matrix should still # be 2^nqubits if there are elements all along the # the main diagonal trace_of_corrected = ( corrected_dense / first_element ) . trace ( ) expected_trace = pow ( 2 , nqubits ) has_correct_trace = trace_of_corrected == expected_trace # If only looking for identity matrices # first element must be a 1 real_is_one = abs ( first_element . real - 1.0 ) < eps imag_is_zero = abs ( first_element . imag ) < eps is_one = real_is_one and imag_is_zero is_identity = is_one if identity_only else True return bool ( is_diagonal and has_correct_trace and is_identity )