Example #1
0
 def _dec_mcg_up_diag(self):
     """
     Call to create a circuit with gates that implement the MCG up to a diagonal gate.
     Remark: The qubits the gate acts on are ordered in the following way:
         q=[q_target,q_controls,q_ancilla_zero,q_ancilla_dirty]
     """
     diag = np.ones(2 ** (self.num_controls + 1)).tolist()
     q = QuantumRegister(self.num_qubits)
     circuit = QuantumCircuit(q)
     (q_target, q_controls, q_ancillas_zero, q_ancillas_dirty) = self._define_qubit_role(q)
     # ToDo: Keep this threshold updated such that the lowest gate count is achieved:
     # ToDo: we implement the MCG with a UCG up to diagonal if the number of controls is
     # ToDo: smaller than the threshold.
     threshold = float("inf")
     if self.num_controls < threshold:
         # Implement the MCG as a UCG (up to diagonal)
         gate_list = [np.eye(2, 2) for i in range(2 ** self.num_controls)]
         gate_list[-1] = self.params[0]
         ucg = UCG(gate_list, up_to_diagonal=True)
         circuit.append(ucg, [q_target] + q_controls)
         diag = ucg._get_diagonal()
         # else:
         # ToDo: Use the best decomposition for MCGs up to diagonal gates here
         # ToDo: (with all available ancillas)
     return circuit, diag
Example #2
0
 def _append_ucg_up_to_diagonal(self, circ, q, single_qubit_gates,
                                control_labels, target_label):
     (q_input, q_ancillas_for_output, q_ancillas_zero, q_ancillas_dirty) = \
         self._define_qubit_role(q)
     n = int(np.log2(self.params[0].shape[0]))
     qubits = q_input + q_ancillas_for_output
     # Note that we have to reverse the control labels, since controls are provided by
     # increasing qubit number toa UCG by convention
     control_qubits = _reverse_qubit_oder(
         _get_qubits_by_label(control_labels, qubits, n))
     target_qubit = _get_qubits_by_label([target_label], qubits, n)[0]
     ucg = UCG(single_qubit_gates, up_to_diagonal=True)
     circ.append(ucg, [target_qubit] + control_qubits)
     return ucg._get_diagonal()
Example #3
0
 def test_ucg(self):
     """Test uniformly controlled gates."""
     for squs, up_to_diagonal in itertools.product(squs_list,
                                                   up_to_diagonal_list):
         with self.subTest(single_qubit_unitaries=squs,
                           up_to_diagonal=up_to_diagonal):
             num_con = int(np.log2(len(squs)))
             q = QuantumRegister(num_con + 1)
             qc = QuantumCircuit(q)
             qc.ucg(squs, q[1:], q[0], up_to_diagonal=up_to_diagonal)
             # 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)
             if up_to_diagonal:
                 ucg = UCG(squs, up_to_diagonal=up_to_diagonal)
                 unitary = np.dot(np.diagflat(ucg._get_diagonal()), unitary)
             unitary_desired = _get_ucg_matrix(squs)
             self.assertTrue(
                 matrix_equal(unitary_desired, unitary, ignore_phase=True))
Example #4
0
def _multiplexed_control(gate, control: Union[AllOneControl, Qubits], target: Qubits):
  # TODO: Now not considering the order because this is being controlled by
  # the all 1s sequence.
  if isinstance(control, Qubits):
    control = AllOneControl(control)

  control_qubits = tuple(chain(
    *(value.qiskit_qubits for value in control.values)))
  control_patterns_count = 2 ** len(control_qubits)
  gate_list = [
    IdGate().to_matrix()
    for _ in range(control_patterns_count - 1)] + [gate.to_matrix()]
  bp.__ALLOCATIONS__[-1].circuit.append(
    UCG(gate_list, False), (target.qiskit_qubits, ) + control_qubits)