Пример #1
0
def evolve_in_real_time(logfile, qc, t, c):
    # definizione di U3 --- https://qiskit-staging.mybluemix.net/documentation/terra/summary_of_quantum_operations.html
    H, U = get_matrices(t, c)
    two_qubit_cnot_decompose = TwoQubitBasisDecomposer(CnotGate())
    C = two_qubit_cnot_decompose.__call__(U)
    i, j = 0, 1
    parameter_string = []
    for g in C:
        instruction, q1, q2 = g
        if (instruction.name == 'u3'):
            t1, t2, t3 = instruction.params
            for x in [t1, t2, t3]:
                parameter_string.append(round(x, 4))
            if (q1[0].index == 0): idx = i
            else: idx = j
            qc.u3(t1, t2, t3, idx)
        if (instruction.name == 'cx'):
            if (q1[0].index == 0):
                idx_ctrl = i
                idx_targ = j
            else:
                idx_ctrl = j
                idx_targ = i
            qc.cx(idx_ctrl, idx_targ)
    logfile.write("time = %f \n" % (t))
    #logfile.write("circuit: \n"+str(qc.draw())+"\n")
    ##logfile.write(qc.draw())
    return qc
Пример #2
0
def _basis_gates_to_decomposer_2q(basis_gates, pulse_optimize=None):
    kak_gate = _choose_kak_gate(basis_gates)
    euler_basis = _choose_euler_basis(basis_gates)

    if isinstance(kak_gate, RZXGate):
        backup_optimizer = TwoQubitBasisDecomposer(
            CXGate(), euler_basis=euler_basis, pulse_optimize=pulse_optimize)
        return XXDecomposer(euler_basis=euler_basis,
                            backup_optimizer=backup_optimizer)
    elif kak_gate is not None:
        return TwoQubitBasisDecomposer(kak_gate,
                                       euler_basis=euler_basis,
                                       pulse_optimize=pulse_optimize)
    else:
        return None
 def test_exact_supercontrolled_decompose_random(self, seeds):
     """Exact decomposition for random supercontrolled basis and random target"""
     k1 = np.kron(random_unitary(2, seed=seeds[0]).data, random_unitary(2, seed=seeds[1]).data)
     k2 = np.kron(random_unitary(2, seed=seeds[2]).data, random_unitary(2, seed=seeds[3]).data)
     basis_unitary = k1 @ Ud(np.pi / 4, 0, 0) @ k2
     decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary))
     self.check_exact_decomposition(random_unitary(4, seed=seeds[4]).data, decomposer)
Пример #4
0
    def test_euler_basis_selection(self):
        """Verify decomposition uses euler_basis for 1q gates."""

        euler_bases = [
            ('U3', ['u3']),
            ('U1X', ['u1', 'rx']),
            ('RR', ['r']),
            ('ZYZ', ['rz', 'ry']),
            ('ZXZ', ['rz', 'rx']),
            ('XYX', ['rx', 'ry']),
        ]

        kak_gates = [
            (CXGate(), 'cx'),
            (CZGate(), 'cz'),
            (iSwapGate(), 'iswap'),
            (RXXGate(np.pi / 2), 'rxx'),
        ]

        for basis in product(euler_bases, kak_gates):
            (euler_basis, oneq_gates), (kak_gate, kak_gate_name) = basis

            with self.subTest(euler_basis=euler_basis, kak_gate=kak_gate):
                decomposer = TwoQubitBasisDecomposer(kak_gate,
                                                     euler_basis=euler_basis)
                unitary = random_unitary(4)
                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))
Пример #5
0
 def test_exact_supercontrolled_decompose_random(self, seed):
     """Exact decomposition for random supercontrolled basis and random target (seed={seed})"""
     # pylint: disable=invalid-name
     k1 = np.kron(random_unitary(2, seed=seed).data, random_unitary(2, seed=seed + 1).data)
     k2 = np.kron(random_unitary(2, seed=seed + 2).data, random_unitary(2, seed=seed + 3).data)
     basis_unitary = k1 @ Ud(np.pi / 4, 0, 0) @ k2
     decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary))
     self.check_exact_decomposition(random_unitary(4, seed=seed + 4).data, decomposer)
Пример #6
0
    def test_exact_supercontrolled_decompose_random(self, nsamples=10):
        """Verify exact decomposition for random supercontrolled basis and random target"""

        for _ in range(nsamples):
            k1 = np.kron(random_unitary(2).data, random_unitary(2).data)
            k2 = np.kron(random_unitary(2).data, random_unitary(2).data)
            basis_unitary = k1 @ Ud(np.pi / 4, 0, 0) @ k2
            decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary))
            self.check_exact_decomposition(random_unitary(4).data, decomposer)
