The Quipper System

Safe HaskellNone

QuipperLib.FPReal

Contents

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)) 

type FPReal = FPRealX BoolSource

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.

type FPRealQ = FPRealX QubitSource

Fixed-precision reals for quantum circuits.

type FPRealC = FPRealX BitSource

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 xSource

Create an FPRealX from an XInt together with an exponent.

fpreal_of_double :: Double -> FPRealSource

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.

fprealx_expt :: FPRealX x -> IntSource

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'.

fprealx_num :: FPRealX x -> XInt xSource

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'.

fprealx_length :: FPRealX x -> IntSource

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

fprealx_set_expt :: Int -> FPRealX x -> String -> FPRealX xSource

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.

fprealx_maybe_expt :: FPRealX x -> Maybe IntSource

Return the (possibly indeterminate) exponent of an FPRealX.

fpreal_case :: FPReal -> Either (Int, IntM) DoubleSource

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 -> BoolSource

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

fprealq_shape :: Int -> Int -> FPRealQSource

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.

fprealc_shape :: Int -> Int -> FPRealCSource

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

fpreal_promote :: FPReal -> FPRealX x -> ErrMsg -> FPRealSource

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

fpreal_common_shape :: [FPReal] -> ErrMsg -> FPRealSource

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 -> FPRealSource

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 -> FPRealSource

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

Shape/precision control

fpreal_pad :: Int -> Int -> FPReal -> FPRealSource

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

fpreal_unpad :: Int -> Int -> FPReal -> FPRealSource

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

intm_fix_length_auto :: IntM -> IntMSource

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

TODO: belongs in Arith

fpreal_fix_shape_auto :: FPReal -> FPRealSource

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

fprealq_pad :: Int -> Int -> FPRealQ -> Circ FPRealQSource

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.

fprealq_shift :: Int -> FPRealQ -> FPRealQSource

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.

fprealq_sub_param_in_place :: FPReal -> FPRealQ -> Circ FPRealQSource

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

Note: highly sub-optimal. TODO: optimize!

fprealq_add_param_in_place :: FPReal -> FPRealQ -> Circ FPRealQSource

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

Note: highly sub-optimal. TODO: optimize!

fprealq_mult_param_het :: FPReal -> FPRealQ -> Circ (FPRealQ, FPRealQ)Source

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

fprealq_ge_param :: FPReal -> FPRealQ -> Circ (FPRealQ, Qubit)Source

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

Note: highly sub-optimal. TODO: optimize!

fprealq_add_het :: Int -> Int -> FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ, FPRealQ)Source

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)).

fprealq_log :: FPRealQ -> Circ (FPRealQ, FPRealQ)Source

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 :: FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ)Source

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.