# `ExDataSketch.Quantiles`
[🔗](https://github.com/thanos/ex_data_sketch/blob/main/lib/ex_data_sketch/quantiles.ex#L1)

Facade for quantile sketch algorithms.

Provides a unified API for creating and querying quantile sketches.

## Supported Types

- `:kll` (default) -- KLL quantiles sketch. See `ExDataSketch.KLL`.
- `:ddsketch` -- DDSketch quantiles sketch. See `ExDataSketch.DDSketch`.
- `:req` -- REQ relative error quantiles sketch. See `ExDataSketch.REQ`.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new(type: :kll)
    iex> sketch.__struct__
    ExDataSketch.KLL

    iex> sketch = ExDataSketch.Quantiles.new()
    iex> sketch = ExDataSketch.Quantiles.update(sketch, 42.0)
    iex> ExDataSketch.Quantiles.count(sketch)
    1

# `sketch`

```elixir
@type sketch() ::
  ExDataSketch.KLL.t() | ExDataSketch.DDSketch.t() | ExDataSketch.REQ.t()
```

# `cdf`

```elixir
@spec cdf(sketch(), [number()]) :: [float()] | nil
```

Returns the CDF at the given split points.

Given split points `[s1, s2, ..., sm]`, returns `[rank(s1), rank(s2), ..., rank(sm)]`.
Returns `nil` if the sketch is empty.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update_many(1..100)
    iex> cdf = ExDataSketch.Quantiles.cdf(sketch, [25.0, 75.0])
    iex> length(cdf)
    2

# `count`

```elixir
@spec count(sketch()) :: non_neg_integer()
```

Returns the total number of items inserted into the sketch.

## Examples

    iex> ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.count()
    0

# `max_value`

```elixir
@spec max_value(sketch()) :: float() | nil
```

Returns the maximum value seen by the sketch, or `nil` if empty.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update(5.0)
    iex> ExDataSketch.Quantiles.max_value(sketch)
    5.0

# `merge`

```elixir
@spec merge(sketch(), sketch()) :: sketch()
```

Merges two quantile sketches of the same type.

## Examples

    iex> a = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update(1.0)
    iex> b = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update(2.0)
    iex> merged = ExDataSketch.Quantiles.merge(a, b)
    iex> ExDataSketch.Quantiles.count(merged)
    2

# `min_value`

```elixir
@spec min_value(sketch()) :: float() | nil
```

Returns the minimum value seen by the sketch, or `nil` if empty.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update(5.0)
    iex> ExDataSketch.Quantiles.min_value(sketch)
    5.0

# `new`

```elixir
@spec new(keyword()) :: sketch()
```

Creates a new quantile sketch.

## Options

- `:type` - sketch type, `:kll` (default), `:ddsketch`, or `:req`.
- All other options are passed to the underlying sketch constructor.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new(type: :kll, k: 200)
    iex> sketch.opts
    [k: 200]

# `pmf`

```elixir
@spec pmf(sketch(), [number()]) :: [float()] | nil
```

Returns the PMF at the given split points.

Given split points `[s1, s2, ..., sm]`, returns `m+1` values representing
the approximate fraction of items in each interval. Returns `nil` if empty.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update_many(1..100)
    iex> pmf = ExDataSketch.Quantiles.pmf(sketch, [50.0])
    iex> length(pmf)
    2

# `quantile`

```elixir
@spec quantile(sketch(), float()) :: float() | nil
```

Returns the approximate value at the given normalized rank.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update_many(1..100)
    iex> q = ExDataSketch.Quantiles.quantile(sketch, 0.5)
    iex> is_float(q)
    true

# `quantiles`

```elixir
@spec quantiles(sketch(), [float()]) :: [float() | nil]
```

Returns the approximate values at the given normalized ranks.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update_many(1..100)
    iex> qs = ExDataSketch.Quantiles.quantiles(sketch, [0.25, 0.5, 0.75])
    iex> length(qs)
    3

# `rank`

```elixir
@spec rank(sketch(), number()) :: float() | nil
```

Returns the approximate normalized rank of a given value.

The rank is the fraction of items in the sketch that are less than or
equal to the given value. Returns `nil` if the sketch is empty.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update_many(1..100)
    iex> r = ExDataSketch.Quantiles.rank(sketch, 50.0)
    iex> is_float(r)
    true

# `update`

```elixir
@spec update(sketch(), number()) :: sketch()
```

Updates the sketch with a single numeric value.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update(1.0)
    iex> ExDataSketch.Quantiles.count(sketch)
    1

# `update_many`

```elixir
@spec update_many(sketch(), Enumerable.t()) :: sketch()
```

Updates the sketch with multiple numeric values.

## Examples

    iex> sketch = ExDataSketch.Quantiles.new() |> ExDataSketch.Quantiles.update_many([1.0, 2.0])
    iex> ExDataSketch.Quantiles.count(sketch)
    2

---

*Consult [api-reference.md](api-reference.md) for complete listing*
