The Quipper System

Safe HaskellNone

QuipperLib.DynamicLiftings

Contents

Description

This library provides various transformers and functions for performing dynamic liftings based on different mechanisms. Some use simulations to do the dynamic liftings; others just do them randomly. There are also functions for printing the simulated circuit.

This code is experimental.

Synopsis

Random Dynamic Liftings and Liftings from a List

type RandomCirc a = StateT StdGen Circ aSource

A State monad that holds a random generator.

type ListCirc a = StateT [Bool] Circ aSource

A State monad that holds a list of booleans.

evalRandomCirc :: Int -> RandomCirc a -> Circ aSource

To evaluate a RandomCirc we require a seed for the random generator.

evalListCirc :: [Bool] -> ListCirc a -> Circ aSource

To evaluate a ListCirc we require a list of booleans.

evalRandomCirc_unary :: Int -> (a -> RandomCirc b) -> a -> Circ bSource

Lift evalRandomCirc to unary random circuit generating functions.

evalListCirc_unary :: [Bool] -> (a -> ListCirc b) -> a -> Circ bSource

Left evalListCirc to unary list circuit generating functions.

randomRRandomCirc :: Random a => (a, a) -> RandomCirc aSource

Lift the underlying randomR function into the RandomCirc monad.

print_unary_random :: QCData qa => Format -> (qa -> RandomCirc b) -> qa -> IO ()Source

Print a RandomCirc by evaluating it with a seed in the IO monad.

print_unary_list :: QCData qa => Format -> Int -> (qa -> ListCirc b) -> qa -> IO ()Source

Print a LiftCirc by evaluating it in the IO Monad, so as to read in a given number of booleans.

lifted_identity_transformer :: MonadTrans t => Transformer (t Circ) Qubit BitSource

Lift the identity_transformer using any monad transformer.

random_dynamic_lift :: Bit -> RandomCirc BoolSource

Dynamic lifting can make use of a random result (without caring which wire is being lifted).

list_dynamic_lift :: Bit -> ListCirc BoolSource

Dynamic lifting can pop the head off of a list of booleans, and use that to lift the given wire.

random_dynamic_lift_transformer :: DynamicTransformer (StateT StdGen Circ) Qubit BitSource

A dynamic transformer which is the identity transformer (lifted to RandomCirc), except for the dynamic lifting operation.

list_dynamic_lift_transformer :: DynamicTransformer (StateT [Bool] Circ) Qubit BitSource

A dynamic transformer which is the identity transformer (lifted to ListCirc), except for the dynamic lifting operation.

print_unary_with_random_liftings :: (QCData a, QCData b) => Format -> (a -> Circ b) -> a -> IO ()Source

Print a circuit, using random dynamic liftings.

print_unary_with_list_liftings :: (QCData a, QCData b) => Format -> Int -> (a -> Circ b) -> a -> IO ()Source

Print a circuit, using a list of dynamic liftings.

Simulating the Dynamic Liftings

data SimulationState Source

Add state to the Circ Monad so that we can simulate the circuit and use that data for dynamic liftings.

empty_simulation_state :: Int -> SimulationStateSource

When we start a simulation, we need an empty starting state, with a seed for the generator.

type SimulatedCirc a = StateT SimulationState Circ aSource

A State monad that holds our SimulationState.

evalSimulatedCirc :: Int -> SimulatedCirc a -> Circ aSource

Evaluate a SimulatedCirc. This requires a seed for the random generator.

evalSimulatedCirc_unary :: Int -> (a -> SimulatedCirc b) -> a -> Circ bSource

Lift evalSimulatedCirc to unary functions.

randomRSimulatedCirc :: Random a => (a, a) -> SimulatedCirc aSource

Lift the underlying randomR function into the SimulatedCirc monad.

putQS :: Amplitudes Double -> SimulatedCirc ()Source

A specialized put function for the quantum state that uses the current state instead of a previously retrieved state.

putCS :: Map Bit Bool -> SimulatedCirc ()Source

A specialized put function for the classical state that uses the current state instead of a previously retrieved state.

s_classical_control :: Map Bit Bool -> Signed (B_Endpoint Qubit Bit) -> BoolSource

It doesn't make sense having a quantum control on a classical gate, so we can throw an error if that is the case, and just lookup the boolean result otherwise.

s_classical_controls :: Map Bit Bool -> Ctrls Qubit Bit -> BoolSource

Map the s_classical_control function to all the controls, and take the and of the result.

s_qc_control :: Map Bit Bool -> Map Qubit Bool -> Signed (B_Endpoint Qubit Bit) -> BoolSource

When we want a quantum control, we will be working with one basis state at a time, and can look up the qubit's value in that basis state to see whether the control fires.

s_qc_controls :: Map Bit Bool -> Map Qubit Bool -> Ctrls Qubit Bit -> BoolSource

Map the s_qc_control function to all the controls (under the given basis state), and take the and of the result.

s_if_controls :: Map Bit Bool -> Ctrls Qubit Bit -> (Map Qubit Bool -> Amplitudes Double) -> Map Qubit Bool -> Amplitudes DoubleSource

Apply the given function only if the controls fire.

simulated_lift_transformer :: Transformer (StateT SimulationState Circ) Qubit BitSource

The simulated_lift_transformer is the actual transformer that does the simulation, while recreating the circuit.

simulated_dynamic_lift :: Bit -> SimulatedCirc BoolSource

Dynamic lifting can make use of a simulated result.

simulated_dynamic_lift_transformer :: DynamicTransformer (StateT SimulationState Circ) Qubit BitSource

A dynamic transformer which simulates the circuit, whilst reconstructing it with simulated lifting results. Note: do not handle classical controlling.

print_simulated :: Format -> SimulatedCirc b -> IO ()Source

Print a RandomCirc by evaluating it with a seed in the IO monad.

print_unary_with_simulated_liftings :: (QCData a, QCData b) => Format -> (a -> Circ b) -> BType a -> IO ()Source

Print a circuit, using simulated liftings.

simulate_liftings_unary :: (QCData a, QCData b) => Int -> (a -> Circ b) -> BType a -> Circ bSource

Pass a (possibly) dynamic circuit through the simulated_dynamic_lift_transformer and evaluate the liftings so as to leave us with a static circuit that represents a single run of the original circuit, with the given inputs. We also need to pass in a seed for the RNG.