Exemplo n.º 1
0
def plot_bloch_multivector(rho, title='', figsize=None):
    """Plot the Bloch sphere.

    Plot a sphere, axes, the Bloch vector, and its projections onto each axis.

    Args:
        rho (ndarray): Numpy array for state vector or density matrix.
        title (str): a string that represents the plot title
        figsize (tuple): Has no effect, here for compatibility only.

    Returns:
        matplotlib.Figure:
            A matplotlib figure instance.

    Raises:
        ImportError: Requires matplotlib.

    Example:
        .. jupyter-execute::

            from qiskit import QuantumCircuit, BasicAer, execute
            from qiskit.visualization import plot_bloch_multivector
            %matplotlib inline

            qc = QuantumCircuit(2, 2)
            qc.h(0)
            qc.cx(0, 1)
            qc.measure([0, 1], [0, 1])

            backend = BasicAer.get_backend('statevector_simulator')
            job = execute(qc, backend).result()
            plot_bloch_multivector(job.get_statevector(qc), title="New Bloch Multivector")
    """
    if not HAS_MATPLOTLIB:
        raise ImportError(
            'Must have Matplotlib installed. To install, run "pip install '
            'matplotlib".')
    rho = _validate_input_state(rho)
    num = int(np.log2(len(rho)))
    width, height = plt.figaspect(1 / num)
    fig = plt.figure(figsize=(width, height))
    for i in range(num):
        ax = fig.add_subplot(1, num, i + 1, projection='3d')
        pauli_singles = [
            Pauli.pauli_single(num, i, 'X'),
            Pauli.pauli_single(num, i, 'Y'),
            Pauli.pauli_single(num, i, 'Z')
        ]
        bloch_state = list(
            map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
                pauli_singles))
        plot_bloch_vector(bloch_state,
                          "qubit " + str(i),
                          ax=ax,
                          figsize=figsize)
    fig.suptitle(title, fontsize=16)
    if get_backend() in ['module://ipykernel.pylab.backend_inline', 'nbAgg']:
        plt.close(fig)
    return fig
Exemplo n.º 2
0
    def test_pauli_error_2q_gate_from_pauli(self):
        """Test two-qubit pauli error as gate qobj from Pauli obj"""
        paulis = [Pauli.from_label(s) for s in ['XZ', 'YX', 'ZY']]
        probs = [0.5, 0.3, 0.2]
        error = pauli_error(zip(paulis, probs), standard_gates=True)

        target_circs = [[{
            "name": "z",
            "qubits": [0]
        }, {
            "name": "x",
            "qubits": [1]
        }], [{
            "name": "x",
            "qubits": [0]
        }, {
            "name": "y",
            "qubits": [1]
        }], [{
            "name": "y",
            "qubits": [0]
        }, {
            "name": "z",
            "qubits": [1]
        }]]
        target_probs = probs.copy()

        for j in range(len(paulis)):
            circ, p = error.error_term(j)
            self.remove_if_found(p, target_probs)
            self.remove_if_found(circ, target_circs)
        self.assertEqual(target_probs, [], msg="Incorrect probabilities")
        self.assertEqual(target_circs, [], msg="Incorrect circuits")
Exemplo n.º 3
0
    def test_pauli_error_1q_unitary_from_pauli(self):
        """Test single-qubit pauli error as unitary qobj from Pauli obj"""
        paulis = [Pauli.from_label(s) for s in ['I', 'X', 'Y', 'Z']]
        probs = [0.4, 0.3, 0.2, 0.1]
        error = pauli_error(zip(paulis, probs), standard_gates=False)

        target_unitaries = [
            standard_gate_unitary('x'),
            standard_gate_unitary('y'),
            standard_gate_unitary('z')
        ]
        target_probs = probs.copy()
        target_identity_count = 0
        for j in range(len(paulis)):
            circ, p = error.error_term(j)
            name = circ[0]['name']
            self.assertIn(name, ('unitary', 'id'))
            self.assertEqual(circ[0]['qubits'], [0])
            self.remove_if_found(p, target_probs)
            if name == "unitary":
                self.remove_if_found(circ[0]['params'][0], target_unitaries)
            else:
                target_identity_count += 1
        self.assertEqual(target_probs, [], msg="Incorrect probabilities")
        self.assertEqual(target_unitaries, [], msg="Incorrect unitaries")
        self.assertEqual(target_identity_count, 1, msg="Incorrect identities")
