def test_euler_basis_selection(self, euler_bases, kak_gates, seed):
        """Verify decomposition uses euler_basis for 1q gates."""
        (euler_basis, oneq_gates) = euler_bases
        (kak_gate, kak_gate_name) = kak_gates

        with self.subTest(euler_basis=euler_basis, kak_gate=kak_gate):
            decomposer = TwoQubitBasisDecomposer(kak_gate,
                                                 euler_basis=euler_basis)
            unitary = random_unitary(4, seed=seed)
            self.check_exact_decomposition(unitary.data, decomposer)

            decomposition_basis = set(decomposer(unitary).count_ops())
            requested_basis = set(oneq_gates + [kak_gate_name])
            self.assertTrue(decomposition_basis.issubset(requested_basis))
    def test_global_phase_ucg(self):
        """Test global phase of uniformly controlled gates"""
        gates = [random_unitary(2).data for _ in range(2**2)]
        num_con = int(np.log2(len(gates)))
        q = QuantumRegister(num_con + 1)
        qc = QuantumCircuit(q)

        qc.uc(gates, q[1:], q[0], up_to_diagonal=False)
        simulator = BasicAer.get_backend("unitary_simulator")
        result = execute(qc, simulator).result()
        unitary = result.get_unitary(qc)
        unitary_desired = _get_ucg_matrix(gates)

        self.assertTrue(np.allclose(unitary_desired, unitary))
Exemple #3
0
def unitary_random_gate_counts_nondeterministic(shots):
    """Unitary gate test circuits with nondeterministic counts."""
    # random_unitary seed = nq
    targets = []
    for n in range(1, 5):
        unitary1 = random_unitary(2**n, seed=n)
        state = Statevector.from_label(n * '0').evolve(unitary1)
        probs = state.probabilities_dict()
        hex_counts = {
            hex(int(key, 2)): val * shots
            for key, val in probs.items()
        }
        targets.append(hex_counts)
    return targets
 def test_two_qubit_kak(self):
     """Verify KAK decomposition for random Haar 4x4 unitaries.
     """
     for _ in range(100):
         unitary = random_unitary(4)
         with self.subTest(unitary=unitary):
             decomp_circuit = two_qubit_kak(unitary)
             result = execute(decomp_circuit, UnitarySimulatorPy()).result()
             decomp_unitary = Operator(result.get_unitary())
             equal_up_to_phase = matrix_equal(unitary.data,
                                              decomp_unitary.data,
                                              ignore_phase=True,
                                              atol=1e-7)
             self.assertTrue(equal_up_to_phase)
 def test_coupling_map_unequal_durations(self, opt):
     """Test direction with transpile/execute with backend durations."""
     qr = QuantumRegister(2)
     circ = QuantumCircuit(qr)
     circ.append(random_unitary(4, seed=1), [1, 0])
     backend = FakeVigo()
     tqc = transpile(circ,
                     backend=backend,
                     optimization_level=opt,
                     translation_method="synthesis")
     tqc_index = {qubit: index for index, qubit in enumerate(tqc.qubits)}
     self.assertTrue(
         all(((0, 1) == (tqc_index[qlist[0]], tqc_index[qlist[1]])
              for _, qlist, _ in tqc.get_instructions("cx"))))
Exemple #6
0
    def __init__(self,
                 num_qubits: int,
                 depth: Optional[int] = None,
                 seed: Optional[int] = None,
                 classical_permutation: bool = True) -> None:
        """Create quantum volume model circuit of size num_qubits x depth.

        Args:
            num_qubits: number of active qubits in model circuit.
            depth: layers of SU(4) operations in model circuit.
            seed: randomization seed.
            classical_permutation: use classical permutations at every layer,
                rather than quantum.
        """
        depth = depth or num_qubits  # how many layers of SU(4)
        width = int(np.floor(num_qubits/2))  # how many SU(4)s fit in each layer

        if seed is None:
            rng_set = np.random.RandomState()
            seed = rng_set.randint(low=1, high=1000)

        name = "quantum_volume_" + str([num_qubits, depth, seed]).replace(' ', '')

        super().__init__(num_qubits, name=name)

        rng = np.random.default_rng(seed)

        unitary_seeds = rng.integers(low=1, high=1000, size=[depth, width])

        # For each layer, generate a permutation of qubits
        # Then generate and apply a Haar-random SU(4) to each pair
        inner = QuantumCircuit(num_qubits)
        perm_0 = list(range(num_qubits))
        for d in range(depth):
            perm = rng.permutation(perm_0)
            if not classical_permutation:
                layer_perm = Permutation(num_qubits, perm)
                inner.compose(layer_perm, inplace=True)
            for w in range(width):
                seed_u = unitary_seeds[d][w]
                su4 = random_unitary(4, seed=seed_u).to_instruction()
                su4.label = 'su4_' + str(seed_u)
                if classical_permutation:
                    physical_qubits = int(perm[2*w]), int(perm[2*w+1])
                    inner.compose(su4, [physical_qubits[0], physical_qubits[1]], inplace=True)
                else:
                    inner.compose(su4, [2*w, 2*w+1], inplace=True)
        inner.label = name
        self.append(inner, self.qubits)
