Example #1
0
    def test_save_expval_var_cptp_pauli(self, pauli):
        """Test Pauli expval_var for stabilizer circuit"""

        SUPPORTED_METHODS = [
            'density_matrix', 'density_matrix_gpu', 'density_matrix_thrust'
        ]
        SEED = 5832

        opts = self.BACKEND_OPTS.copy()
        if opts.get('method') in SUPPORTED_METHODS:

            oper = qi.Operator(qi.Operator(qi.Pauli(pauli)))

            # CPTP channel test circuit
            channel = qi.random_quantum_channel(4, seed=SEED)
            state_circ = QuantumCircuit(2)
            state_circ.append(channel, range(2))

            state = qi.DensityMatrix(state_circ)
            expval = state.expectation_value(oper).real
            variance = state.expectation_value(oper**2).real - expval**2
            target = [expval, variance]

            # Snapshot circuit
            circ = transpile(state_circ, self.SIMULATOR)
            circ.save_expectation_value_variance(oper, [0, 1], label='expval')
            qobj = assemble(circ)
            result = self.SIMULATOR.run(qobj, **opts).result()

            self.assertTrue(result.success)
            value = result.data(0)['expval']
            self.assertTrue(allclose(value, target))
Example #2
0
    def test_save_unitary(self):
        """Test save unitary for instruction"""

        SUPPORTED_METHODS = [
            'automatic', 'unitary', 'unitary_gpu', 'unitary_thrust'
        ]

        # Stabilizer test circuit
        circ = transpile(QuantumVolume(3), self.SIMULATOR)

        # Target unitary
        target = qi.Operator(circ)

        # Add save to circuit
        save_key = 'state'
        circ.save_unitary(save_key)

        # Run
        opts = self.BACKEND_OPTS.copy()
        qobj = assemble(circ, self.SIMULATOR)
        result = self.SIMULATOR.run(qobj, **opts).result()
        method = opts.get('method', 'automatic')
        if method not in SUPPORTED_METHODS:
            self.assertFalse(result.success)
        else:
            self.assertTrue(result.success)
            data = result.data(0)
            self.assertIn(save_key, data)
            value = qi.Operator(result.data(0)[save_key])
            self.assertEqual(value, target)
    def test_weyl_unitaries_random_circuit(self):
        """Weyl decomposition for a random two-qubit circuit."""
        theta = pi / 9
        epsilon = 5
        delta = -1
        eta = 0.2
        qr = QuantumRegister(2, "qr")
        circuit = QuantumCircuit(qr)

        # random two-qubit circuit.
        circuit.rzx(theta, 0, 1)
        circuit.rzz(epsilon, 0, 1)
        circuit.rz(eta, 0)
        circuit.swap(1, 0)
        circuit.h(0)
        circuit.rzz(delta, 1, 0)
        circuit.swap(0, 1)
        circuit.cx(1, 0)
        circuit.swap(0, 1)
        circuit.h(1)
        circuit.rxx(theta, 0, 1)
        circuit.ryy(theta, 1, 0)
        circuit.ecr(0, 1)

        unitary_circuit = qi.Operator(circuit).data

        dag = circuit_to_dag(circuit)
        pass_ = EchoRZXWeylDecomposition(self.inst_map)
        after = dag_to_circuit(pass_.run(dag))

        unitary_after = qi.Operator(after).data

        self.assertTrue(np.allclose(unitary_circuit, unitary_after))