Exemplo n.º 4
0
def heisenberg1D(num_qubits):
    '''construct the 1D Heisenberg model with open
       boundary conditions:
         1/4 * \sum_i (X_i X_{i+1} + Y_i Y_{i+1} + Z_i Z_{i+1})

       Inputs:
         num_qubits the number of qubits (spins) in the chain
    
       Returns:
         Operator (SummedOp of PauliOps) representing the Hamiltonian
    '''

    ind_op = 0
    coeff = 0.25
    for i in range(num_qubits - 1):
        for pauli_label in ['X', 'Y', 'Z']:
            labels = ['I'] * (i) + [pauli_label, pauli_label
                                    ] + ['I'] * (num_qubits - (i + 2))

            pauli = Pauli(label=labels)
            pauli_op = PauliOp(pauli, coeff)

            if ind_op == 0:
                hamiltonian = pauli_op
            else:
                hamiltonian += pauli_op

            ind_op += 1

    return hamiltonian
Exemplo n.º 5
0
def magnetic_fields(potentials):
    '''construct magnetic fields of the form
         1/2 * \sum_i h_i Z_i

       Inputs:
         potentials a list or ndarray representing the potential h_i
    
       Returns:
         Operator (SummedOp of PauliOps) representing the magnetic fields
    '''

    num_qubits = len(potentials)

    for i in range(num_qubits):
        coeff = 0.5 * potentials[i]
        labels = ['I'] * (i) + ['Z'] + ['I'] * (num_qubits - (i + 1))

        pauli = Pauli(label=labels)
        pauli_op = PauliOp(pauli, coeff)

        if i == 0:
            op = pauli_op
        else:
            op += pauli_op

    return op
Exemplo n.º 6
0
 def to_pauli(op):
     if isinstance(op, Pauli):
         return op
     elif isinstance(op, str):
         try:
             return Pauli(op)
         except QiskitError:
             pass
     raise NoiseError("Invalid Pauli input operator: {}".format(op))
Exemplo n.º 7
0
def get_bloch_vectors(qc):
    rho = what_is_the_density_matrix(qc)
    bit_size = int(log2(rho.shape[0]))

    bloch_array = []
    for current_bit in range(bit_size):
        x_component = np.real(
            np.trace(
                Pauli.pauli_single(bit_size, current_bit, 'X').to_matrix()
                @ rho))
        y_component = np.real(
            np.trace(
                Pauli.pauli_single(bit_size, current_bit, 'Y').to_matrix()
                @ rho))
        z_component = np.real(
            np.trace(
                Pauli.pauli_single(bit_size, current_bit, 'Z').to_matrix()
                @ rho))
        bloch_array.append([x_component, y_component, z_component])
    return bloch_array
Exemplo n.º 8
0
 def test_init_from_pauli(self):
     """Test initialization from Pauli"""
     samples = 10
     nseed = 999
     for qubit_num in range(1, 5):
         for i in range(samples):
             pauli = Pauli.random(qubit_num, seed=nseed + i)
             elem = CNOTDihedral(pauli)
             value = Operator(pauli)
             target = Operator(elem)
             self.assertTrue(value.equiv(target),
                             'Error: Pauli operator is not the same.')
