• No se han encontrado resultados

CAPÍTULO 2: ANÁLISIS Y PRESENTACIÓN DE RESULTADOS

2.9 IMPLEMENTACIÓN DE LOS CONTROLADORES PID Y LQR EN

To hold our quantum states we define a class of vectors. As we mentioned, we have designed these vectors such that all the primitive operations available for them, keep the overall state of the vector normalised. This normalisation equates to combining equal base state terms by summing their complex amplitudes (an action that can lead to deconstructive interference, as is expected).

The vectors we define should be able to be an instance of the Monad type-class in Haskell, such that it is possible to define the semantics of our monadic QIO computations in terms of monadic operations acting on these vectors. We shall look at how this is achieved after introducing the VecEq class of vectors. The requirement that our underlying type in the vectors has definable equality causes a few problems with this monadic definition, but we will see how we can make use of a trick suggested in [Sit08] to achieve such a definition.

The VecEq class is given by classVecEq v where

vzero :: v x a (⊕) :: (Eq a, Num x ) ⇒ v x a → v x a → v x a (⊗) :: (Num x ) ⇒ x → v x a → v x a (@) :: (Eq a, Num x )⇒ a → v x a → x fromList :: [(a, x )]→ v x a toList :: v x a → [(a, x )]

and we can now go over each of these class functions to describe the actions they must define. As an aside, these vectors can have any numeric type x to represent the amplitudes, and be over any type a with definable equality. To define quantum computation we use them with the complex numbers, and over heaps, and as such often use the terminology associated with this specific case.

The vzero element is just an empty vector, which is used in a similar way to the initial element of the Heap class, that is to describe the state of an empty quantum system before any qubits have been initialised.

The (⊕) operation is used to combine two vectors, and it is specifically this operation that keeps the vectors normalised. In combining two vectors, we require that the underlying type the vector holds has a definable equality, that is, that it is a member of the type-class Eq. When combining two vectors, this operation will simply sum the amplitudes of any underlying base states that are present in both input vectors.

The (⊗) operation is a form of scalar multiplication for vectors, and is used to multiply all the complex amplitudes in a vector by the given scalar.

The (@) function is a kind of look-up function, that corresponds to finding the current amplitude of a given base state within the overall state represented by the vector.

The fromList and toList functions are simply helper functions that are used in defining the VecEq class as a monadic structure. In fact, the implementation we have used for an instance of the VecEq class is simply a data-type that repre- sents a vector as a list of pairs, and these operations are simple to define (as the constructor and deconstructor elements of that data-type).

dataVecEqL x a = VecEqL{unVecEqL :: [(a, x )]} deriving Show The vzero element of such a list based vector is just the empty list.

vEqZero :: VecEqL x a vEqZero = VecEqL [ ]

The (⊕) function (given by vEqPlus) can be given using a fold operation that steps through the elements in the second argument vector, and uses the add func- tion to check if the current element is already a member of the first vector. If this is the case, then the corresponding amplitudes are added, but if this isn’t the case then the element is concatenated onto the end of the first vector.

vEqPlus :: (Eq a, Num x )

VecEqL x a → VecEqL x a → VecEqL x a (VecEqL as) ‘vEqPlus‘ vbs = foldr add vbs as

add (a, x ) (VecEqL axs) = VecEqL (addV′ axs)

where addV′ [ ] = [(a, x )]

addV′ ((by@(b, y)) : bys)| a ≡ b = (b, x + y) : bys

| otherwise = by : (addV′ bys)

The (⊗) function (given by vEqTimes) simply maps the multiplication operation by the given scalar to each complex amplitude in the vector, and the (@) function (given by vEqAt) steps through the vector until the matching base state is found. If the base state is not found in the vector then then an amplitude of zero is returned.

vEqTimes :: (Num x )⇒ x → VecEqL x a → VecEqL x a l ‘vEqTimes‘ (VecEqL bs)| l ≡ 0 = VecEqL [ ]

| otherwise

= VecEqL (map (λ(b, k )→ (b, l ∗ k)) bs) vEqAt :: (Eq a, Num x )⇒ a → VecEqL x a → x

a ‘vEqAt‘ (VecEqL [ ]) = 0

a ‘vEqAt‘ (VecEqL ((a′, b) : abs))| a ≡ a= b

| otherwise

= a ‘vEqAt‘ (VecEqL abs)

These definitions can now be used to give VecEqL as an instance of the VecEq class.

instanceVecEq VecEqL where

vzero = vEqZero (⊕) = vEqPlus (⊗) = vEqTimes (@) = vEqAt

fromList as = VecEqL as toList (VecEqL as) = as

The requirement that the underlying type is a member of Eq leads to a problem that we can not define VecEq as a monad, which we require so we can sequence the

monadic QIO operations over it. We follow the technique suggested in ([Sit08]), but for restricting the monad by means of an instance of Eq instead of Ord . We can define an EqMonad class, whose members correspond to the restricted monad operations we wish to define.

classEqMonad m where

eqReturn :: Eq a ⇒ a → m a

eqBind :: (Eq a, Eq b) ⇒ m a → (a → m b) → m b

We can’t just use this definition in place of a monad as it would prevent us from being able to use do notation. We can however define VecEq as a member of this class, with the functions corresponding to the monadic behaviour we require.

instance(VecEq v , Num x )⇒ EqMonad (v x ) where eqReturn a = fromList [(a, 1)]

eqBind va f = case toList va of ([ ])→ vzero

((a, x ) : [ ])→ x ⊗ f a

((a, x ) : vas)→ (x ⊗ f a) ⊕ ((fromList vas) ‘eqBind‘ f )

In order to define EqMonad as a form of monad in Haskell, we need to embed it in a monadic structure that can be defined by the AsMonad data-type.

dataAsMonad m a where

Embed :: (EqMonad m, Eq a) ⇒ m a → AsMonad m a

Return :: EqMonad m ⇒ a → AsMonad m a

Bind :: EqMonad m ⇒

AsMonad m a → (a → AsMonad m b) → AsMonad m b

instanceEqMonad m ⇒ Monad (AsMonad m) where

return = Return (>>=) = Bind

The overall AsMonad structure is indeed an instance of the Monad class in Haskell, and as such can be used with the do notation as we required. However, to be actually able to use our embedded instance of the EqMonad we need a function

unEmbed , which as the name suggests unembeds the EqMonad structure.

unEmbed :: Eq a ⇒ AsMonad m a → m a

unEmbed (Embed m) = m

unEmbed (Return a) = eqReturn a

unEmbed (Bind (Embed m) f ) = m ‘eqBind ‘ (unEmbed ◦ f ) unEmbed (Bind (Return a) f ) = unEmbed (f a)

unEmbed (Bind (Bind m f ) g) = unEmbed

(Bind m (λx → Bind (f x ) g))

This gives us a fully monadic implementation of the VecEq type of vectors, and as such we can now go on to look at how the primitive QIO operations can be translated into the primitive operations of the VecEq type.