Example #4
0
 def test_save_expval_var_cptp_pauli(self, method, device, pauli):
     """Test Pauli expval_var for stabilizer circuit"""
     SEED = 5832
     oper = qi.Operator(qi.Operator(qi.Pauli(pauli)))
     channel = qi.random_quantum_channel(4, seed=SEED)
     circ = QuantumCircuit(2)
     circ.append(channel, range(2))
     qubits = [0, 1]
     self._test_save_expval(circ,
                            oper,
                            qubits,
                            True,
                            method=method,
                            device=device)
    def test_weyl_decomposition_gate_angles(self):
        """Check the number and angles of the RZX gates for different gates"""
        thetas = [pi / 9, 2.1, -0.2]

        qr = QuantumRegister(2, "qr")
        circuit_rxx = QuantumCircuit(qr)
        circuit_rxx.rxx(thetas[0], qr[1], qr[0])

        circuit_ryy = QuantumCircuit(qr)
        circuit_ryy.ryy(thetas[1], qr[0], qr[1])

        circuit_rzz = QuantumCircuit(qr)
        circuit_rzz.rzz(thetas[2], qr[1], qr[0])

        circuits = [circuit_rxx, circuit_ryy, circuit_rzz]

        for circuit in circuits:

            unitary_circuit = qi.Operator(circuit).data

            dag = circuit_to_dag(circuit)
            pass_ = EchoRZXWeylDecomposition(self.inst_map)
            after = dag_to_circuit(pass_.run(dag))
            dag_after = circuit_to_dag(after)

            unitary_after = qi.Operator(after).data

            # check whether the unitaries are equivalent.
            self.assertTrue(np.allclose(unitary_circuit, unitary_after))

            # check whether the after circuit has the correct number of rzx gates.
            self.assertRZXgates(unitary_circuit, after)

            alpha = TwoQubitWeylDecomposition(unitary_circuit).a

            rzx_angles = []
            for node in dag_after.two_qubit_ops():
                if node.name == "rzx":
                    rzx_angle = node.op.params[0]
                    # check whether the absolute values of the RZX gate angles
                    # are equivalent to the corresponding Weyl parameter.
                    self.assertAlmostEqual(np.abs(rzx_angle), alpha)
                    rzx_angles.append(rzx_angle)

            # check whether the angles of every RZX gate pair of an echoed RZX gate
            # have opposite signs.
            for idx in range(1, len(rzx_angles), 2):
                self.assertAlmostEqual(rzx_angles[idx - 1], -rzx_angles[idx])
 def hamiltonian_superop(ham):
     ham = qi.Operator(ham)
     dim, _ = ham.dim
     iden = np.eye(dim)
     super_op = -1j * np.kron(iden, ham.data) + 1j * np.kron(
         np.conj(ham.data), iden)
     return qi.SuperOp(super_op)
    def test_rzx_number_native_weyl_decomposition(self):
        """Check the number of RZX gates for a hardware-native cx"""
        qr = QuantumRegister(2, "qr")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[0], qr[1])

        unitary_circuit = qi.Operator(circuit).data

        after = EchoRZXWeylDecomposition(self.inst_map)(circuit)

        unitary_after = qi.Operator(after).data

        self.assertTrue(np.allclose(unitary_circuit, unitary_after))

        # check whether the after circuit has the correct number of rzx gates.
        self.assertRZXgates(unitary_circuit, after)
Example #8
0
    def test_save_expval_var_stabilizer_pauli(self, pauli):
        """Test Pauli expval_var for stabilizer circuit"""

        SUPPORTED_METHODS = [
            'automatic', 'statevector', 'statevector_gpu',
            'statevector_thrust', 'density_matrix', 'density_matrix_gpu',
            'density_matrix_thrust', 'matrix_product_state', 'stabilizer'
        ]
        SEED = 5832

        # Stabilizer test circuit
        state_circ = qi.random_clifford(2, seed=SEED).to_circuit()
        oper = qi.Operator(qi.Pauli(pauli))
        state = qi.Statevector(state_circ)
        expval = state.expectation_value(oper).real
        variance = state.expectation_value(oper**2).real - expval**2
        target = [expval, variance]

        # Snapshot circuit
        opts = self.BACKEND_OPTS.copy()
        method = opts.get('method', 'automatic')
        circ = transpile(state_circ,
                         basis_gates=[
                             'id', 'x', 'y', 'z', 'h', 's', 'sdg', 'cx', 'cz',
                             'swap'
                         ])
        circ.save_expectation_value_variance(oper, [0, 1], label='expval')
        qobj = assemble(circ)
        result = self.SIMULATOR.run(qobj, **opts).result()
        if method not in SUPPORTED_METHODS:
            self.assertFalse(result.success)
        else:
            self.assertTrue(result.success)
            value = result.data(0)['expval']
            self.assertTrue(allclose(value, target))