Exemple #7
0
 def test_approx_random_unitary_channel_2q(self):
     noise = Kraus(random_unitary(4, seed=123))
     for opstr in ['pauli']:
         new_result = approximate_quantum_error(noise,
                                                operator_string=opstr)
         old_result = self.old_approximate_quantum_error(
             noise, operator_string=opstr)
         self.assertEqual(new_result, old_result)
     for opstr in ['reset']:
         new_result = approximate_quantum_error(noise,
                                                operator_string=opstr)
         old_result = self.old_approximate_quantum_error(
             noise, operator_string=opstr)
         self.assertGreaterEqual(process_fidelity(noise, new_result),
                                 process_fidelity(noise, old_result))
 def test_mixed_registers(self):
     """Test circuit with mix of standalone and shared registers."""
     qubits = [Qubit() for _ in range(5)]
     clbits = [Clbit() for _ in range(5)]
     qc = QuantumCircuit()
     qc.add_bits(qubits)
     qc.add_bits(clbits)
     qr = QuantumRegister(bits=qubits)
     cr = ClassicalRegister(bits=clbits)
     qc.add_register(qr)
     qc.add_register(cr)
     qr_standalone = QuantumRegister(2, "standalone")
     qc.add_register(qr_standalone)
     cr_standalone = ClassicalRegister(2, "classical_standalone")
     qc.add_register(cr_standalone)
     qc.unitary(random_unitary(32, seed=42), qr)
     qc.unitary(random_unitary(4, seed=100), qr_standalone)
     qc.measure(qr, cr)
     qc.measure(qr_standalone, cr_standalone)
     qpy_file = io.BytesIO()
     dump(qc, qpy_file)
     qpy_file.seek(0)
     new_circ = load(qpy_file)[0]
     self.assertEqual(qc, new_circ)
Exemple #9
0
    def test_two_qubit_synthesis_to_directional_cx_from_coupling_map_natural_false(self):
        """Verify natural cx direction is used when specified in coupling map
        when natural_direction is None."""
        # TODO: should make check more explicit e.g. explicitly set gate
        # direction in test instead of using specific fake backend
        backend = FakeVigo()
        conf = backend.configuration()
        qr = QuantumRegister(2)
        coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]])
        triv_layout_pass = TrivialLayout(coupling_map)
        qc = QuantumCircuit(qr)
        qc.unitary(random_unitary(4, seed=12), [0, 1])
        unisynth_pass = UnitarySynthesis(
            basis_gates=conf.basis_gates,
            coupling_map=coupling_map,
            backend_props=backend.properties(),
            pulse_optimize=True,
            natural_direction=False,
        )
        pm = PassManager([triv_layout_pass, unisynth_pass])
        qc_out = pm.run(qc)

        unisynth_pass_nat = UnitarySynthesis(
            basis_gates=conf.basis_gates,
            coupling_map=coupling_map,
            backend_props=backend.properties(),
            pulse_optimize=True,
            natural_direction=False,
        )

        pm_nat = PassManager([triv_layout_pass, unisynth_pass_nat])
        qc_out_nat = pm_nat.run(qc)
        # the decomposer defaults to the [1, 0] direction but the coupling
        # map specifies a [0, 1] direction. Check that this is respected.
        self.assertTrue(
            all(
                # pylint: disable=no-member
                ([qr[1], qr[0]] == qlist for _, qlist, _ in qc_out.get_instructions("cx"))
            )
        )
        self.assertTrue(
            all(
                # pylint: disable=no-member
                ([qr[1], qr[0]] == qlist for _, qlist, _ in qc_out_nat.get_instructions("cx"))
            )
        )
        self.assertEqual(Operator(qc), Operator(qc_out))
        self.assertEqual(Operator(qc), Operator(qc_out_nat))
