The Quipper System

QuipperLib.FPReal

Description

This library provides a quantum implementation of fixed-precision real numbers (i.e., with precision determined at circuit-generation time), and classical counterpart types.

Currently still significantly experimental. TODO:

• decide on how much access to provide to underlying representation of FPReal. Full fpreal_case, or more like just what’s available through Haskell’s RealFloat?
• decide how to use ErrMsg: in internal functions only, or exported ones too?
• many specific TODO’s in code throughout this file.
• write export list.

Synopsis

Fixed-precision real arithmetic: the FPReal family

data FPRealX x Source #

FPRealX: a family of datatypes for fixed-precision real numbers. (That is, the precision is a parameter, fixed at circuit-generation time.)

FPRealX is based on the family XInt of fixed-length integer types: FPRealX n a represents 2n a, where a is some fixed-length integer.

Alternately, in the specific case x = Bool, a Haskell Double may be used as an FPReal, considered as having indeterminate length and exponent. This is exactly analogous to the case of indeterminate length in XInt / IntM; for a more detailed explanation, see the documentation there.

Constructors

 FPRealX Int (XInt x) FPReal_indet Double (Identity IntM (XInt x))

Instances

 # MethodstoEnum :: Int -> FPReal #enumFrom :: FPReal -> [FPReal] #enumFromThen :: FPReal -> FPReal -> [FPReal] #enumFromTo :: FPReal -> FPReal -> [FPReal] #enumFromThenTo :: FPReal -> FPReal -> FPReal -> [FPReal] # # Methodsexp :: FPReal -> FPReal #log :: FPReal -> FPReal #(**) :: FPReal -> FPReal -> FPReal #sin :: FPReal -> FPReal #cos :: FPReal -> FPReal #tan :: FPReal -> FPReal # # Methods(/) :: FPReal -> FPReal -> FPReal # # Methods(+) :: FPReal -> FPReal -> FPReal #(-) :: FPReal -> FPReal -> FPReal #(*) :: FPReal -> FPReal -> FPReal #abs :: FPReal -> FPReal # # Methods(<) :: FPReal -> FPReal -> Bool #(<=) :: FPReal -> FPReal -> Bool #(>) :: FPReal -> FPReal -> Bool #(>=) :: FPReal -> FPReal -> Bool #max :: FPReal -> FPReal -> FPReal #min :: FPReal -> FPReal -> FPReal # # Methods # MethodsproperFraction :: Integral b => FPReal -> (b, FPReal) #truncate :: Integral b => FPReal -> b #round :: Integral b => FPReal -> b #ceiling :: Integral b => FPReal -> b #floor :: Integral b => FPReal -> b # # MethodsshowList :: [FPRealQ] -> ShowS # # MethodsshowsPrec :: Int -> FPReal -> ShowS #showList :: [FPReal] -> ShowS # # Methods # Methods Eq x => Eq (FPRealX x) # Methods(==) :: FPRealX x -> FPRealX x -> Bool #(/=) :: FPRealX x -> FPRealX x -> Bool # Show x => Show (FPRealX x) # MethodsshowsPrec :: Int -> FPRealX x -> ShowS #show :: FPRealX x -> String #showList :: [FPRealX x] -> ShowS # QCLeaf x => QCData (FPRealX x) # Methodsqcdata_mapM :: Monad m => FPRealX x -> (q -> m q') -> (c -> m c') -> QCType q c (FPRealX x) -> m (QCType q' c' (FPRealX x)) Source #qcdata_zip :: FPRealX x -> q -> c -> q' -> c' -> QCType q c (FPRealX x) -> QCType q' c' (FPRealX x) -> ErrMsg -> QCType (q, q') (c, c') (FPRealX x) Source #qcdata_promote :: BType (FPRealX x) -> FPRealX x -> ErrMsg -> BType (FPRealX x) Source # QCLeaf x => Labelable (FPRealX x) String # Methodslabel_rec :: FPRealX x -> String -> LabelMonad () Source # type QTypeB FPReal # type QTypeB FPReal = FPRealQ type QCType x y (FPRealX z) # type QCType x y (FPRealX z) = FPRealX (QCType x y z)

Fixed-precision real parameters. As with IntM, the length and/or exponent of an FPReal may be indeterminate; such an FPReal may only be used in certain contexts, typically either when the length/exponent can be inferred from context (e.g., terminating a FPRealQ), or where the result can again be indeterminate.

As with indeterminate IntMs, indeterminate FPReals may be used for efficient, high-precision classical calculation, and then explicitly or implicitly coerced to determinate FPReals when required for interfacing with quantum computation.

Fixed-precision reals for quantum circuits.

Fixed-precision reals for classical circuits.

Primitive combinators on FPReal

Like XInt, the type FPReal is intended to be an abstract data type, and all access to it should pass through the functions of this section.

Constructors

fprealx :: Int -> XInt x -> FPRealX x Source #

Create an FPRealX from an XInt together with an exponent.

Create an indeterminate FPReal from a Double.

Destructor

fprealx_case :: FPRealX x -> Either (Int, XInt x) (Double, Identity IntM (XInt x)) Source #

If the FPRealX is of determinate exponent, return its exponent and mantissa.

If the FPRealX is indeterminate, return a pair (r, id), where r is the underlying Double, and id is a witness of the fact that x = Bool.

This is a lowest-level access function not intended to be used by user-level code, and is not exported.

Other low-level operations

The operations in this section are the only ones intended to use fprealx_case directly.

Extract the exponent of an FPRealX, assumed to be determinate.

When x is not Bool, this and fprealx_num should be considered the destructors of 'FPRealX x'.

Extract the mantissa of an FPRealX, assumed to be of determinate exponent.