Example #9
0
    def test_save_expval_nonstabilizer_pauli(self, pauli):
        """Test Pauli expval for non-stabilizer circuit"""

        SUPPORTED_METHODS = [
            'automatic', 'statevector', 'statevector_gpu',
            'statevector_thrust', 'density_matrix', 'density_matrix_gpu',
            'density_matrix_thrust', 'matrix_product_state'
        ]
        SEED = 7382

        # Stabilizer test circuit
        state_circ = QuantumVolume(2, 1, seed=SEED)
        oper = qi.Operator(qi.Pauli(pauli))
        state = qi.Statevector(state_circ)
        target = state.expectation_value(oper).real

        # Snapshot circuit
        opts = self.BACKEND_OPTS.copy()
        method = opts.get('method', 'automatic')
        circ = transpile(state_circ,
                         basis_gates=['u1', 'u2', 'u3', 'cx', 'swap'])
        circ.save_expectation_value(oper, [0, 1], label='expval')
        qobj = assemble(circ)
        result = self.SIMULATOR.run(qobj, **opts).result()
        if method not in SUPPORTED_METHODS:
            self.assertFalse(result.success)
        else:
            self.assertTrue(result.success)
            value = result.data(0)['expval']
            self.assertAlmostEqual(value, target)
Example #10
0
    def _test_save_expval(self, circuit, oper, qubits, variance, **options):
        """Test Pauli expval for stabilizer circuit"""
        backend = self.backend(**options)
        label = 'expval'

        # Format operator and target value
        circ = circuit.copy()
        oper = qi.Operator(oper)
        state = qi.DensityMatrix(circ)
        expval = state.expectation_value(oper, qubits).real

        if variance:
            var = state.expectation_value(oper**2, qubits).real - expval**2
            target = [expval, var]
            circ.save_expectation_value_variance(oper, qubits, label=label)
        else:
            target = expval
            circ.save_expectation_value(oper, qubits, label=label)

        result = backend.run(transpile(circ, backend, optimization_level=0),
                             shots=1).result()
        self.assertTrue(result.success)
        simdata = result.data(0)
        self.assertIn(label, simdata)
        value = simdata[label]
        if variance:
            self.assertTrue(allclose(value, target))
        else:
            self.assertAlmostEqual(value, target)
Example #11
0
    def assert_circuit_equivalence(self, qc, qcd):
        """ Raise exception if two circuits not equivalent """
        I = qc.compose(qcd.inverse())
        op = qi.Operator(I)

        U = op.data / np.sqrt(complex(np.linalg.det(op.data)))
        U *= U[0, 0]
        np.testing.assert_almost_equal(U, np.eye(2**qc.num_qubits))
Example #12
0
    def test_pauli_error_2q_gate_from_string_1qonly(self):
        """Test two-qubit pauli error as gate qobj from string label"""
        paulis = ['XI', 'YI', 'ZI']
        probs = [0.5, 0.3, 0.2]
        with self.assertWarns(DeprecationWarning):
            actual = pauli_error(zip(paulis, probs), standard_gates=True)

        target_circs = [[{"name": "id", "qubits": [0]}, {"name": "x", "qubits": [1]}],
                        [{"name": "id", "qubits": [0]}, {"name": "y", "qubits": [1]}],
                        [{"name": "id", "qubits": [0]}, {"name": "z", "qubits": [1]}]]
        with self.assertWarns(DeprecationWarning):
            expected = QuantumError(zip(target_circs, probs), standard_gates=True)

        for i in range(actual.size):
            circ, prob = actual.error_term(i)
            expected_circ, expected_prob = expected.error_term(i)
            self.assertTrue(qi.Operator(circ).equiv(qi.Operator(expected_circ)))
            self.assertAlmostEqual(prob, expected_prob)
Example #13
0
    def _test_gate(self, gate, gates_dict, **options):
        """Test standard gates."""

        backend = self.backend(**options)

        gate_cls, num_angles, has_ctrl_qubits = gates_dict[gate]
        circuits = self.gate_circuits(gate_cls,
                                      num_angles=num_angles,
                                      has_ctrl_qubits=has_ctrl_qubits,
                                      rng=self.RNG)

        label = 'final'
        method = backend.options.method
        for circuit in circuits:
            if method == 'density_matrix':
                target = qi.DensityMatrix(circuit)
                circuit.save_density_matrix(label=label)
                state_fn = qi.DensityMatrix
                fidelity_fn = qi.state_fidelity
            elif method == 'stabilizer':
                target = qi.Clifford(circuit)
                circuit.save_stabilizer(label=label)
                state_fn = qi.Clifford.from_dict
                fidelity_fn = qi.process_fidelity
            elif method == 'unitary':
                target = qi.Operator(circuit)
                circuit.save_unitary(label=label)
                state_fn = qi.Operator
                fidelity_fn = qi.process_fidelity
            elif method == 'superop':
                target = qi.SuperOp(circuit)
                circuit.save_superop(label=label)
                state_fn = qi.SuperOp
                fidelity_fn = qi.process_fidelity
            else:
                target = qi.Statevector(circuit)
                circuit.save_statevector(label=label)
                state_fn = qi.Statevector
                fidelity_fn = qi.state_fidelity

            result = backend.run(transpile(circuit,
                                           backend,
                                           optimization_level=0),
                                 shots=1).result()

            # Check results
            success = getattr(result, 'success', False)
            self.assertTrue(success)
            data = result.data(0)
            self.assertIn(label, data)
            value = state_fn(data[label])
            fidelity = fidelity_fn(target, value)
            self.assertGreater(fidelity, 0.9999)