Exemple #10
0
    def test_unitary_nottogether_across_4(self):
        """ Unitary that are 2 bits apart"""
        expected = '\n'.join([
            "        ┌──────────┐", "q_0: |0>┤0         ├",
            "        │          │", "q_1: |0>┤          ├",
            "        │  unitary │", "q_2: |0>┤          ├",
            "        │          │", "q_3: |0>┤1         ├",
            "        └──────────┘"
        ])

        qr = QuantumRegister(4, 'q')
        qc = QuantumCircuit(qr)

        qc.append(random_unitary(4, seed=42), [qr[0], qr[3]])

        self.assertEqual(str(_text_circuit_drawer(qc)), expected)
 def test_non_overlapping_kak_gates_with_backendv2(self, opt_level):
     qr = QuantumRegister(2)
     circ = QuantumCircuit(qr)
     circ.append(random_unitary(4, seed=1), [1, 0])
     backend = FakeBackendV2()
     tqc = transpile(
         circ,
         backend=backend,
         optimization_level=opt_level,
         translation_method="synthesis",
         layout_method="trivial",
     )
     tqc_index = {qubit: index for index, qubit in enumerate(tqc.qubits)}
     self.assertGreaterEqual(len(tqc.get_instructions("ecr")), 1)
     for instr in tqc.get_instructions("ecr"):
         self.assertEqual((1, 0), (tqc_index[instr.qubits[0]], tqc_index[instr.qubits[1]]))
def qiskit_custom_unroll():
    qr = QuantumRegister(5)
    cr = ClassicalRegister(5)
    qiskit_circuit = QuantumCircuit(qr, cr)
    """standard qiskit gates """
    gate = qiskit_gates.CXGate()
    qiskit_circuit.append(gate, qargs=[3, 2])
    gate = qiskit_gates.CZGate()
    qiskit_circuit.append(gate, qargs=[1, 2])
    gate = qiskit_gates.HGate()
    qiskit_circuit.append(gate, qargs=[1])
    gate = qiskit_gates.CCXGate()
    qiskit_circuit.append(gate, qargs=[0, 1, 2])
    gate = qiskit_gates.RXGate(np.pi / 4)
    qiskit_circuit.append(gate, qargs=[0])
    """custom gate"""
    # custom_matrix1 = np.array([
    #     [np.e**(1j*np.pi/2), 0, 0, 0],
    #     [0, 1, 0, 0],
    #     [0, 0, 1, 0],
    #     [0, 0, 0, np.e**(1j*np.pi/2)]
    # ], dtype=complex)
    # custom_matrix1 = random_unitary(4, seed=42)
    # custom_gate1 = UnitaryGate(custom_matrix1, label="unitary_custom")
    # qiskit_circuit.append(custom_gate1, qargs=[0,1])
    """custom gate #2"""
    custom_matrix1 = random_unitary(4, seed=42)
    custom_gate1 = UnitaryGate(custom_matrix1, label="unitary_2qubits")
    qiskit_circuit.append(custom_gate1, qargs=[0, 1])
    """custom gate #3"""
    # custom_matrix1 = random_unitary(8, seed=42)
    # custom_gate1 = UnitaryGate(custom_matrix1, label="unitary_3qubits")
    # qiskit_circuit.append(custom_gate1, qargs=[0,1,2])
    """custom gate #4"""
    # operator = Operator([[1, 0, 0, 0],
    #           [0, 0, 0, 1],
    #           [0, 0, 1, 0],
    #           [0, 1, 0, 0]])
    # custom_gate1 = UnitaryGate(custom_matrix1, label="operator")
    # qiskit_circuit.unitary(operator, [0,1], label="operator")
    """parameterized qiskit cirucit"""
    # theta = qiskit_circuit_library.Parameter("θ")
    # qiskit_circuit.rz(theta, 1)

    # show_figure(qiskit_circuit)
    return qiskit_circuit
