Safe Haskell | None |
---|
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
. Fullfpreal_case
, or more like just what’s available through Haskell’sRealFloat
? - 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
- data FPRealX x
- type FPReal = FPRealX Bool
- type FPRealQ = FPRealX Qubit
- type FPRealC = FPRealX Bit
- fprealx :: Int -> XInt x -> FPRealX x
- fpreal_of_double :: Double -> FPReal
- fprealx_case :: FPRealX x -> Either (Int, XInt x) (Double, Identity IntM (XInt x))
- fprealx_expt :: FPRealX x -> Int
- fprealx_num :: FPRealX x -> XInt x
- fprealx_length :: FPRealX x -> Int
- fprealx_set_expt :: Int -> FPRealX x -> String -> FPRealX x
- fprealx_maybe_expt :: FPRealX x -> Maybe Int
- fpreal_case :: FPReal -> Either (Int, IntM) Double
- fprealx_equals :: Eq x => FPRealX x -> FPRealX x -> Bool
- fprealq_shape :: Int -> Int -> FPRealQ
- fprealc_shape :: Int -> Int -> FPRealC
- fpreal_promote :: FPReal -> FPRealX x -> ErrMsg -> FPReal
- double_of_fpreal :: FPReal -> Double
- fpreal_common_shape :: [FPReal] -> ErrMsg -> FPReal
- fpreal_binop :: (Double -> Double -> Double) -> String -> FPReal -> FPReal -> FPReal
- fpreal_unop :: (Double -> Double) -> FPReal -> FPReal
- fpreal_pad :: Int -> Int -> FPReal -> FPReal
- fpreal_unpad :: Int -> Int -> FPReal -> FPReal
- intm_fix_length_auto :: IntM -> IntM
- fpreal_fix_shape_auto :: FPReal -> FPReal
- fprealq_pad :: Int -> Int -> FPRealQ -> Circ FPRealQ
- fprealq_unpad :: Int -> Int -> FPRealQ -> Circ (FPRealQ, [Qubit])
- fprealq_shift :: Int -> FPRealQ -> FPRealQ
- fprealq_add_in_place :: FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ)
- fprealq_sub_in_place :: FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ)
- fprealq_sub_param_in_place :: FPReal -> FPRealQ -> Circ FPRealQ
- fprealq_add_param_in_place :: FPReal -> FPRealQ -> Circ FPRealQ
- fprealq_mult_param_het :: FPReal -> FPRealQ -> Circ (FPRealQ, FPRealQ)
- fprealq_ge_param :: FPReal -> FPRealQ -> Circ (FPRealQ, Qubit)
- fprealq_add_het :: Int -> Int -> FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ, FPRealQ)
- fprealq_logBase_internal :: (Floating a, RealFrac a) => ErrMsg -> a -> Int -> Int -> FPRealQ -> Circ (FPRealQ, FPRealQ)
- fprealq_log :: FPRealQ -> Circ (FPRealQ, FPRealQ)
- fprealq_logBase :: (Floating a, RealFrac a) => a -> FPRealQ -> Circ (FPRealQ, FPRealQ)
- fprealq_log_with_shape :: FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ)
- fprealq_logBase_with_shape :: (Floating a, RealFrac a) => a -> FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ)
Fixed-precision real arithmetic: the FPReal family
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:
represents 2n a, where a is some fixed-length integer.FPRealX
n a
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.
Instances
type FPReal = FPRealX Bool Source #
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 IntM
s, indeterminate FPReal
s may be used for efficient,
high-precision classical calculation, and then explicitly or implicitly coerced
to determinate FPReal
s when required for interfacing with quantum computation.
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
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 -> Int Source #
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 x Source #
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 -> Int Source #
Extract the length (in bits) of an FPRealX
, assumed to be of determinate exponent and length.
fprealx_set_expt :: Int -> FPRealX x -> String -> FPRealX x Source #
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 Int Source #
Return the (possibly indeterminate) exponent of an FPRealX
.
fpreal_case :: FPReal -> Either (Int, IntM) Double Source #
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 Double
s.
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 -> FPRealQ Source #
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 -> FPRealC Source #
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 -> FPReal Source #
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 FPReal
s may be seen as a partial order, where
s1 ≤ s2 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 -> FPReal Source #
From a list of FPReal
s, 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).
Shape/precision control
fpreal_pad :: Int -> Int -> FPReal -> FPReal Source #
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 -> FPReal Source #
Discard the top m and bottom n bits of a determinate length and precision FPReal
.
intm_fix_length_auto :: IntM -> IntM Source #
fpreal_fix_shape_auto :: FPReal -> FPReal Source #
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 FPRealQ Source #
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 -> FPRealQ Source #
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_add_in_place :: FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ) Source #
Analogue of q_add_in_place
, for FPRealQ
.
fprealq_sub_in_place :: FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ) Source #
Analogue of q_sub_in_place
, for FPRealQ
.
fprealq_add_het :: Int -> Int -> FPRealQ -> FPRealQ -> Circ (FPRealQ, FPRealQ, FPRealQ) Source #
fprealq_add_het
p l qx qy: add two FPRealQ
s, 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 #
: compute logb(qx), returning l binary digits before the point and p after. The underlying implementation of the rest of the fprealq_logBase_internal
errmsg b h p qx'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 #
: compute the natural log y, with length and precision of x.fprealq_log_with_shape
x y
Note: the behavior on negative inputs is unspecified.