Example #14
0
 def test_save_expval_var_stabilizer_pauli(self, method, device, pauli):
     """Test Pauli expval_var for stabilizer circuit"""
     SEED = 5832
     circ = qi.random_clifford(2, seed=SEED).to_circuit()
     oper = qi.Operator(qi.Pauli(pauli))
     qubits = [0, 1]
     self._test_save_expval(circ,
                            oper,
                            qubits,
                            True,
                            method=method,
                            device=device)
Example #15
0
 def test_save_expval_var_nonstabilizer_pauli(self, method, device, pauli):
     """Test Pauli expval_var for non-stabilizer circuit"""
     SEED = 7382
     circ = QuantumVolume(2, 1, seed=SEED)
     oper = qi.Operator(qi.Pauli(pauli))
     qubits = [0, 1]
     self._test_save_expval(circ,
                            oper,
                            qubits,
                            True,
                            method=method,
                            device=device)
    def _target_quantum_channel(
        cls,
        circuit: QuantumCircuit,
        measurement_qubits: Optional[Sequence[int]] = None,
        preparation_qubits: Optional[Sequence[int]] = None,
    ):
        """Return the process tomography target"""
        # Check if circuit contains measure instructions
        # If so we cannot return target state
        circuit_ops = circuit.count_ops()
        if "measure" in circuit_ops:
            return None

        perm_circ = cls._permute_circuit(circuit,
                                         measurement_qubits=measurement_qubits,
                                         preparation_qubits=preparation_qubits)
        try:
            if "reset" in circuit_ops or "kraus" in circuit_ops or "superop" in circuit_ops:
                channel = qi.Choi(perm_circ)
            else:
                channel = qi.Operator(perm_circ)
        except QiskitError:
            # Circuit couldn't be simulated
            return None

        total_qubits = circuit.num_qubits
        if measurement_qubits:
            num_meas = len(measurement_qubits)
        else:
            num_meas = total_qubits
        if preparation_qubits:
            num_prep = len(preparation_qubits)
        else:
            num_prep = total_qubits

        if num_prep == total_qubits and num_meas == total_qubits:
            return channel

        # Trace out non-measurement subsystems
        tr_qargs = []
        if preparation_qubits:
            tr_qargs += list(range(num_prep, total_qubits))
        if measurement_qubits:
            tr_qargs += list(range(total_qubits + num_meas, 2 * total_qubits))

        chan_state = qi.Statevector(np.ravel(channel, order="F"))
        chan_state = qi.partial_trace(chan_state,
                                      tr_qargs) / 2**(total_qubits - num_meas)
        channel = qi.Choi(chan_state.data,
                          input_dims=[2] * num_prep,
                          output_dims=[2] * num_meas)
        return channel
    def run(self, dag: DAGCircuit):
        """Run the EchoRZXWeylDecomposition pass on `dag`.

        Rewrites two-qubit gates in an arbitrary circuit in terms of echoed cross-resonance
        gates by computing the Weyl decomposition of the corresponding unitary. Modifies the
        input dag.

        Args:
            dag (DAGCircuit): DAG to rewrite.

        Returns:
            DAGCircuit: The modified dag.

        Raises:
            TranspilerError: If the circuit cannot be rewritten.
        """

        if len(dag.qregs) > 1:
            raise TranspilerError(
                "EchoRZXWeylDecomposition expects a single qreg input DAG,"
                f"but input DAG had qregs: {dag.qregs}.")

        trivial_layout = Layout.generate_trivial_layout(*dag.qregs.values())

        decomposer = TwoQubitControlledUDecomposer(RZXGate)

        for node in dag.two_qubit_ops():

            unitary = qi.Operator(node.op).data
            dag_weyl = circuit_to_dag(decomposer(unitary))
            dag.substitute_node_with_dag(node, dag_weyl)

        for node in dag.two_qubit_ops():
            if node.name == "rzx":
                control = node.qargs[0]
                target = node.qargs[1]

                physical_q0 = trivial_layout[control]
                physical_q1 = trivial_layout[target]

                is_native = self._is_native((physical_q0, physical_q1))

                theta = node.op.params[0]
                if is_native:
                    dag.substitute_node_with_dag(node,
                                                 self._echo_rzx_dag(theta))
                else:
                    dag.substitute_node_with_dag(
                        node, self._reverse_echo_rzx_dag(theta))

        return dag
