Source code for qibo.models.qft

import math

from qibo import gates
from qibo.config import raise_error
from qibo.models.circuit import Circuit


[docs]def QFT(nqubits, with_swaps=True, accelerators=None) -> Circuit: """Creates a circuit that implements the Quantum Fourier Transform. Args: nqubits (int): Number of qubits in the circuit. with_swaps (bool): Use SWAP gates at the end of the circuit so that the qubit order in the final state is the same as the initial state. accelerators (dict): Accelerator device dictionary in order to use a distributed circuit If ``None`` a simple (non-distributed) circuit will be used. Returns: A qibo.models.Circuit that implements the Quantum Fourier Transform. Example: .. testcode:: import numpy as np from qibo.models import QFT nqubits = 6 c = QFT(nqubits) # Random normalized initial state vector init_state = np.random.random(2 ** nqubits) + 1j * np.random.random(2 ** nqubits) init_state = init_state / np.sqrt((np.abs(init_state)**2).sum()) # Execute the circuit final_state = c(init_state) """ if accelerators is not None: if not with_swaps: raise_error( NotImplementedError, "Distributed QFT is only implemented " "with SWAPs.", ) return _DistributedQFT(nqubits, accelerators) circuit = Circuit(nqubits) for i1 in range(nqubits): circuit.add(gates.H(i1)) for i2 in range(i1 + 1, nqubits): theta = math.pi / 2 ** (i2 - i1) circuit.add(gates.CU1(i2, i1, theta)) if with_swaps: for i in range(nqubits // 2): circuit.add(gates.SWAP(i, nqubits - i - 1)) return circuit
def _DistributedQFT(nqubits, accelerators=None): """QFT with the order of gates optimized for reduced multi-device communication.""" circuit = Circuit(nqubits, accelerators) icrit = nqubits // 2 + nqubits % 2 if accelerators is not None: circuit.global_qubits = range(circuit.nlocal, nqubits) # pylint: disable=E1101 if icrit < circuit.nglobal: # pylint: disable=E1101 raise_error( NotImplementedError, f"Cannot implement QFT for {nqubits} qubits " + f"using {circuit.nglobal} global qubits.", ) # pylint: disable=E1101 for i1 in range(nqubits): if i1 < icrit: i1eff = i1 else: i1eff = nqubits - i1 - 1 circuit.add(gates.SWAP(i1, i1eff)) circuit.add(gates.H(i1eff)) for i2 in range(i1 + 1, nqubits): theta = math.pi / 2 ** (i2 - i1) circuit.add(gates.CU1(i2, i1eff, theta)) return circuit