README.md

# WAM

Pure Elixir implementation of Walker's Alias Method (WAM). It's method for performing weighted random sampling.

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `wam` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:wam, "~> 0.1.0"}
  ]
end
```

## Usage

It supports both weights and probabilities.

```elixir
wam = WAM.new(%{a: 10, b: 4, c: 5})
wam = WAM.new(%{a: 10 / 19, b: 4 / 19, c: 5 / 19})
```

Also it supports list of tuples and two lists:

```elixir
wam = WAM.new([{:a, 10}, {:b, 4}, {:c, 5}])
wam = WAM.new([:a, :b, :c], [10, 4, 5])
```

And provides three functions to work with random sampling:

- `fetch(wam, index, random)` - to get weighted value in form of `{:ok, value}` or return `{:error, reason}` tuple in case of error. 

  ```elixir
  {:ok, value} = WAM.fetch(wam, :rand.uniform(wam.size) - 1, :rand.uniform())
  {:error, reason} = WAM.fetch(wam, :rand.uniform(wam.size) + 1, :rand.uniform())
  ```

- `fetch(wam, index, random, default \\ nil)` - to get weighted value or default value in case of error. The default value is `nil` unless otherwise specified. 

  ```elixir
  value = WAM.get(wam, :rand.uniform(wam.size) - 1, :rand.uniform())
  nil = WAM.get(wam, :rand.uniform(wam.size) + 1, :rand.uniform())
  value = WAM.get(wam, :rand.uniform(wam.size) - 1, :rand.uniform(), :default)
  :default = WAM.get(wam, :rand.uniform(wam.size) + 1, :rand.uniform(), :default)
  ```

- `index(wam, index, random)` - to get weighted index in form of `{:ok, value}` or return `{:error, reason}` tuple in case of error

  ```elixir
  {:ok, index} = WAM.fetch(wam, :rand.uniform(wam.size) - 1, :rand.uniform())
  {:error, reason} = WAM.fetch(wam, :rand.uniform(wam.size) + 1, :rand.uniform())
  ```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/wam>.