Example #18
0
    def test_save_unitary(self, method, device):
        """Test save unitary instruction"""
        backend = self.backend(method=method, device=device)

        # Test circuit
        SEED = 5426
        circ = QuantumVolume(3, seed=SEED)

        # Target unitary
        target = qi.Operator(circ)

        # Add save to circuit
        label = 'state'
        circ.save_unitary(label=label)

        # Run
        result = backend.run(transpile(
            circ, backend, optimization_level=0), shots=1).result()
        self.assertTrue(result.success)
        simdata = result.data(0)
        self.assertIn(label, simdata)
        value = qi.Operator(simdata[label])
        self.assertEqual(value, target)
Example #19
0
 def test_save_expval_stabilizer_pauli_cache_blocking(
         self, method, device, pauli):
     """Test Pauli expval for stabilizer circuit"""
     SEED = 5832
     circ = qi.random_clifford(2, seed=SEED).to_circuit()
     oper = qi.Operator(qi.Pauli(pauli))
     qubits = [0, 1]
     self._test_save_expval(circ,
                            oper,
                            qubits,
                            False,
                            method=method,
                            device=device,
                            blocking_qubits=2,
                            max_parallel_threads=1)
 def test_unitary_snap(self):
     """Test Unitary matrix snaps on a random circuit"""
     backend = UnitarySimulator()
     target = qi.random_unitary(2 ** 4, seed=111)
     circ = QuantumCircuit(4)
     circ.append(target, [0, 1, 2, 3])
     circ.append(Snapshot("final", "unitary", 4), [0, 1, 2, 3])
     qobj = assemble(circ, backend=backend, shots=1)
     job = backend.run(qobj)
     result = job.result()
     self.assertSuccess(result)
     snaps = result.data(0)['snapshots']['unitary']['final']
     for arr in snaps:
         self.assertTrue(isinstance(arr, np.ndarray))
         self.assertEqual(qi.Operator(arr), target)
    def test_full_exp_meas_prep_qubits(self, qubits):
        """Test subset state tomography generation"""
        # Subsystem unitaries
        seed = 1111
        nq = 3
        ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)]

        # Target state
        target_circ = QuantumCircuit(len(qubits))
        for i, qubit in enumerate(qubits):
            target_circ.append(ops[qubit], [i])
        target = qi.Operator(target_circ)

        # Preparation circuit
        circ = QuantumCircuit(nq)
        for i, op in enumerate(ops):
            circ.append(op, [i])

        # Run
        backend = AerSimulator(seed_simulator=9000)
        exp = ProcessTomography(circ,
                                measurement_qubits=qubits,
                                preparation_qubits=qubits)
        expdata = exp.run(backend)
        self.assertExperimentDone(expdata)
        results = expdata.analysis_results()

        # Check result
        f_threshold = 0.95

        # Check state is density matrix
        state = filter_results(results, "state").value
        self.assertTrue(isinstance(state, qi.Choi),
                        msg="fitted state is not a Choi matrix")

        # Check fit state fidelity
        fid = filter_results(results, "process_fidelity").value
        self.assertGreater(fid, f_threshold, msg="fit fidelity is low")

        # Manually check fidelity
        target_fid = qi.process_fidelity(state,
                                         target,
                                         require_tp=False,
                                         require_cp=False)
        self.assertAlmostEqual(fid,
                               target_fid,
                               places=6,
                               msg="result fidelity is incorrect")