Пример #7
0
 def evolve_dimer(self,qc,i,j,dt):                       #
         c=self.B
         H,U  = get_matrices(dt,c)
         two_qubit_cnot_decompose = TwoQubitBasisDecomposer(CnotGate())
         C = two_qubit_cnot_decompose.__call__(U)
         parameter_string = []
         for g in C:
             instruction,q1,q2 = g
             if(instruction.name=='u3'):
                t1,t2,t3 = instruction.params
                for x in [t1,t2,t3]: parameter_string.append(round(x,4))
                if(q1[0].index==0): idx = i
                else:               idx = j
                qc.u3(t1,t2,t3,idx)
             if(instruction.name=='cx'):
                if(q1[0].index==0): idx_ctrl = i; idx_targ = j
                else:               idx_ctrl = j; idx_targ = i
                qc.cx(idx_ctrl,idx_targ)
         return qc
    def run(self, dag: DAGCircuit) -> DAGCircuit:
        """Run the UnitarySynthesis pass on `dag`.

        Args:
            dag: input dag.

        Returns:
            Output dag with UnitaryGates synthesized to target basis.

        Raises:
            TranspilerError:
                1. pulse_optimize is True but pulse optimal decomposition is not known
                   for requested basis.
                2. pulse_optimize is True and natural_direction is True but a preferred
                   gate direction can't be determined from the coupling map or the
                   relative gate lengths.
        """

        euler_basis = _choose_euler_basis(self._basis_gates)
        kak_gate = _choose_kak_gate(self._basis_gates)
        decomposer1q, decomposer2q = None, None
        if euler_basis is not None:
            decomposer1q = one_qubit_decompose.OneQubitEulerDecomposer(
                euler_basis)
        if kak_gate is not None:
            decomposer2q = TwoQubitBasisDecomposer(
                kak_gate,
                euler_basis=euler_basis,
                pulse_optimize=self._pulse_optimize)

        for node in dag.named_nodes(*self._synth_gates):
            if self._basis_gates and node.name in self._basis_gates:
                continue
            synth_dag = None
            wires = None
            if len(node.qargs) == 1:
                if decomposer1q is None:
                    continue
                synth_dag = circuit_to_dag(
                    decomposer1q._decompose(node.op.to_matrix()))
            elif len(node.qargs) == 2:
                if decomposer2q is None:
                    continue
                synth_dag, wires = self._synth_natural_direction(
                    node, dag, decomposer2q)
            else:
                synth_dag = circuit_to_dag(
                    isometry.Isometry(node.op.to_matrix(), 0, 0).definition)

            dag.substitute_node_with_dag(node, synth_dag, wires=wires)

        return dag
Пример #9
0
    def run(self, unitary, **options):
        # Approximation degree is set directly as an attribute on the
        # instance by the UnitarySynthesis pass here as it's not part of
        # plugin interface. However if for some reason it's not set assume
        # it's 1.
        approximation_degree = getattr(self, "_approximation_degree", 1)
        basis_gates = options["basis_gates"]
        coupling_map = options["coupling_map"][0]
        natural_direction = options["natural_direction"]
        pulse_optimize = options["pulse_optimize"]
        gate_lengths = options["gate_lengths"]
        gate_errors = options["gate_errors"]
        qubits = options["coupling_map"][1]

        euler_basis = _choose_euler_basis(basis_gates)
        kak_gate = _choose_kak_gate(basis_gates)

        decomposer1q, decomposer2q = None, None
        if euler_basis is not None:
            decomposer1q = one_qubit_decompose.OneQubitEulerDecomposer(
                euler_basis)
        if kak_gate is not None:
            decomposer2q = TwoQubitBasisDecomposer(
                kak_gate,
                euler_basis=euler_basis,
                pulse_optimize=pulse_optimize)

        synth_dag = None
        wires = None
        if unitary.shape == (2, 2):
            if decomposer1q is None:
                return None
            synth_dag = circuit_to_dag(decomposer1q._decompose(unitary))
        elif unitary.shape == (4, 4):
            if decomposer2q is None:
                return None
            synth_dag, wires = self._synth_natural_direction(
                unitary,
                coupling_map,
                qubits,
                decomposer2q,
                gate_lengths,
                gate_errors,
                natural_direction,
                approximation_degree,
                pulse_optimize,
            )
        else:
            synth_dag = circuit_to_dag(
                isometry.Isometry(unitary, 0, 0).definition)

        return synth_dag, wires
Пример #10
0
    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))
Пример #11
0
    def replace_definition_cz(self, dag: DAGCircuit) -> None:
        """by default custom two qubit gates are defined by CX and 1Qubit Gates
        this method replaces the definition by a definition consisting of CZ and 1Qubit Gates
        """
        cz_matrix = np.array(
            [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, -1]],
            dtype=complex)
        cz_gate = UnitaryGate(cz_matrix)
        two_qubit_cz_decompose = TwoQubitBasisDecomposer(cz_gate)

        for node in dag.op_nodes():
            gate = node.op
            if isinstance(gate, UnitaryGate) and gate.num_qubits == 2:
                gate.definition = two_qubit_cz_decompose(gate.to_matrix()).data
