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 a Source #

A State monad that holds a random generator.

type ListCirc a = StateT [Bool] Circ a Source #

A State monad that holds a list of booleans.

evalRandomCirc :: Int -> RandomCirc a -> Circ a Source #

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

evalListCirc :: [Bool] -> ListCirc a -> Circ a Source #

To evaluate a ListCirc we require a list of booleans.

evalRandomCirc_unary :: Int -> (a -> RandomCirc b) -> a -> Circ b Source #

Lift evalRandomCirc to unary random circuit generating functions.

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

Left evalListCirc to unary list circuit generating functions.

randomRRandomCirc :: Random a => (a, a) -> RandomCirc a Source #

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 Bit Source #

Lift the identity_transformer using any monad transformer.

random_dynamic_lift :: Bit -> RandomCirc Bool Source #

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

list_dynamic_lift :: Bit -> ListCirc Bool Source #

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 Bit Source #

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 Bit Source #

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 -> SimulationState Source #

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

type SimulatedCirc a = StateT SimulationState Circ a Source #

A State monad that holds our SimulationState.

evalSimulatedCirc :: Int -> SimulatedCirc a -> Circ a Source #

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

evalSimulatedCirc_unary :: Int -> (a -> SimulatedCirc b) -> a -> Circ b Source #

Lift evalSimulatedCirc to unary functions.

randomRSimulatedCirc :: Random a => (a, a) -> SimulatedCirc a Source #

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) -> Bool Source #

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 -> Bool Source #

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) -> Bool Source #

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 -> Bool Source #

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 Double Source #

Apply the given function only if the controls fire.

simulated_lift_transformer :: Transformer (StateT SimulationState Circ) Qubit Bit Source #

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

simulated_dynamic_lift :: Bit -> SimulatedCirc Bool Source #

Dynamic lifting can make use of a simulated result.

simulated_dynamic_lift_transformer :: DynamicTransformer (StateT SimulationState Circ) Qubit Bit Source #

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 b Source #

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.