def generate_two_qubit_N_operator(theta):
    '''
    somehow this is diff from the commented out one above lol ohwell

    this is from Abol's paper
    '''
    qc = QuantumCircuit(2, name = "N({theta})".format(theta = theta))
    qc.rz(np.pi/2,1)
    qc.cx(1,0)
    qc.rz(2*theta - np.pi/2, 0)
    qc.ry(np.pi/2 - 2*theta, 1)
    qc.cx(0,1)
    qc.ry(2*theta - np.pi/2, 1)
    qc.cx(1,0)
    qc.rz(-np.pi/2,0)

    return qi.Operator(qc)
Example #23
0
    def test_pauli_gate(self, method, device, pauli):
        """Test multi-qubit Pauli gate."""
        pauli = qi.Pauli(pauli)
        circuit = QuantumCircuit(pauli.num_qubits)
        circuit.append(pauli, range(pauli.num_qubits))

        backend = self.backend(method=method, device=device)
        label = 'final'
        if method == 'density_matrix':
            target = qi.DensityMatrix(circuit)
            circuit.save_density_matrix(label=label)
            state_fn = qi.DensityMatrix
            fidelity_fn = qi.state_fidelity
        elif method == 'stabilizer':
            target = qi.Clifford(circuit)
            circuit.save_stabilizer(label=label)
            state_fn = qi.Clifford.from_dict
            fidelity_fn = qi.process_fidelity
        elif method == 'unitary':
            target = qi.Operator(circuit)
            circuit.save_unitary(label=label)
            state_fn = qi.Operator
            fidelity_fn = qi.process_fidelity
        elif method == 'superop':
            target = qi.SuperOp(circuit)
            circuit.save_superop(label=label)
            state_fn = qi.SuperOp
            fidelity_fn = qi.process_fidelity
        else:
            target = qi.Statevector(circuit)
            circuit.save_statevector(label=label)
            state_fn = qi.Statevector
            fidelity_fn = qi.state_fidelity

        result = backend.run(transpile(circuit, backend, optimization_level=0),
                             shots=1).result()

        # Check results
        success = getattr(result, 'success', False)
        self.assertTrue(success)
        data = result.data(0)
        self.assertIn(label, data)
        value = state_fn(data[label])
        fidelity = fidelity_fn(target, value)
        self.assertGreater(fidelity, 0.9999)
Example #24
0
def costvsthetas_disc(vth):

    th1 = np.round(vth[0]) / 32 * pi
    th2 = np.round(vth[1]) / 32 * pi
    th3 = np.round(vth[2]) / 32 * pi
    th4 = np.round(vth[3]) / 32 * pi

    qc = QuantumCircuit(4)
    qc.rx(th1, 0)
    qc.rx(th2, 1)
    qc.rx(th3, 2)
    qc.rx(th4, 3)

    mtrx = qi.Operator(qc).data

    #mtrx = fourgates(th1, th2, th3, th4)

    return cost(mtrx - uu)
    def test_set_unitary(self, method, device, num_qubits):
        """Test SetUnitary instruction"""
        backend = self.backend(method=method, device=device)

        seed = 100
        label = 'state'

        target = qi.random_unitary(2**num_qubits, seed=seed)

        circ = QuantumCircuit(num_qubits)
        circ.set_unitary(target)
        circ.save_unitary(label=label)

        # Run
        result = backend.run(transpile(circ, backend, optimization_level=0),
                             shots=1).result()
        self.assertTrue(result.success)
        simdata = result.data(0)
        self.assertIn(label, simdata)
        value = qi.Operator(simdata[label])
        self.assertEqual(value, target)
    def test_exp_measurement_preparation_qubits(self, qubits):
        """Test subset measurement process tomography generation"""
        # Subsystem unitaries
        seed = 1111
        nq = 3
        ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)]

        # Preparation circuit
        circ = QuantumCircuit(nq)
        for i, op in enumerate(ops):
            circ.append(op, [i])

        num_meas = len(qubits)
        exp = ProcessTomography(circ,
                                measurement_qubits=qubits,
                                preparation_qubits=qubits)
        tomo_circuits = exp.circuits()

        # Check correct number of circuits are generated
        size = 3**num_meas * 4**num_meas
        self.assertEqual(len(tomo_circuits), size)

        # Check circuit metadata is correct
        for circ in tomo_circuits:
            meta = circ.metadata
            clbits = meta.get("clbits")
            self.assertEqual(clbits,
                             list(range(num_meas)),
                             msg="metadata clbits is incorrect")

        # Check experiment target metadata is correct
        exp_meta = exp._metadata()
        target_state = exp_meta.get("target")

        target_circ = QuantumCircuit(num_meas)
        for i, qubit in enumerate(qubits):
            target_circ.append(ops[qubit], [i])
        fid = qi.process_fidelity(target_state, qi.Operator(target_circ))
        self.assertGreater(fid, 0.99, msg="target_state is incorrect")