Пример #12
0
    def run(self, dag: DAGCircuit) -> DAGCircuit:
        """Run the UnitarySynthesis pass on `dag`.

        Args:
            dag: input dag.

        Returns:
            Output dag with UnitaryGates synthesized to target basis.
        """
        euler_basis = _choose_euler_basis(self._basis_gates)
        kak_gate = _choose_kak_gate(self._basis_gates)

        decomposer1q, decomposer2q = None, None
        if euler_basis is not None:
            decomposer1q = one_qubit_decompose.OneQubitEulerDecomposer(
                euler_basis)
        if kak_gate is not None:
            decomposer2q = TwoQubitBasisDecomposer(kak_gate,
                                                   euler_basis=euler_basis)

        for node in dag.named_nodes("unitary"):

            synth_dag = None
            if len(node.qargs) == 1:
                if decomposer1q is None:
                    continue
                synth_dag = circuit_to_dag(
                    decomposer1q._decompose(node.op.to_matrix()))
            elif len(node.qargs) == 2:
                if decomposer2q is None:
                    continue
                synth_dag = circuit_to_dag(
                    decomposer2q(node.op.to_matrix(),
                                 basis_fidelity=self._approximation_degree))
            else:
                synth_dag = circuit_to_dag(
                    isometry.Isometry(node.op.to_matrix(), 0, 0).definition)

            dag.substitute_node_with_dag(node, synth_dag)

        return dag
Пример #13
0
 def test_exact_nonsupercontrolled_decompose(self):
     """Check that the nonsupercontrolled basis throws a warning"""
     with self.assertWarns(UserWarning, msg="Supposed to warn when basis non-supercontrolled"):
         TwoQubitBasisDecomposer(UnitaryGate(Ud(np.pi / 4, 0.2, 0.1)))
Пример #14
0
    def _find_decomposer_2q_from_target(self, target, qubits, pulse_optimize):
        qubits_tuple = tuple(qubits)
        reverse_tuple = (qubits[1], qubits[0])
        if qubits_tuple in self._decomposer_cache:
            return self._decomposer_cache[qubits_tuple]

        matching = {}
        reverse = {}
        kak_gates = _find_matching_kak_gates(target)
        euler_basis_gates = _find_matching_euler_bases(target)
        decomposers_2q = []
        # find all decomposers
        for kak_gate, euler_basis in product(kak_gates, euler_basis_gates):
            gate_name = None
            if isinstance(kak_gate, tuple):
                gate_name = kak_gate[1]
                kak_gate = kak_gate[0]
            if isinstance(kak_gate, RZXGate):
                backup_optimizer = TwoQubitBasisDecomposer(
                    CXGate(),
                    euler_basis=euler_basis,
                    pulse_optimize=pulse_optimize)
                decomposer = XXDecomposer(euler_basis=euler_basis,
                                          backup_optimizer=backup_optimizer)
                if gate_name is not None:
                    decomposer.gate_name = gate_name
                decomposers_2q.append(decomposer)
            elif kak_gate is not None:
                decomposer = TwoQubitBasisDecomposer(
                    kak_gate,
                    euler_basis=euler_basis,
                    pulse_optimize=pulse_optimize)
                if gate_name is not None:
                    decomposer.gate_name = gate_name
                decomposers_2q.append(decomposer)

        # Find lowest error matching or reverse decomposer and use that
        for index, decomposer in enumerate(decomposers_2q):
            gate_name = getattr(decomposer, "gate_name", decomposer.gate.name)
            props_dict = target[gate_name]
            if target.instruction_supported(gate_name, qubits_tuple):
                if props_dict is None or None in props_dict:
                    error = 0.0
                else:
                    error = getattr(props_dict[qubits_tuple], "error", 0.0)
                    if error is None:
                        error = 0.0
                matching[index] = error
            # Skip reverse check if we already have matching
            elif not matching and target.instruction_supported(
                    gate_name, reverse_tuple):
                if props_dict is None or None in props_dict:
                    error = 0.0
                else:
                    error = getattr(props_dict[reverse_tuple], "error", 0.0)
                    if error is None:
                        error = 0.0
                reverse[index] = error
        preferred_direction = None
        if matching:
            preferred_direction = [0, 1]
            min_error_index = min(matching, key=matching.get)
            decomposer2q = decomposers_2q[min_error_index]
        elif reverse:
            preferred_direction = [1, 0]
            min_error_index = min(reverse, key=reverse.get)
            decomposer2q = decomposers_2q[min_error_index]
        # If no matching or reverse direction is found just pick one, if natural direction is
        # enforced it will fail later
        else:
            decomposer2q = decomposers_2q[0]
        self._decomposer_cache[qubits_tuple] = (decomposer2q,
                                                preferred_direction)
        return (decomposer2q, preferred_direction)