Ejemplo n.º 1
0
def _double_controlled_modular_adder(constant: int, N: int, n: int, qft: Gate,
                                     iqft: Gate) -> Gate:
    ctrl_qreg = QuantumRegister(2, name='ctrl')
    x_qreg = QuantumRegister(n, name='x')
    g_qreg = QuantumRegister(n - 1 if n >= 2 else 1, name='g')
    flag_qreg = QuantumRegister(1, name='flag')

    circuit = QuantumCircuit(ctrl_qreg,
                             x_qreg,
                             g_qreg,
                             flag_qreg,
                             name=f'CC-MA_({constant})_Mod_{N}')

    adder_regs = list(chain(flag_qreg, x_qreg))

    circuit.append(double_controlled_comparator(N - constant, n),
                   circuit.qubits)

    circuit.append(qft, x_qreg)
    circuit.append(
        phi_constant_adder(get_angles(constant, n)).control(1), adder_regs)
    circuit.ccx(ctrl_qreg[0], ctrl_qreg[1], flag_qreg[0])
    circuit.append(
        phi_constant_adder(get_angles(N - constant, n)).control(1).inverse(),
        adder_regs)
    circuit.append(iqft, x_qreg)

    circuit.append(double_controlled_comparator(constant, n), circuit.qubits)

    return circuit.to_gate()
Ejemplo n.º 2
0
    def _construct_circuit_with_semiclassical_QFT(self, a: int, N: int,
                                                  n: int) -> QuantumCircuit:
        self._qft = QFT(n + 1, do_swaps=False).to_gate()
        self._iqft = self._qft.inverse()

        phi_add_N = phi_constant_adder(get_angles(N, n + 1))
        self._iphi_add_N = phi_add_N.inverse()
        self._c_phi_add_N = phi_add_N.control(1)

        return super()._construct_circuit_with_semiclassical_QFT(a, N, n)
Ejemplo n.º 3
0
def _double_controlled_phi_add_mod_N(angles: Union[np.ndarray,
                                                   ParameterVector],
                                     c_phi_add_N: Gate, iphi_add_N: Gate,
                                     qft: Gate, iqft: Gate) -> QuantumCircuit:
    ctrl_qreg = QuantumRegister(2, 'ctrl')
    b_qreg = QuantumRegister(len(angles), 'b')
    flag_qreg = QuantumRegister(1, 'flag')

    circuit = QuantumCircuit(ctrl_qreg,
                             b_qreg,
                             flag_qreg,
                             name='ccphi_add_a_mod_N')

    cc_phi_add_a = phi_constant_adder(angles).control(2)
    cc_iphi_add_a = cc_phi_add_a.inverse()

    circuit.append(cc_phi_add_a, [*ctrl_qreg, *b_qreg])

    circuit.append(iphi_add_N, b_qreg)

    circuit.append(iqft, b_qreg)
    circuit.cx(b_qreg[-1], flag_qreg[0])
    circuit.append(qft, b_qreg)

    circuit.append(c_phi_add_N, [*flag_qreg, *b_qreg])

    circuit.append(cc_iphi_add_a, [*ctrl_qreg, *b_qreg])

    circuit.append(iqft, b_qreg)
    circuit.x(b_qreg[-1])
    circuit.cx(b_qreg[-1], flag_qreg[0])
    circuit.x(b_qreg[-1])
    circuit.append(qft, b_qreg)

    circuit.append(cc_phi_add_a, [*ctrl_qreg, *b_qreg])

    return circuit
Ejemplo n.º 4
0
def modular_exponentiation_gate(constant: int, N: int, n: int) -> Instruction:
    up_qreg = QuantumRegister(2 * n, name='up')
    down_qreg = QuantumRegister(n, name='down')
    aux_qreg = QuantumRegister(n + 2, name='aux')

    circuit = QuantumCircuit(up_qreg,
                             down_qreg,
                             aux_qreg,
                             name=f'{constant}^x mod {N}')

    qft = QFT(n + 1, do_swaps=False).to_gate()
    iqft = qft.inverse()

    phi_add_N = phi_constant_adder(get_angles(N, n + 1))
    iphi_add_N = phi_add_N.inverse()
    c_phi_add_N = phi_add_N.control(1)

    for i in range(2 * n):
        partial_constant = pow(constant, pow(2, i), mod=N)
        modulo_multiplier = controlled_modular_multiplication_gate(
            partial_constant, N, n, c_phi_add_N, iphi_add_N, qft, iqft)
        circuit.append(modulo_multiplier, [up_qreg[i], *down_qreg, *aux_qreg])

    return circuit.to_instruction()