Exemple #13
0
 def test_one_qubit_euler_angles(self):
     """Verify euler_angles_1q produces correct Euler angles for
     a single-qubit unitary.
     """
     for _ in range(100):
         unitary = random_unitary(2)
         with self.subTest(unitary=unitary):
             angles = euler_angles_1q(unitary.data)
             decomp_circuit = QuantumCircuit(1)
             decomp_circuit.u3(*angles, 0)
             result = execute(decomp_circuit, UnitarySimulatorPy()).result()
             decomp_unitary = Operator(result.get_unitary())
             equal_up_to_phase = matrix_equal(unitary.data,
                                              decomp_unitary.data,
                                              ignore_phase=True,
                                              atol=1e-7)
             self.assertTrue(equal_up_to_phase)
Exemple #14
0
    def test_scale(self):
        """Tests scale
        See: https://github.com/Qiskit/qiskit-terra/issues/4179"""
        filename1 = self._get_resource_path('test_latex_scale_default.tex')
        filename2 = self._get_resource_path('test_latex_scale_half.tex')
        filename3 = self._get_resource_path('test_latex_scale_double.tex')
        circuit = QuantumCircuit(5)
        circuit.unitary(random_unitary(2 ** 5), circuit.qubits)

        circuit_drawer(circuit, filename=filename1, output='latex_source')

        self.assertEqualToReference(filename1)
        circuit_drawer(circuit, filename=filename2, output='latex_source', scale=0.5)

        self.assertEqualToReference(filename2)
        circuit_drawer(circuit, filename=filename3, output='latex_source', scale=2.0)

        self.assertEqualToReference(filename3)
Exemple #15
0
def build_model_circuit(width, depth, seed=None):
    """
    The model circuits consist of layers of Haar random
    elements of SU(4) applied between corresponding pairs
    of qubits in a random bipartition.
    """
    np.random.seed(seed)
    circuit = QuantumCircuit(width)
    # For each layer
    for _ in range(depth):
        # Generate uniformly random permutation Pj of [0...n-1]
        perm = np.random.permutation(width)
        # For each pair p in Pj, generate Haar random SU(4)
        for k in range(int(np.floor(width / 2))):
            U = random_unitary(4)
            pair = int(perm[2 * k]), int(perm[2 * k + 1])
            circuit.append(U, [pair[0], pair[1]])
    return circuit
    def test_isometry(self):
        """Tests for the decomposition of isometries from m to n qubits"""
        for iso in [
                np.eye(2, 2),
                random_unitary(2).data,
                np.eye(4, 4),
                random_unitary(4).data[:, 0],
                np.eye(4, 4)[:, 0:2],
                random_unitary(4).data,
                np.eye(4,
                       4)[:,
                          np.random.permutation(np.eye(4, 4).shape[1])][:,
                                                                        0:2],
                np.eye(8, 8)[:,
                             np.random.permutation(np.eye(8, 8).shape[1])],
                random_unitary(8).data[:, 0:4],
                random_unitary(8).data,
                random_unitary(16).data,
                random_unitary(16).data[:, 0:8]
        ]:
            with self.subTest(iso=iso):
                if len(iso.shape) == 1:
                    iso = iso.reshape((len(iso), 1))
                num_q_input = int(np.log2(iso.shape[1]))
                num_q_ancilla_for_output = int(np.log2(
                    iso.shape[0])) - num_q_input
                n = num_q_input + num_q_ancilla_for_output
                q = QuantumRegister(n)
                qc = QuantumCircuit(q)
                qc.isometry(iso, q[:num_q_input], q[num_q_input:])

                # Verify the circuit can be decomposed
                self.assertIsInstance(qc.decompose(), QuantumCircuit)

                # Decompose the gate
                qc = transpile(qc, basis_gates=['u1', 'u3', 'u2', 'cx', 'id'])

                # Simulate the decomposed gate
                simulator = BasicAer.get_backend('unitary_simulator')
                result = execute(qc, simulator).result()
                unitary = result.get_unitary(qc)
                iso_from_circuit = unitary[::, 0:2**num_q_input]
                iso_desired = iso
                self.assertTrue(
                    matrix_equal(iso_from_circuit,
                                 iso_desired,
                                 ignore_phase=True))
