Example #1
0
    def _setup(self):
        self._ret['translation'] = sum(
            [abs(p[0]) for p in self._operator.get_flat_pauli_list()])
        self._ret['stretch'] = 0.5 / self._ret['translation']

        # translate the operator
        self._operator._simplify_paulis()
        translation_op = Operator([[
            self._ret['translation'],
            Pauli(np.zeros(self._operator.num_qubits),
                  np.zeros(self._operator.num_qubits))
        ]])
        translation_op._simplify_paulis()
        self._operator += translation_op

        self._pauli_list = self._operator.get_flat_pauli_list()

        # stretch the operator
        for p in self._pauli_list:
            p[0] = p[0] * self._ret['stretch']

        if len(self._pauli_list) == 1:
            slice_pauli_list = self._pauli_list
        else:
            if self._expansion_mode == 'trotter':
                slice_pauli_list = self._pauli_list
            else:
                slice_pauli_list = Operator._suzuki_expansion_slice_pauli_list(
                    self._pauli_list, 1, self._expansion_order)
        self._slice_pauli_list = slice_pauli_list
Example #2
0
    def __init__(self,
                 operator,
                 state_in,
                 iqft,
                 num_time_slices=1,
                 num_ancillae=1,
                 expansion_mode='trotter',
                 expansion_order=1,
                 shallow_circuit_concat=False):
        """
        Constructor.

        Args:
            operator (Operator): the hamiltonian Operator object
            state_in (InitialState): the InitialState pluggable component representing the initial quantum state
            iqft (IQFT): the Inverse Quantum Fourier Transform pluggable component
            num_time_slices (int): the number of time slices
            num_ancillae (int): the number of ancillary qubits to use for the measurement
            expansion_mode (str): the expansion mode (trotter|suzuki)
            expansion_order (int): the suzuki expansion order
            shallow_circuit_concat (bool): indicate whether to use shallow (cheap) mode for circuit concatenation
        """
        self.validate(locals())
        super().__init__()

        self._num_ancillae = num_ancillae
        self._ret = {}
        self._operator = deepcopy(operator)

        self._ret['translation'] = sum(
            [abs(p[0]) for p in self._operator.get_flat_pauli_list()])
        self._ret['stretch'] = 0.5 / self._ret['translation']

        # translate the operator
        self._operator._simplify_paulis()
        translation_op = Operator([[
            self._ret['translation'],
            Pauli(np.zeros(self._operator.num_qubits),
                  np.zeros(self._operator.num_qubits))
        ]])
        translation_op._simplify_paulis()
        self._operator += translation_op
        self._pauli_list = self._operator.get_flat_pauli_list()

        # stretch the operator
        for p in self._pauli_list:
            p[0] = p[0] * self._ret['stretch']

        self._phase_estimation_circuit = PhaseEstimationCircuit(
            operator=self._operator,
            state_in=state_in,
            iqft=iqft,
            num_time_slices=num_time_slices,
            num_ancillae=num_ancillae,
            expansion_mode=expansion_mode,
            expansion_order=expansion_order,
            shallow_circuit_concat=shallow_circuit_concat,
            pauli_list=self._pauli_list)
        self._binary_fractions = [1 / 2**p for p in range(1, num_ancillae + 1)]
Example #3
0
def limit_paulis(mat, n=5, sparsity=None):
    """
    Limits the number of Pauli basis matrices of a hermitian matrix to the n
    highest magnitude ones.
    Args:
        mat (np.ndarray): Input matrix
        n (int): number of surviving Pauli matrices (default=5)
        sparsity (float < 1): sparsity of matrix

    Returns:
        scipy.sparse.csr_matrix
    """
    from qiskit.aqua import Operator
    # Bringing matrix into form 2**Nx2**N
    _l = mat.shape[0]
    if np.log2(_l) % 1 != 0:
        k = int(2**np.ceil(np.log2(_l)))
        m = np.zeros([k, k], dtype=np.complex128)
        m[:_l, :_l] = mat
        m[_l:, _l:] = np.identity(k - _l)
        mat = m

    # Getting Pauli matrices
    op = Operator(matrix=mat)
    op._check_representation("paulis")
    op._simplify_paulis()
    paulis = sorted(op.paulis, key=lambda x: abs(x[0]), reverse=True)
    g = 2**op.num_qubits
    mat = scipy.sparse.csr_matrix(([], ([], [])),
                                  shape=(g, g),
                                  dtype=np.complex128)

    # Truncation
    if sparsity is None:
        for pa in paulis[:n]:
            mat += pa[0] * pa[1].to_spmatrix()
    else:
        idx = 0
        while mat[:_l, :_l].nnz / _l**2 < sparsity:
            mat += paulis[idx][0] * paulis[idx][1].to_spmatrix()
            idx += 1
        n = idx
    mat = mat.toarray()
    return mat[:_l, :_l]