Monday, August 20, 2012

F#: Infinity and Infinitesimal-ness

These days many programming languages have the notion of infinity defined explicitly with their float type. F# (or .Net actually) is no exception. In contrast to infinity, Double.Epsilon is the smallest positive float in F#, i.e., anything between Double.Epsilon and 0.0 is viewed as 0.0 in F#. Let's use F# Interactive to do some simple empirical studies on both infinity and Double.Epsilon in F#.

First of all, F# has a built-in float value of infinity, which is equivalent to System.Double.PositiveInfinity in .Net.

> infinity;;
val it : float = infinity
> System.Double.PositiveInfinity;;
val it : float = infinity

Well, negative infinity is also there.

> -infinity;;
val it : float = -infinity
> System.Double.NegativeInfinity;;
val it : float = -infinity

Then let's see how small Double.Epsilon is:

 > System.Double.Epsilon;;
val it : float = 4.940656458e-324

Not sure how you feel about this, but it looks "scary" small to me. By the way, we also have Double.MaxValue and Double.MinValue.

> System.Double.MaxValue;;
val it : float = 1.797693135e+308
> infinity > System.Double.MaxValue;;
val it : bool = true
> System.Double.MinValue;;
val it : float = -1.797693135e+308
> System.Double.MinValue > -infinity;;
val it : bool = true

In financial mathematics, log(x) and exp(x) are used excessively, so let's take a look at how these 2 functions operate with infinity and Double.Epsilon.

> exp(infinity);;
val it : float = infinity
> log(infinity);;
val it : float = infinity

> log(0.0);;
val it : float = -infinity

We know that log(x) goes to negative infinity when x goes to 0.0. What if we evaluate log(x) at x = Double.Epsilon? Can F# properly handle this seemingly extreme case?

> log(System.Double.Epsilon);;
val it : float = -744.4400719
> exp(log(System.Double.Epsilon));;
val it : float = 4.940656458e-324
> exp(log(System.Double.Epsilon)) = System.Double.Epsilon;;
val it : bool = true

OK, log(Double.Epsilon) is only around -744.44, not too bad relative to the infinitesimal-ness of Double.Epsilon, and if you substitute this value into exp(x) you basically recover Double.Epsilon as shown above. If you run similar tests in Matlab, Matlab will return you pretty much the same results.

The above example actually implies a few things about the resolution of log(x) and exp(x) in F#:
  • Other than negative infinity, you won't see that log(x) could ever return any numerical value lower than -744.4400719, i.e., log(Double.Epsilon)
  • For any x smaller than -744.4400719, i.e., log(Double.Epsilon), exp(x) is evaluated as 0.0.
Besides exp(x) and log(x), you might also try how well F# handles sin(x) and cos(x) when x is extremely big or small. You might see something unexpected.

No comments:

Post a Comment