Exemple #17
0
def unitary_random_gate_circuits_nondeterministic(final_measure=True):
    """Unitary gate test circuits with random unitary gate and nondeterministic count output."""
    # random_unitary seed = nq
    circuits = []
    for n in range(1, 5):
        qr = QuantumRegister(n, 'qr')
        if final_measure:
            cr = ClassicalRegister(n, 'cr')
            regs = (qr, cr)
        else:
            regs = (qr, )

        circuit = QuantumCircuit(*regs)
        circuit.unitary(random_unitary(2**n, seed=n), list(range(n)))
        if final_measure:
            circuit.barrier(qr)
            circuit.measure(qr, cr)
        circuits.append(circuit)

    return circuits
    def __init__(self,
                 num_qubits: int,
                 depth: Optional[int] = None,
                 seed: Optional[int] = None) -> QuantumCircuit:
        """Create quantum volume model circuit of size num_qubits x depth.

        Args:
            num_qubits: number of active qubits in model circuit.
            depth: layers of SU(4) operations in model circuit.
            seed: randomization seed.

        Returns:
            QuantumCircuit: a randomly constructed quantum volume model circuit.

        Reference Circuit:
            .. jupyter-execute::
                :hide-code:

                from qiskit.circuit.library import QuantumVolume
                import qiskit.tools.jupyter
                circuit = QuantumVolume(5, seed=42)
                %circuit_library_info circuit
        """
        super().__init__(num_qubits, name="volume")

        depth = depth or num_qubits  # how many layers of SU(4)
        width = int(np.floor(num_qubits /
                             2))  # how many SU(4)s fit in each layer
        rng = np.random.RandomState(seed)

        unitary_seeds = rng.randint(low=1, high=1000, size=[depth, width])

        # For each layer, generate a permutation of qubits
        # Then generate and apply a Haar-random SU(4) to each pair
        perm_0 = list(range(num_qubits))
        for d in range(depth):
            perm = rng.permutation(perm_0)
            for w in range(width):
                physical_qubits = int(perm[2 * w]), int(perm[2 * w + 1])
                su4 = random_unitary(4, seed=unitary_seeds[d][w])
                self.append(su4, [physical_qubits[0], physical_qubits[1]])
 def test_reverse_direction(self, opt_level):
     target = Target(2)
     target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=1.2e-6)})
     target.add_instruction(ECRGate(), {(0, 1): InstructionProperties(error=1.2e-7)})
     target.add_instruction(
         UGate(Parameter("theta"), Parameter("phi"), Parameter("lam")), {(0,): None, (1,): None}
     )
     qr = QuantumRegister(2)
     circ = QuantumCircuit(qr)
     circ.append(random_unitary(4, seed=1), [1, 0])
     tqc = transpile(
         circ,
         target=target,
         optimization_level=opt_level,
         translation_method="synthesis",
         layout_method="trivial",
     )
     tqc_index = {qubit: index for index, qubit in enumerate(tqc.qubits)}
     self.assertGreaterEqual(len(tqc.get_instructions("ecr")), 1)
     for instr in tqc.get_instructions("ecr"):
         self.assertEqual((0, 1), (tqc_index[instr.qubits[0]], tqc_index[instr.qubits[1]]))
    def test_coupling_unequal_duration_with_backendv2(self, opt_level, bidirectional):
        qr = QuantumRegister(2)
        circ = QuantumCircuit(qr)
        circ.append(random_unitary(4, seed=1), [1, 0])
        backend = FakeBackend5QV2(bidirectional)
        tqc = transpile(
            circ,
            backend=backend,
            optimization_level=opt_level,
            translation_method="synthesis",
            layout_method="trivial",
        )
        tqc_index = {qubit: index for index, qubit in enumerate(tqc.qubits)}
        self.assertGreaterEqual(len(tqc.get_instructions("cx")), 1)
        if bidirectional:
            for instr in tqc.get_instructions("cx"):
                self.assertEqual((1, 0), (tqc_index[instr.qubits[0]], tqc_index[instr.qubits[1]]))

        else:
            for instr in tqc.get_instructions("cx"):
                self.assertEqual((0, 1), (tqc_index[instr.qubits[0]], tqc_index[instr.qubits[1]]))
 def test_two_qubit_pulse_optimal_true_raises(self):
     """Verify raises if pulse optimal==True but cx is not in the backend basis."""
     backend = FakeVigo()
     conf = backend.configuration()
     # this assumes iswawp pulse optimal decomposition doesn't exist
     conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates]
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         coupling_map=coupling_map,
         backend_props=backend.properties(),
         pulse_optimize=True,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     with self.assertRaises(QiskitError):
         pm.run(qc)
    def build_model_circuit_kak(width, depth, seed=None):
        """Create quantum volume model circuit on quantum register qreg of given
        depth (default depth is equal to width) and random seed.
        The model circuits consist of layers of Haar random
        elements of U(4) applied between corresponding pairs
        of qubits in a random bipartition.
        """
        qreg = QuantumRegister(width)
        depth = depth or width

        np.random.seed(seed)
        circuit = QuantumCircuit(qreg,
                                 name="Qvolume: %s by %s, seed: %s" %
                                 (width, depth, seed))

        for _ in range(depth):
            # Generate uniformly random permutation Pj of [0...n-1]
            perm = np.random.permutation(width)

            # For each pair p in Pj, generate Haar random U(4)
            # Decompose each U(4) into CNOT + SU(2)
            for k in range(width // 2):
                U = random_unitary(4, seed).data
                for gate in two_qubit_cnot_decompose(U):
                    qs = [qreg[int(perm[2 * k + i.index])] for i in gate[1]]
                    pars = gate[0].params
                    name = gate[0].name
                    if name == "cx":
                        circuit.cx(qs[0], qs[1])
                    elif name == "u1":
                        circuit.u1(pars[0], qs[0])
                    elif name == "u2":
                        circuit.u2(*pars[:2], qs[0])
                    elif name == "u3":
                        circuit.u3(*pars[:3], qs[0])
                    elif name == "id":
                        pass  # do nothing
                    else:
                        raise Exception("Unexpected gate name: %s" % name)
        return circuit
Exemple #23
0
 def test_unitary(self):
     """Test unitary gate instruction"""
     num_trials = 10
     max_qubits = 3
     # Test 1 to max_qubits for random n-qubit unitary gate
     for i in range(max_qubits):
         num_qubits = i + 1
         unitary_init = Operator(np.eye(2 ** num_qubits))
         qr = QuantumRegister(num_qubits, "qr")
         for _ in range(num_trials):
             # Create random unitary
             unitary = random_unitary(2 ** num_qubits)
             # Compute expected output state
             unitary_target = unitary.dot(unitary_init)
             # Simulate output on circuit
             circuit = QuantumCircuit(qr)
             circuit.unitary(unitary, qr)
             job = execute(circuit, self.backend)
             result = job.result()
             unitary_out = Operator(result.get_unitary(0))
             fidelity = process_fidelity(unitary_target, unitary_out)
             self.assertGreater(fidelity, 0.999)
 def test_two_qubit_natural_direction_true_gate_length_raises(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     for _, nduv in backend.properties()._gates["cx"].items():
         nduv["gate_length"] = (4e-7, nduv["gate_length"][1])
         nduv["gate_error"] = (7e-3, nduv["gate_error"][1])
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 0], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         backend_props=backend.properties(),
         pulse_optimize=True,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     with self.assertRaises(TranspilerError):
         pm.run(qc)
Exemple #25
0
    def test_mps_options(self):
        """Test MPS options"""
        shots = 4000
        method="matrix_product_state"
        backend_swap_left = self.backend(method=method,
                                          mps_swap_direction='mps_swap_left')
        backend_swap_right = self.backend(method=method,
                                          mps_swap_direction='mps_swap_right')
        backend_approx = self.backend(method=method,
                                     matrix_product_state_max_bond_dimension=8)
        # The test must be large enough and entangled enough so that
        # approximation actually truncates something
        n = 10
        circuit = QuantumCircuit(n)
        for times in range(2):
            for i in range(0, n, 2):
                circuit.unitary(random_unitary(4), [i, i+1])
            for i in range(1, n-1):
                circuit.cx(0, i)
        circuit.save_statevector('sv')

        result_swap_left = backend_swap_left.run(circuit, shots=shots).result()
        sv_left = result_swap_left.data(0)['sv']
        
        result_swap_right = backend_swap_right.run(circuit, shots=shots).result()
        sv_right = result_swap_right.data(0)['sv']
        
        result_approx = backend_approx.run(circuit, shots=shots).result()
        sv_approx = result_approx.data(0)['sv']

        # swap_left and swap_right should give the same state vector
        self.assertAlmostEqual(state_fidelity(sv_left, sv_right), 1.0)
        
        # Check that the fidelity of approximation is reasonable
        self.assertGreaterEqual(state_fidelity(sv_left, sv_approx), 0.80)

        # Check that the approximated result is not identical to the exact
        # result, because that could mean there was actually no approximation
        self.assertLessEqual(state_fidelity(sv_left, sv_approx), 0.999)
 def test_two_qubit_natural_direction_true_duration_fallback(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     # conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates]
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 0], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         coupling_map=coupling_map,
         backend_props=backend.properties(),
         pulse_optimize=True,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     qc_out = pm.run(qc)
     self.assertTrue(
         all(((qr[0], qr[1]) == instr.qubits for instr in qc_out.get_instructions("cx")))
     )
 def test_unitary(self):
     """Test unitary gate instruction"""
     num_trials = 10
     max_qubits = 3
     # Test 1 to max_qubits for random n-qubit unitary gate
     for i in range(max_qubits):
         num_qubits = i + 1
         psi_init = np.zeros(2**num_qubits)
         psi_init[0] = 1.0
         qr = QuantumRegister(num_qubits, 'qr')
         for _ in range(num_trials):
             # Create random unitary
             unitary = random_unitary(2**num_qubits)
             # Compute expected output state
             psi_target = unitary.data.dot(psi_init)
             # Simulate output on circuit
             circuit = QuantumCircuit(qr)
             circuit.unitary(unitary, qr)
             job = execute(circuit, self.backend)
             result = job.result()
             psi_out = result.get_statevector(0)
             fidelity = state_fidelity(psi_target, psi_out)
             self.assertGreater(fidelity, 0.999)
    def test_random_unitary_gate_with_permutations(self, method, device, perm):
        """Test simulation with random unitary gate with permutations."""
        backend = self.backend(method=method, device=device)
        all_permutations = list(itertools.permutations([0, 1, 2]))
        unitary_matrix = random_unitary(8, seed=5)
        n = 3
        shots = 2000
        circuit = QuantumCircuit(n, n)
        circuit.unitary(unitary_matrix, perm)
        circuit.barrier(range(n))
        circuit.measure(range(n), range(n))
        circuits = transpile(circuit, backend)
        result = backend.run(circuits, shots=shots).result()

        state = Statevector.from_label(n * '0').evolve(unitary_matrix, perm)
        state.seed(11111)
        probs = state.probabilities_dict()
        hex_counts = {
            hex(int(key, 2)): val * shots
            for key, val in probs.items()
        }
        self.assertSuccess(result)
        self.compare_counts(result, [circuit], [hex_counts],
                            delta=0.05 * shots)
 def test_two_qubit_synthesis_not_pulse_optimal(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     backend = FakeVigo()
     conf = backend.configuration()
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         coupling_map=coupling_map,
         backend_props=backend.properties(),
         pulse_optimize=False,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     qc_out = pm.run(qc)
     if isinstance(qc_out, QuantumCircuit):
         num_ops = qc_out.count_ops()
     else:
         num_ops = qc_out[0].count_ops()
     self.assertIn("sx", num_ops)
     self.assertGreaterEqual(num_ops["sx"], 16)
    def test_random_unitary_gate_with_permutations(self):
        """Test simulation with random unitary gate with permutations."""
        all_permutations = list(itertools.permutations([0, 1, 2]))
        unitary_matrix = random_unitary(8, seed=5)
        n = 3
        shots = 2000
        for perm in all_permutations:
            circuit = QuantumCircuit(n, n)
            circuit.unitary(unitary_matrix, perm)
            circuit.barrier(range(n))
            circuit.measure(range(n), range(n))
            result = execute(circuit,
                             self.SIMULATOR,
                             shots=shots,
                             optimization_level=0,
                             **self.BACKEND_OPTS).result()

            state = Statevector.from_label(n * '0').evolve(
                unitary_matrix, perm)
            counts = state.sample_counts(shots=shots)
            hex_counts = {hex(int(key, 2)): val for key, val in counts.items()}
            self.assertSuccess(result)
            self.compare_counts(result, [circuit], [hex_counts],
                                delta=0.05 * shots)