# RVar

An instance of `RVar`

represents a computation that, when executed, results in a value with randomness applied. `RVar`

is one of the most important structures in CIlib and is therefore discussed first in order to understand how the data structure works.

`RVar`

has a monad instance and therefore allows a for a large amount of composition, but more importantly allows for the tracking of randomness within the `RVar`

computation. This tracking is of the utmost importance within computational intelligence algorithms, as randomness needs to be controlled in a manner that facilitates repetition. In other words, even if a computation uses randomness, given the same inputs, the same results are expected even with randomness applied.

Due to the monadic nature of the data structure, the data structure may be transformed by functions such as `map`

, `flatMap`

, etc

There are several predefined combinators that allow the user to use and create `RVar`

computations. These include functions for randomness applied to primitive types (such and `Int`

and `Double`

) to more complex types that build on the primitives, or even for user defined types.

The simplest would be to look at some examples of `RVar`

usage. It is quite common to request several random numbers. `RVar`

provides several functions, with `ints`

and `doubles`

being the most common for random variable creation:

```
| val ints = RVar.ints(5)
ints: cilib.RVar[List[Int]] = cilib.RVar$$anon$2@e8cd5ee
scala> val doubles = RVar.doubles(5)
doubles: cilib.RVar[List[Double]] = cilib.RVar$$anon$2@1d6758c8
```

Both functions result in a `RVar`

that, when provided with a pseudo-random number generator (PRNG), will result in a list of values.

The user if free to define a PRNG for themselves, but CIlib provides a default PRNG that is suitable for scientific work. The CMWC generator may be initialized by either providing a seed value for the pseudo-random number stream, or it may be taken from the current time of the computer. It is always recommended to record the seed value, so that others may reproduce results, especially if the results are to be published.

Let’s create a `RNG`

instance using both methods:

```
scala> val rng = RNG.init(1234L)
rng: cilib.RNG = cilib.CMWC@65f28afb
scala> val fromTimeYOLO = RNG.fromTime
fromTimeYOLO: cilib.RNG = cilib.CMWC@6fba65f4
```

Now, let’s run both `doubles`

and `ints`

with the generator:

```
scala> val r1 = ints.run(rng)
r1: (cilib.RNG, List[Int]) = (cilib.CMWC@6108a1c3,List(-2012280037, -456312394, -1608573853, -1720473833, 1662253751))
scala> doubles.run(rng)
res1: (cilib.RNG, List[Double]) = (cilib.CMWC@3a6440e6,List(0.5314795508050395, 0.6254747152242208, 0.3870236094802634, 0.3590652564475848, 0.1350043437170152))
scala> val r2 = ints.run(rng)
r2: (cilib.RNG, List[Int]) = (cilib.CMWC@18c0fc35,List(-2012280037, -456312394, -1608573853, -1720473833, 1662253751))
scala> r1._2 == r2._2
res2: Boolean = true
```

The result is a tuple of the state of the PRNG after being used in the computation, together with the result of the computation itself. The important point to note is that running the computation again, with the same PRNG, that is the original state of the PRNG *will* result in the same obtained results. Unlike the normal PRNG within the JVM platform, obtaining some random value from the source does not implicitly mutate the PRNG. In order to keep selecting from the PRNG stream, the next state of the PRNG should be passed into subsequent computations, when needed:

```
scala> val (rng2, x) = ints.run(rng)
rng2: cilib.RNG = cilib.CMWC@359f02e6
x: List[Int] = List(-2012280037, -456312394, -1608573853, -1720473833, 1662253751)
scala> val (rng3, y) = ints.run(rng2)
rng3: cilib.RNG = cilib.CMWC@7ed27a03
y: List[Int] = List(-973239118, 1542173555, 1984558752, 579839250, 609517835)
scala> x != y
res3: Boolean = true
```

This manual state passing for the PRNG is very cumbersome and as a result, the monad instance of `RVar`

provides this exact functionality to the user, thereby preventing accidental errors due to incorrect usage of PRNG state. Furthermore, the monad instance for `RVar`

allows for cleaner syntax through the use of a `for`

-comprehension as provided by Scala:

```
scala> val composition = for {
| a <- RVar.next[Int] // Get a single Int
| b <- RVar.next[Double] // Get a single Double, using the next state of the PRNG
| c <- RVar.next[Boolean] // Get a Boolean, again passing the PRNG state
| } yield if (c) a*b else b
composition: cilib.RVar[Double] = cilib.RVar$$anon$2@2b856ae9
scala> composition.run(rng)
res4: (cilib.RNG, Double) = (cilib.CMWC@73e166e5,-1.798488339436242E9)
```

From this definition of how randomness is managed, we can derive several useful algorithms which operate within the `RVar`

computation. Please refer to the scaladoc for more combinators, but some of the more commonly used are illustrated below:

```
scala> val sampleList = List(6,4,5,2,1,3)
sampleList: List[Int] = List(6, 4, 5, 2, 1, 3)
scala> RVar.shuffle(sampleList).run(rng)
res5: (cilib.RNG, List[Int]) = (cilib.CMWC@55d4de7a,List(4, 3, 5, 1, 2, 6))
scala> RVar.sample(3, sampleList).run.run(rng)
res6: (cilib.RNG, Option[List[Int]]) = (cilib.CMWC@3a1405b9,Some(List(5, 3, 4)))
```

Building on `RVar`

, we can easily define probability distributions from which, randomness may be sampled. The provided distributions, where standard distributions are also defined, include:

- Uniform
- Gaussian / Normal
- Cauchy
- Gamma
- Exponential
- etc

The interface for the distributions is simply a resulting `RVar`

```
scala> // Use a derived function from monad to repeat an action 'n' times
| Dist.stdNormal.replicateM(5).run(rng)
res8: (cilib.RNG, List[Double]) = (cilib.CMWC@1733d248,List(0.12471034611540575, 0.10241216207344515, -0.49485286860096944, -2.6592051237450325, 0.7016898748604742))
```