Exemplo n.º 9
0
def plot_bloch_multivector(rho, title='', figsize=None):
    """Plot the Bloch sphere.

    Plot a sphere, axes, the Bloch vector, and its projections onto each axis.

    Args:
        rho (ndarray): Numpy array for state vector or density matrix.
        title (str): a string that represents the plot title
        figsize (tuple): Has no effect, here for compatibility only.

    Returns:
        Figure: A matplotlib figure instance.

    Raises:
        ImportError: Requires matplotlib.
    """
    if not HAS_MATPLOTLIB:
        raise ImportError('Must have Matplotlib installed.')
    rho = _validate_input_state(rho)
    num = int(np.log2(len(rho)))
    width, height = plt.figaspect(1 / num)
    fig = plt.figure(figsize=(width, height))
    for i in range(num):
        ax = fig.add_subplot(1, num, i + 1, projection='3d')
        pauli_singles = [
            Pauli.pauli_single(num, i, 'X'),
            Pauli.pauli_single(num, i, 'Y'),
            Pauli.pauli_single(num, i, 'Z')
        ]
        bloch_state = list(
            map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
                pauli_singles))
        plot_bloch_vector(bloch_state,
                          "qubit " + str(i),
                          ax=ax,
                          figsize=figsize)
    fig.suptitle(title, fontsize=16)
    if get_backend() in ['module://ipykernel.pylab.backend_inline', 'nbAgg']:
        plt.close(fig)
    return fig
    def test_pauli_error_2q_unitary_from_pauli(self):
        """Test two-qubit pauli error as unitary qobj from Pauli obj"""
        paulis = [Pauli.from_label(s) for s in ['XY', 'YZ', 'ZX']]
        probs = [0.5, 0.3, 0.2]
        error = pauli_error(zip(paulis, probs), standard_gates=False)

        X = standard_gate_unitary('x')
        Y = standard_gate_unitary('y')
        Z = standard_gate_unitary('z')
        target_unitaries = [np.kron(X, Y), np.kron(Y, Z), np.kron(Z, X)]
        target_probs = probs.copy()
        for j in range(len(paulis)):
            circ, p = error.error_term(j)
            name = circ[0]['name']
            self.assertIn(name, 'unitary')
            self.assertEqual(circ[0]['qubits'], [0, 1])
            self.remove_if_found(p, target_probs)
            self.remove_if_found(circ[0]['params'], target_unitaries)
        self.assertEqual(target_probs, [], msg="Incorrect probabilities")
        self.assertEqual(target_unitaries, [], msg="Incorrect unitaries")
Exemplo n.º 11
0
def iplot_bloch_multivector(rho, figsize=None):
    """ Create a bloch sphere representation.

        Graphical representation of the input array, using as much bloch
        spheres as qubit are required.

        Args:
            rho (array): State vector or density matrix
            figsize (tuple): Figure size in pixels.

        Example:
            .. code-block::

                from qiskit import QuantumCircuit, BasicAer, execute
                from qiskit.visualization import iplot_bloch_multivector
                %matplotlib inline

                qc = QuantumCircuit(2, 2)
                qc.h(0)
                qc.cx(0, 1)
                qc.measure([0, 1], [0, 1])

                backend = BasicAer.get_backend('statevector_simulator')
                job = execute(qc, backend).result()
                iplot_bloch_multivector(job.get_statevector(qc))
    """

    # HTML
    html_template = Template("""
    <p>
        <div id="content_$divNumber" style="position: absolute; z-index: 1;">
            <div id="bloch_$divNumber"></div>
        </div>
    </p>
    """)

    # JavaScript
    javascript_template = Template("""
    <script>
        requirejs.config({
            paths: {
                qVisualization: "https://qvisualization.mybluemix.net/q-visualizations"
            }
        });
        data = $data;
        dataValues = [];
        for (var i = 0; i < data.length; i++) {
            // Coordinates
            var x = data[i][0];
            var y = data[i][1];
            var z = data[i][2];
            var point = {'x': x,
                        'y': y,
                        'z': z};
            dataValues.push(point);
        }

        require(["qVisualization"], function(qVisualizations) {
            // Plot figure
            qVisualizations.plotState("bloch_$divNumber",
                                      "bloch",
                                      dataValues,
                                      $options);
        });
    </script>
    """)
    rho = _validate_input_state(rho)
    if figsize is None:
        options = {}
    else:
        options = {'width': figsize[0], 'height': figsize[1]}

    # Process data and execute
    num = int(np.log2(len(rho)))

    bloch_data = []
    for i in range(num):
        pauli_singles = [Pauli.pauli_single(num, i, 'X'), Pauli.pauli_single(num, i, 'Y'),
                         Pauli.pauli_single(num, i, 'Z')]
        bloch_state = list(map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
                               pauli_singles))
        bloch_data.append(bloch_state)

    div_number = str(time.time())
    div_number = re.sub('[.]', '', div_number)

    html = html_template.substitute({
        'divNumber': div_number
    })

    javascript = javascript_template.substitute({
        'data': bloch_data,
        'divNumber': div_number,
        'options': options
    })

    display(HTML(html + javascript))