Example #27
0
def circ2matrix(qc=None):

    #pl.figure() #figsize=(20,9))

    pl.clf()

    if not qc: qc = QuantumCircuit(4)
    else:
        uc = qi.Operator(qc).data
        pl.subplot(121)
        plu(uc)
        pl.subplot(122)
        plu(uc / compru(uc[0:2, 0:2]), ampl=False)

    be = aer.get_backend('unitary_simulator')

    ucompr = compru(u22)

    gatestr = input('Next gate: ')
    while gatestr != 'q':

        if gatestr == 'r': qc = QuantumCircuit(4)

        elif gatestr[0:3] != 'qc.':
            try:
                exec(gatestr)
            except:
                print('ignoring previous command')

        else:
            #exec('qc.'+gatestr.strip())
            try:
                exec(gatestr)
                goodgate = True
            except:
                goodgate = False
                print('ignoring this gate')

            if goodgate:

                uc = qi.Operator(qc).data

                uc22 = uc[0:2, 0:2]

                u4by4 = np.concatenate((uc22, uc22), axis=0)
                u4by4 = np.concatenate((u4by4, u4by4), axis=1)

                xuc22 = X @ uc22

                x4by4 = np.concatenate((xuc22, xuc22), axis=0)
                x4by4 = np.concatenate((x4by4, x4by4), axis=1)

                u8by8 = np.concatenate((u4by4, x4by4), axis=1)
                u8by8 = np.concatenate(
                    (u8by8, np.concatenate((x4by4, u4by4), axis=1)), axis=0)

                compr = np.concatenate((np.concatenate(
                    (u8by8, u8by8),
                    axis=1), np.concatenate((u8by8, u8by8), axis=1)),
                                       axis=0)
                """
                pl.subplot(221)
                plu(uu)
                pl.subplot(222)
                plu(uu/ucompr)
                """
                pl.clf()
                pl.subplot(121)
                plu(uc)
                #pl.show(block=False)
                pl.subplot(122)
                plu(uc / compr, ampl=False)
                #pl.show(block=False)

        gatestr = input('Next gate: ')
Example #28
0
def get_unitary(circuit: QuantumCircuit) -> np.ndarray:
    V = qi.Operator(circuit).data
    return V
