Sunday, October 4, 2009

Let there be chaos – sort of

Program code follows order. Syntax and semantics. But when run, they can be very unpredictable and unordered. Chaos out of order you might say. A clear picture of this are fractals (although they embody both order and chaos at the same time); a better example may be random numbers.

Actually, most of the time we deal with pseudo-random numbers, that is, numbers that operate on a seed value and calculate some other number based on this seed value. But then, if we know the seed value, we can compute the “random” number, so unless the seed value itself is random, we don’t have a truly random number.

More troublingly, how can we even determine that a number is random? Well, let’s not go there. Instead, let’s try to bring order to the chaos that is randomness in Random in the .Net Framework. In particular, rather than fetching one “random” number at a time, we should see randomness is a stream of numbers.

So the definition follows*

public static IE Random(this int seed, int min = 0, int max = int.MaxValue) { var r = new Random(seed); while (true) yield return r.Next(min, max); }

So this looks pretty good, now instead of calling r.Next explicitly, and thereby invoking a side-effect, we just get a sequence of pseudo-random or chaotic numbers based on a seed value.

This means we have pure randomness: functional randomness where chaos is a function of order, that is we get the same randomness for the same seed, every time; at least unless the implementation of Random breaks and suddenly gives us new randomness for the same seed value; something which would be highly… irregular.

Now we can create a random combinator which given an IEnumerable and a seed value, will predictably randomize this IEnumerable into a new IEnumerable.

public static IE Random(this IE s, int seed = 0) { var n = s.Count(); return from i in seed.Random(0, n).Distinct().Take(n) select s.ElementAt(i); }

Simple, predictable, composable.

Now looking back at the previous post “Information”, we might be inspired to decompose randomness into a stream of bits instead; I mean, why should we deal with pesky integers. Looks like a random choice of number system to me.

public static IE Random(this bool seed) { var r = new Random(seed ? 1 : 0); while (true) yield return r.Next(0,1) == 1; }

And so there you go. Pure, predictable, pseudo-random numbers in the most simple package there is: a stream of bits.

* Notice that IE is short-hand for IEnumerable.

No comments:

Post a Comment