Exemplo n.º 12
0
def run_exp(num_reps=1):

    # choice of Hi basis
    H_basis = [Pauli.from_label(p) for p in ['II', 'ZI', 'IZ', 'ZZ', 'YY', 'XX']]

    num_qubits = 2
    evo_time = 1
    epsilon = 0.1
    L = 32    ## number of local hamiltonian terms

    ############################################################
    # Generate a random Hamiltonian H as the sum of m basis Hi operators
    ############################################################

    hs = np.random.random(L)
    indexes = np.random.randint(low=0, high=6, size=L)

    ## H in matrix form
    H_matrix = np.zeros((2 ** num_qubits, 2 ** num_qubits))

    ## H as a list of pauli operators (unweighted)
    H_list = []
    for i in range(L):
        H_matrix = H_matrix + hs[i] * H_basis[indexes[i]].to_matrix()
        H_list.append(H_basis[indexes[i]])
    print('matrix H: \n', H_matrix)

    # H as a pauli operator
    H_qubitOp = op_converter.to_weighted_pauli_operator(MatrixOperator(matrix=H_matrix))

    # Generate an initial state
    state_in = Custom(num_qubits, state='random')

    ############################################################
    # Ground truth and benchmarks
    ############################################################

    # Ground truth
    state_in_vec = state_in.construct_circuit('vector')
    groundtruth = expm(-1.j * H_matrix * evo_time) @ state_in_vec
    print('The directly computed groundtruth evolution result state is')
    print('{}\n.'.format(groundtruth))

    # Build circuit using Qiskit's evolve algorithm, which based on Trotter-Suzuki.
    quantum_registers = QuantumRegister(num_qubits)
    circuit = state_in.construct_circuit('circuit', quantum_registers)
    circuit += H_qubitOp.evolve(
        None, evo_time, num_time_slices=10,
        quantum_registers=quantum_registers,
        expansion_mode='suzuki',
        expansion_order=1
    )

    # Simulate Trotter-Suzuki circuit and print it
    backend = BasicAer.get_backend('statevector_simulator')
    job = q_execute(circuit, backend)
    circuit_execution_result = np.asarray(job.result().get_statevector(circuit))
    print('The simulated (suzuki) evolution result state is')
    print('{}\n'.format(circuit_execution_result))

    # The difference between the ground truth and the simulated state
    # measured by "Fidelity"
    fidelity_suzuki = state_fidelity(groundtruth, circuit_execution_result)
    print('Fidelity between the groundtruth and the circuit result states is {}.'.format(fidelity_suzuki))
    print('\n')

    ############################################################
    # Our qdrift implementation
    ############################################################

    quantum_registers = QuantumRegister(num_qubits)
    circuit = state_in.construct_circuit('circuit', quantum_registers)

    # Contruct the circuit which implements qdrift
    circuit = time_evolve_qubits(quantum_registers, circuit, num_qubits, H_list, hs, evo_time, epsilon, num_reps)

    # Simulate circuit and print it
    backend = BasicAer.get_backend('statevector_simulator')
    job = q_execute(circuit, backend)
    circuit_execution_result = np.asarray(job.result().get_statevector(circuit))
    print('The simulated (qdrift) evolution result state is\n{}.'.format(circuit_execution_result))
    print('\n')

    # Measure the fidelity
    fidelity_qdrift = state_fidelity(groundtruth, circuit_execution_result)
    print('Fidelity between the groundtruth and the circuit result states is {}.'.format(fidelity_qdrift))
    print('\n')

    print('benchmark, suzuki:', fidelity_suzuki)
    print('qdrift:', fidelity_qdrift)
    return fidelity_qdrift, fidelity_suzuki
