# README

## Introduction

High performance platform for generating random values, with probabilities or weights.

[Upgrading from before v1.0.0?](/guides/upgrading_guide.md)

## Docs

See [Hex docs](https://weighted-random.hexdocs.pm/). Documentation will not be kept in the README.

## Visual Examples

Uniform random

```elixir
for _ <- 1..5000 do
  Enum.random(0..3)
end
```

![Uniform](https://github.com/greetingsfellowhumans/weighted_random/raw/master/assets/examples/uniform.png)

```elixir

probabilities = [
  0.3, 0.05, 0.6, 0.05
]
WeightedRandom.preprocess_p(probabilities)
|> WeightedRandom.take(1000)
```

![Probabilities](https://github.com/greetingsfellowhumans/weighted_random/raw/master/assets/examples/probabilities.png)

```elixir
# Weights offer an alternative paradigm to probabilities.
# By default, every number has a weight of 1.0
# Let's add a little weight to the outcome of 2 for a total of 1.8

outcomes = 0..3
weights = [
  %{target: 2, amount: 0.8}
]

WeightedRandom.preprocess(outcomes, weights)
|> WeightedRandom.take(5000)
```

![Small Weight](https://github.com/greetingsfellowhumans/weighted_random/raw/master/assets/examples/small_weight.png)

WeightedRandom integrates well with the [Curves](https://hex.pm/packages/curves) library.

```elixir
####
# By using different predefined curves, we clearly get very distinct shapes
# (Of course, some curves work better than others when doing this)

curve = :ease_in_out
outcomes = 0..100
weights = [%{curve: curve, radius: 25, target: 50, amount: 100}]

# see that `radius` field? 
# It basically means we are now targeting all numbers from 25-75,
# or rather (target - radius) to (target + radius)
# But instead of applying the weight amount of 100 evenly, it spreads it out as an ease_in_out bezier curve.

WeightedRandom.preprocess(outcomes, weights)
|> WeightedRandom.take(1_000_000)
```

![Ease In Out](https://github.com/greetingsfellowhumans/weighted_random/raw/master/assets/examples/ease_in_out.png)

```elixir
#### Define your own bezier curve ####
curve = [
  {0, 0},
  {0.33, -4},
  {0.67, 4},
  {1, 1}
]
outcomes = 0..100
weights = [%{target: 50, amount: 200, radius: 25, curve: curve}]
####


WeightedRandom.preprocess(outcomes, weights)
|> WeightedRandom.take(1_000_000)
```

![Custom Curve](https://github.com/greetingsfellowhumans/weighted_random/raw/master/assets/examples/custom_curve.png)
