-- | This module provides an implementation of the addition circuit found in -- Thomas G. Draper's paper \"Addition on a Quantum Computer\". module Quipper.Libraries.QFTAdd ( qft_add_in_place ) where import Quipper import Quipper.Libraries.Arith -- we make use of the QDInt data type for quantum integers import Quipper.Libraries.QFT -- we make use of the big endian QFT -- | Add one 'QDInt' onto a second, in place; i.e. (/x/,/y/) ↦ (/x/,/x/+/y/). -- Arguments are assumed to be of equal size. -- This implementation follows the implementation in Thomas G. Draper's -- paper \"Addition on a Quantum Computer\" which doesn't require the use of any -- ancilla qubits through a clever use of the Quantum Fourier Transform. qft_add_in_place :: QDInt -> QDInt -> Circ (QDInt,QDInt) qft_add_in_place x y = do let x' = list_of_xint_bh x let y' = list_of_xint_bh y (x', y') <- qft_add_in_place_qulist x' y' let x = xint_of_list_bh x' let y = xint_of_list_bh y' return (x, y) -- | Low-level implementation of 'qft_add_in_place': represents integers -- as big-headian qubit lists. qft_add_in_place_qulist :: [Qubit] -> [Qubit] -> Circ ([Qubit], [Qubit]) qft_add_in_place_qulist a b = do label (a,b) ("a","b") with_computed (box "QFT" qft_big_endian b) $ \b' -> do qft_adder a (reverse b') label (a,b) ("a","b") return (a,b) -- | The circuit that performs the addition after a QFT qft_adder :: [Qubit] -> [Qubit] -> Circ () qft_adder _ [] = return () qft_adder as (b:bs) = do qft_adder' as b 1 qft_adder (tail as) bs where qft_adder' :: [Qubit] -> Qubit -> Int -> Circ [Qubit] qft_adder' [] _ _ = return [] qft_adder' (a:as) b n = do b <- rGate n b `controlled` a qft_adder' as b (n+1)