def hamiltonian_reconstruction(channels: List[Choi],
                               pauli_labels: List[str],
                               gate_time: float,
                               phase_shifts: List[float] = None,
                               shifter_label: str = 'ZI',
                               sanity_check: bool = False)\
        -> Tuple[Dict[str, np.ndarray], List[float]]:
    """ Extract Pauli term coefficient from quantum channel.
    Args:
        channels: quantum channels to reconstruct Hamiltonian.
        pauli_labels: name of Pauli terms
        gate_time: duration of gate
        phase_shifts: phase shift to unwrap 2pi uncertainty.
        shifter_label: pauli term to shift.
        sanity_check: do sanity check.

    Additional information:
        To remove 2pi uncertainty of Logm, we need decompose superop S to satisfy |M| < 2 pi.
        S_H = exp(w * L_H) where L_H is superop of Pauli term shift.
        According to BCH expansion::
            M = logm(S. S_H)
              = logm(exp(tG).exp(w L_H))
              = tG + w L_H + t*w*[G, L_H] + O(2 coms)
            M' = M - w L_H
        Then Pauli coefficients are::
            b = Tr[B^dag.M']
              = t*Tr[B^dag.G] + t*w*Tr[B^dag.[G, L_H]] + O(2 coms)
              = b_true + + t*w*Tr[B^dag.[G, L_H]] + O(2 coms)
        When commutator of G and L_H is zero, b = b_true.
        Optimizer finds w to calculate principal matrix log.
    """
    threshold_san1 = 1e-3
    threshold_san2 = 1e-1

    def hamiltonian_superop(ham):
        ham = qi.Operator(ham)
        dim, _ = ham.dim
        iden = np.eye(dim)
        super_op = -1j * np.kron(iden, ham.data) + 1j * np.kron(
            np.conj(ham.data), iden)
        return qi.SuperOp(super_op)

    if phase_shifts is None:
        phase_shifts = [0 for _ in range(len(channels))]

    coeffs = defaultdict(list)
    estimated_hamiltonian_fidelities = []
    for phase_shift, chan in zip(phase_shifts, channels):
        sup_s = qi.SuperOp(chan)
        sup_l_h = hamiltonian_superop(qi.Operator.from_label(shifter_label))

        def logm(w):
            sup_s_h = qi.SuperOp(la.expm(w * sup_l_h.data))
            return la.logm((sup_s @ sup_s_h).data)

        def cost_func(w):
            gen_m = logm(w) - w * sup_l_h.data
            target = qi.SuperOp(la.expm(gen_m))
            if __HAS_DNORM:
                return dnorm(sup_s - target)
            # use 2-norm when old version qiskit is used. both cost functions perform comparably.
            return la.norm(sup_s.data - target.data)

        def log_constraint(w):
            return 2 * np.pi - la.norm(logm(w))

        cons = ({'type': 'ineq', 'fun': log_constraint})

        opt_result = opt.minimize(cost_func,
                                  x0=phase_shift,
                                  constraints=cons,
                                  method='SLSQP')
        w_opt = opt_result.x[0]

        # opt status
        print('w_opt = %.3e, cost_func = %.3e, generator norm = %.3e' %
              (w_opt, cost_func(w_opt), log_constraint(w_opt)))

        # sanitary check 1
        sup_s_h_opt = qi.SuperOp(la.expm(w_opt * sup_l_h.data))
        com_norm = la.norm((sup_s @ sup_s_h_opt - sup_s_h_opt @ sup_s).data)
        print('Commutator [S, S_H] norm = %.3e' % com_norm)

        if sanity_check:
            assert com_norm < threshold_san1

        gen_m_opt = logm(w_opt) - w_opt * sup_l_h.data

        for pauli_label in pauli_labels:
            sup_b = hamiltonian_superop(
                0.5 * qi.Operator.from_label(pauli_label).data)
            sup_b_dag = sup_b.adjoint()

            renorm = np.real(np.trace((sup_b_dag @ sup_b).data))
            coeff = np.real(
                np.trace(np.dot(gen_m_opt, sup_b_dag.data)) / renorm)
            coeffs[pauli_label].append(coeff / gate_time)

        # sanitary check 2
        reconst_ham = np.zeros((4, 4))
        for pauli_label in pauli_labels:
            ham_op = 0.5 * qi.Operator.from_label(pauli_label).data
            reconst_ham = reconst_ham + coeffs[pauli_label][-1] * ham_op

        reconst_u = qi.Operator(la.expm(-1j * reconst_ham * gate_time))
        u_fid = qi.average_gate_fidelity(chan, reconst_u)
        estimated_hamiltonian_fidelities.append(u_fid)

        if sanity_check:
            assert 1 - u_fid < threshold_san2

    # list -> ndarray
    coeffs = dict(coeffs)
    for pauli_label in coeffs.keys():
        coeffs[pauli_label] = np.array(coeffs[pauli_label])

    return coeffs, estimated_hamiltonian_fidelities
Example #30
0
        noise_transform_to_left_channel(L)

        for i in range(len(L)):
            if L[i].pulse_type == 'noise':
                pulse_noise.append(L[i])

        m = np.identity(2)
        for i in reversed(range(len(pulse_noise))):
            m = pulse_to_unitary(
                pulse_noise[i], delta /
                2) @ m  # delta/2: 1/2 here because of Clifford decomposition
        noise_unitary.append(m)

    depol_str = []
    for i in range(len(noise_unitary)):
        ch = quantum_info.Operator(noise_unitary[i])
        F_ave = quantum_info.average_gate_fidelity(ch)
        p = (d * F_ave - 1) / (d - 1)
        depol_str.append(p)
    avg_depol_str.append(np.mean(depol_str))

    depha_m = np.cos(delta) * I_1q - 1j * np.sin(delta) * Z_1q
    depha_ch = quantum_info.Operator(depha_m)
    F_depha = quantum_info.average_gate_fidelity(depha_ch)
    p_depha = (d * F_depha - 1) / (d - 1)
    depha_str.append(p_depha)

plot1 = plt.figure(1)
plt.plot(delta_list, depha_str, 'ro', markersize=2, label='channel noise')
plt.plot(delta_list,
         avg_depol_str,