Exemplo n.º 13
0
def depolarizing_error(param, num_qubits, standard_gates=None):
    r"""
    Return a depolarizing quantum error channel.

    The depolarizing channel is defined as:

    .. math::

        E(ρ) = (1 - λ) ρ + λ \text{Tr}[ρ] \frac{I}{2^n}

    with :math:`0 \le λ \le 4^n / (4^n - 1)`

    where :math:`λ` is the depolarizing error param and :math`n` is the
    number of qubits.

    * If :math:`λ = 0` this is the identity channel :math:`E(ρ) = ρ`
    * If :math:`λ = 1` this is a completely depolarizing channel
      :math:`E(ρ) = I / 2^n`
    * If :math:`λ = 4^n / (4^n - 1)` this is a uniform Pauli
      error channel: :math:`E(ρ) = \sum_j P_j ρ P_j / (4^n - 1)` for
      all :math:`P_j != I`.

    Args:
        param (double): depolarizing error parameter.
        num_qubits (int): the number of qubits for the error channel.
        standard_gates (bool): DEPRECATED, if True return the operators as
                               Pauli gates. If false return as unitary gates.
                               (Default: None)

    Returns:
        QuantumError: The quantum error object.

    Raises:
        NoiseError: If noise parameters are invalid.
    """
    if not isinstance(num_qubits, int) or num_qubits < 1:
        raise NoiseError("num_qubits must be a positive integer.")
    # Check that the depolarizing parameter gives a valid CPTP
    num_terms = 4**num_qubits
    max_param = num_terms / (num_terms - 1)
    if param < 0 or param > max_param:
        raise NoiseError("Depolarizing parameter must be in between 0 "
                         "and {}.".format(max_param))

    # Rescale completely depolarizing channel error probs
    # with the identity component removed
    prob_iden = 1 - param / max_param
    prob_pauli = param / num_terms
    probs = [prob_iden] + (num_terms - 1) * [prob_pauli]

    if standard_gates is not None:
        warnings.warn(
            '"standard_gates" option has been deprecated as of qiskit-aer 0.10.0'
            ' and will be removed no earlier than 3 months from that release date.',
            DeprecationWarning,
            stacklevel=2)
        circs = []
        for pauli_list in it.product(
            [IGate(), XGate(), YGate(), ZGate()], repeat=num_qubits):
            qc = QuantumCircuit(num_qubits)
            for q, pauli in enumerate(pauli_list):
                if not standard_gates:
                    pauli = UnitaryGate(pauli.to_matrix())
                qc.append(pauli, qargs=[q])
            circs.append(qc)
        return QuantumError(zip(circs, probs))

    # Generate pauli strings. The order doesn't matter as long
    # as the all identity string is first.
    paulis = [
        Pauli("".join(tup))
        for tup in it.product(['I', 'X', 'Y', 'Z'], repeat=num_qubits)
    ]
    return QuantumError(zip(paulis, probs))