When x is not Bool, this and fprealx_num should be considered the destructors of 'FPRealX x'.

Extract the length (in bits) of an FPRealX, assumed to be of determinate exponent and length.

Set the exponent of an FPReal to n. This operation is only legal if the input (a) has indeterminate exponent or (b) has determinate exponent already equal to m. In particular, it cannot be used to change the exponent from anything other than from indeterminate to determinate.

If both arguments already have determinate exponents, and they do not coincide, throw an error. The String argument is used as an error message in that case.

Return the (possibly indeterminate) exponent of an FPRealX.

Given an FPReal, return either the exponent and numerator, or else the double it wraps.

A specialized and implementation-hiding wrapper for fprealx_case.

fprealx_equals :: Eq x => FPRealX x -> FPRealX x -> Bool Source #

Equality test. If both have indeterminate exponent, check equality of underlying Doubles. Otherwise, if exponents are compatible (i.e. both determinate and equal, or one indeterminate), check equality of numerators. If exponents are incompatible, throw an error (the test should in this case be considered ill-typed).

Shape parameters

Return a piece of shape data to represent an l-qubit quantum real with exponent n. Please note that the data can only be used as shape; it will be undefined at the leaves.

Return a piece of shape data to represent an l-bit FPRealC, with exponent n. Please note that the data can only be used as shape; it will be undefined at the leaves.

Circuit type class instances

Try to set the exponent/length of an FPReal to that of another FPRealX value (e.g. an FPRealQ, an FPRealC, or another FPReal). This will fail with an error if both numbers already have determinate lengths that don't coincide. In this case, the string argument is used as an error message.

The possible “shapes” of FPReals may be seen as a partial order, where s1s2 means that values of shape s1 are coercible to values of shape s2. fpreal_promote may be seen as taking the binary sup in this poset.

Classical arithmetic on FPReal

Convert an FPReal to a Double.

From a list of FPReals, extract a common shape, provided they have compatible shape (i.e. if any have determinate exponent, they must agree; similarly for length), and throw an error otherwise.

Can be seen as producing finitary suprema in the partial order of shapes.

The FPReal produced should be considered just a shape; its value is a dummy that should never be used (and will throw an error if it is).

fpreal_binop :: (Double -> Double -> Double) -> String -> FPReal -> FPReal -> FPReal Source #

Auxiliary function for lifting a binary operator from Double to IntM. The string argument is the name of the operator, for error messages.

fpreal_unop :: (Double -> Double) -> FPReal -> FPReal Source #

Auxiliary function for lifting a unary operator from Double to FPReal.

Shape/precision control

Extend the length of a determinate length and precision FPReal by m high and n low bits, without changing its value.

Discard the top m and bottom n bits of a determinate length and precision FPReal.

Fix the length of an IntM (to automatically-generated values), if not already determinate.

TODO: belongs in Arith

Fix the precision and length of an FPReal (to automatically-generated values), leaving unchanged any parts of the shape that are already set.

TODO: discuss / reconsider / improve implementation of this.

Quantum operations: FPRealQ

Shape/precision control

Extend the length of an FPRealQ by m high bits and n low bits, without changing its value.

fprealq_unpad :: Int -> Int -> FPRealQ -> Circ (FPRealQ, [Qubit]) Source #

Cut off the top m and bottom n bits of an FPRealQ, retaining them as explicit garbage.

Formally shift an FPRealQ up n bits, i.e. add n to its exponent.

Quantum arithmetic

Besides the functions appearing here in the documentation, basic operations (q_add, etc) are also provided as methods of the QNum type class instance; see QNum for documentation of these functions.

Analogue of q_add_in_place, for FPRealQ.

Analogue of q_sub_in_place, for FPRealQ.

Subtract a parameter FPReal from an FPRealQ, in place. Assume compatible precision.

Note: highly sub-optimal. TODO: optimize!

Add a parameter FPReal to an FPRealQ, in place. Assume compatible precision.

Note: highly sub-optimal. TODO: optimize!

Multiply an FPRealQ by a parameter FPReal. The parameter may have any shape.

Compare an FPRealQ to a parameter FPReal. Assume compatible precision.

Note: highly sub-optimal. TODO: optimize!

q_add_fpreal_het p l qx qy: add two FPRealQs, of potentially different precisions and lengths, into a fresh one with precision p and length l.

TODO: not yet implemented; currently just black box.

fprealq_logBase_internal :: (Floating a, RealFrac a) => ErrMsg -> a -> Int -> Int -> FPRealQ -> Circ (FPRealQ, FPRealQ) Source #

fprealq_logBase_internal errmsg b h p qx': compute logb(qx), returning l binary digits before the point and p after. The underlying implementation of the rest of the fprealq_log family.

Behavior on non-positive qx: currently unspecified. TODO: decide and fix this. Make assertion/post-selection on positivity? Or treat as unsigned?

Time-complexity (estimated): O((log lqx + log log b)(lqx + (h+p)2)).

Compute the natural log of an FPRealQ, with length and precision as in the input.

Note: the behavior on negative inputs is unspecified.

fprealq_logBase :: (Floating a, RealFrac a) => a -> FPRealQ -> Circ (FPRealQ, FPRealQ) Source #

Compute the log (to arbitrary base) of an FPRealQ, with length and precision as in the input.

Note: the behavior on negative inputs is unspecified.

fprealq_log_with_shape x y: compute the natural log y, with length and precision of x.

Note: the behavior on negative inputs is unspecified.

fprealq_logBase_with_shape :: (Floating a, RealFrac a) => a -> FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ) Source #

fprealq_log_with_shape b x y: compute logb y, with length and precision of x.

Note: the behavior on negative inputs is unspecified.