Esempio 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()
Esempio 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)
Esempio n. 3
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()
Esempio n. 4
0
 def append_adder(adder: QuantumCircuit, constant: int, idx: int):
     partial_constant = (pow(2, idx, mod=N) * constant) % N
     angles = get_angles(partial_constant, n + 1)
     bound = adder.assign_parameters({angle_params: angles})
     circuit.append(bound, [*ctrl_qreg, x_qreg[idx], *b_qreg, *flag_qreg])