# Vector of random variables, i.e. distributions

`DistributionVectors.AbstractDistributionVector`

— Type`AbstractDistributionVector{D <: Distribution}`

Is any type able represent a vector of distribution of the same type. This corresponds to a sequence of random variables, each characterized by the same type of distribution but with different parameters. This allows aggregating functions to work, for example, computing the distribution of the sum of random variables by `sum(dv::AbstractDistributionVector)`

.

It is parametrized by `D <: Distribution`

defining the type of the distribution used for all the random variables.

Items may be missing. Hence the element type of the iterator is `Union{Missing,D}`

.

AbstractDistributionVector

- is iterable
- has length and index access, i.e.
`dv[i]::D`

- access to entire parameter vectors:
`params(dv,Val(i))`

- conversion to Tuple of Vectors:
`params(dv)`

- array of random numbers:
`rand(n, dv)`

: adding one dimension that represents across random variables - query if entry is missing without needing to construct the distribution entry:
`ismissing(dv,i)`

:

Specific implementations, need to implement at minimum methods `length`

and `getindex`

, and `params`

.

There are two standard implementations:

`SimpleDistributionVector`

: fast indexing but slower`params`

method`ParamDistributionVector`

: possible allocations in indexing but faster`params`

**Examples**

```
import LinearAlgebra: I
dmn1 = MvNormal([0,0,0], 1 * I)
dmn2 = MvNormal([1,1,1], 2 * I)
dv = SimpleDistributionVector(dmn1, dmn2, missing, missing);
sample = rand(dv,2);
# 4 distr, each 2 samples of length 3
size(sample) == (3,2,4)
```

`DistributionVectors.SimpleDistributionVector`

— Type`SimpleDistributionVector{D <: Distribution, V}`

Is an Vector-of-Distribution based implementation of `AbstractDistributionVector`

.

Vector of random var can be created by

- specifying the distributions as arguments.

```
d1 = LogNormal(log(110), 0.25)
d2 = LogNormal(log(100), 0.15)
dv = SimpleDistributionVector(d1, d2, missing);
isequal(params(dv, Val(1)), [log(110), log(100), missing])
```

- providing the Type of distribution and vectors of each parameter

```
mu = [1.1,1.2,1.3]
sigma = [1.01, 1.02, missing]
dv = SimpleDistributionVector(LogNormal{eltype(mu)}, mu, sigma);
isequal(params(dv, Val(1)), [1.1,1.2,missing])
```

Note that if one of the parameters is missing, then the entire entry of the distribution is marked missing.

Since Distributions are stored directly, indexing passes a reference. However, getting parameter vectors, required iterating all distributions, and allocating a new vector.

`DistributionVectors.ParamDistributionVector`

— Type`ParamDistributionVector{D <: Distribution, V}`

Is an Tuple of Vectors based implementation of `AbstractDistributionVector`

.

Vector of random var can be created by

- specifying the distributions as arguments with some overhead of converting the Distributions to vectors of each parameter

```
d1 = LogNormal(log(110), 0.25)
d2 = LogNormal(log(100), 0.15)
dv = ParamDistributionVector(d1, d2, missing);
isequal(params(dv, Val(1)), [log(110), log(100), missing])
```

- providing the Type of distribution and vectors of each parameter

```
mu = [1.1,1.2,1.3]
sigma = [1.01, 1.02, missing]
dv = ParamDistributionVector(LogNormal{eltype(mu)}, mu, sigma);
ismissing(dv[3])
isequal(params(dv, Val(1)), [1.1,1.2,1.3]) # third still not missing here
```

Note that if one of the parameters for entry `i`

is missing, then `dv[i]`

is missing.

Since distributions are stored by parameter vectors, the acces to these vectors is just passing a reference. Indexing, will create Distribution types.

## Helpers

The conversion between a missing-allowed vector of parameter tuples to a tuple of vectors for each parameter (as used by `ParamDistributionVector`

) is provided in a type-stable manner by function `vectuptotupvec`

.

`DistributionVectors.vectuptotupvec`

— Function`vectuptotupvec(vectup)`

Typesafe convert from Vector of Tuples to Tuple of Vectors.

**Arguments**

`vectup`

: A Vector of identical Tuples

**Examples**

```
vectup = [(1,1.01, "string 1"), (2,2.02, "string 2")]
vectuptotupvec(vectup) == ([1, 2], [1.01, 2.02], ["string 1", "string 2"])
```