FlexFloat.jl

These floating point values stretch to maintain accuracy.
Popularity
3 Stars
Updated Last
2 Years Ago
Started In
December 2015

FlexFloat.jl

These are values that stretch preserve accuracy.

The underlying representation is an interval with bounds that may be closed (exact) or open (inexact). An exact bound takes the floating point value given at that boundry to be a precisely accurate quantity. Two examples of exact quantities are counts and monetary balances. An inexact bound takes the floating point value given at the lower [higher] boundry to be largest [smallest] possible quantity to be included in the bounding value's span. An inexact bound bound extendes away from the center of the interval, almost reaching the next lower [higher] floating point value. Inexact bounds cover a real span that is not fully representable with machine floats -- and from that fact tend to follow results with relatively tight bounds.

The package internals handle all of that without additional guidance. There are four kinds of intervals:

  (a) both bounds are exact (closed): clcl(1,2)
  (b) both bounds are inexact (open): oppp(1,2)
  (c) only the lower bound is exact : clop(1,2)
  (d) only the upper bound is exact : opcl(1,2)

An exact value of 1 is entered as Exact(1). Exact is a synonym for clcl.
An interval with exact bounds of zero and one is entered as Exact(0,1).
An inexact value of 3 is entered as Inexact(3). Inexact is a synonym for opop.
     this indicates any value within the Real range that extends from prevfloat(3) to nextfloat(3) without including either.
The inexact interval Inexact(1,2) indicates any value within the Real range from prevfloat(1) to nextfloat(2), exclusively.

Any values may exist in one of two states

states 'exact', 'inexact' are exported; 'situated', 'enhanced' are the internal names.

This capability exists transparently -- apps that do not need it do not see it.

Each Flex may be [re]assigned either of two states and the statefulness persists unless reassigned. There is no limit on state changes, nor any requirement that states change. The state is independant of the kind of interval (ClCl, OpOp, ClOp, OpCl); one may create some logical dependance in code. To simplify use,

        clcl(), opop(), clop(), opcl() create values in the 'inexact' stat
        ClCl(), OpOp(), ClOp(), OpCl() create values in the 'exact' state
        (lowercase is used with situated values, titlecase with enhanced values)

   Assignment, determination and utilization of statefulness is entirely given to your application.
   
              op(a,b) where isexact(a)&isinexact(b) and a,b are not of the same sculpture
              is not predefinded, nor are associated conversions .. **encode your intent**.

The file 'src/type/cvtqualia.jl' has the comparison and conversion defaults for statefulness.

###Quick Guide

#=
   a closed boundry (an exact bound)  is shown with single angle brackets
   an open boundry (an inexact bound) is shown with double angle brackets

   when the lower bound and the upper bound are equal one number is shown
   when the lower bound and the upper bound are equal, one may use it alone
   
   values in the 'exact' state are tied with '⌁', '~' ties 'inexact' values
=#

julia> opop(1.2345,1.2346), ClCl(1), clcl(1,1), OpOp(1.2,1.2)
(⟪1.2345⌁1.2346⟫,⟨1.0⌁⟩,⟨1.0~⟩,⟪1.2~⟫)

# different sorts of values may be intermixed for arithmetic
julia> a=clcl(2.0); b=opcl(1.5, 2.0); a-b, a*b, a/b
(⟪0.0⌁0.5⟩,⟪3.0⌁4.0⟩,⟪1.0⌁1.3333333333333335⟩)

# Flex64 is a typealias, it works like clcl()
julia> Flex64(1.0)
⟨1.0⌁2.0⟩
julia> Flex64(1.0,2.0)
⟨1.0⌁2.0

###And More

# elementary functions of FlexFloat values
julia> using FlexFloat

julia> exp(OpOp(1.0))
⟨2.7182818284590446~2.7182818284590455# diameter: 8.88e-16

# optionally using CRlibm for more accuracy
julia> using CRlibm      # must preceed using FlexFloat
julia> using FlexFloat

julia> exp(OpOp(1.0))
⟨2.718281828459045~2.7182818284590455# diameter: 4.44e-16

# polynomial evaluation at FlexFloat values
julia> using Polynomials
julia> using FlexFloat

julia> p = Poly([4.0,8,1,-5,-1,1]);
julia> polyval(p,OpOp(2.5,2.5+eps(2.5)))
⟪10.718749999999991~10.718750000000039# cdf, pdf, quantile at FlexFloat values
# for continuous univariate distributions
julia> using Distributions  # must preceed using FlexFloat
julia> using FlexFloat

julia> ND=normal();
julia> pdf(ND, ClCl(0.999,0.9995))
⟨0.24209170987131956~0.24221269516298546⟩
julia> pdf(ND, OpOp(0.999,0.9995))
⟨0.24209170987131953~0.24221269516298546
supports
         (==), (!=), (<), (<=), (>=), (>),
         (+), (-), (*), (/),
         sqrt, exp, log,
         sin, cos, tan, csc, sec, cot,
         asin, acos, atan, acsc, asec, acot,
         sinh, cosh, tanh, csch, sech, coth,
         asinh, acosh, atanh, acsch, asech, acoth,
         erf, erfinv

         when the Distributions package is pre-loaded:
            cdf, pdf, quantile for univariate continuous distributions
References

(please see doc/References.md for all referenced material and links)

John L. Gustafson, The End of Error: Unum Computing
Ulrich Kulisch, Up-to-date Interval Arithmetic