# Probability Metrics

> NumKong for Rust

```rust
use numkong::{JensenShannon, KullbackLeibler};

let p = [0.2_f32, 0.3, 0.5];
let q = [0.1_f32, 0.3, 0.6];
let kl_forward = f32::kullbackleibler(&p, &q).unwrap();
let kl_reverse = f32::kullbackleibler(&q, &p).unwrap();
assert!(kl_forward != kl_reverse); // KLD is asymmetric

let js_forward = f32::jensenshannon(&p, &q).unwrap();
let js_reverse = f32::jensenshannon(&q, &p).unwrap();
assert!((js_forward - js_reverse).abs() < 1e-6, "JSD is symmetric");
```

`use numkong::JensenShannon;`

`use numkong::KullbackLeibler;`

`use numkong::ProbabilitySimilarity;`

## JensenShannon

Computes the __Jensen-Shannon distance__ between two probability distributions.

```rust
pub trait JensenShannon: Sized
```

d_JS(P, Q) = √(½(D_KL(P‖M) + D_KL(Q‖M))), where M = (P + Q) / 2

Range: [0, √ln2]. Symmetric. Fails with [`Error::ShapeMismatch`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#ShapeMismatch) if lengths differ,
or [`Error::KernelFailed`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#KernelFailed) carrying the kernel's status.

Implemented for: `f64`, `f32`, [`f16`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#f16), [`bf16`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#bf16).

Implementors: - `impl [JensenShannon](#JensenShannon) for f64`
- `impl [JensenShannon](#JensenShannon) for f32`
- `impl [JensenShannon](#JensenShannon) for [f16](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#f16)`
- `impl [JensenShannon](#JensenShannon) for [bf16](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#bf16)`

## Output

Result type of the divergence.

```rust
type Output;
```

## jensenshannon

Computes the Jensen-Shannon divergence between `a` and `b`.

```rust
fn jensenshannon(a: &[Self], b: &[Self]) -> Result<Self::Output, Error>
```

## js

Alias for [`jensenshannon`](#jensenshannon).

```rust
fn js(a: &[Self], b: &[Self]) -> Result<Self::Output, Error>
```

## KullbackLeibler

Computes the __Kullback-Leibler divergence__ between two probability distributions.

```rust
pub trait KullbackLeibler: Sized
```

D_KL(P‖Q) = ∑ᵢ pᵢ × ln(pᵢ / qᵢ)

Range: [0, ∞). Not symmetric. Fails with [[`Error::ShapeMismatch`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#ShapeMismatch)] if lengths differ,
or [`Error::KernelFailed`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#KernelFailed) carrying the kernel's status.

Implemented for: `f64`, `f32`, [`f16`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#f16), [`bf16`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#bf16).

Implementors: - `impl [KullbackLeibler](#KullbackLeibler) for f64`
- `impl [KullbackLeibler](#KullbackLeibler) for f32`
- `impl [KullbackLeibler](#KullbackLeibler) for [f16](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#f16)`
- `impl [KullbackLeibler](#KullbackLeibler) for [bf16](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#bf16)`

## Output

Result type of the divergence.

```rust
type Output;
```

## kullbackleibler

Computes the Kullback-Leibler divergence of `a` from `b`.

```rust
fn kullbackleibler(a: &[Self], b: &[Self]) -> Result<Self::Output, Error>
```

## kl

Alias for [`kullbackleibler`](#kullbackleibler).

```rust
fn kl(a: &[Self], b: &[Self]) -> Result<Self::Output, Error>
```

## ProbabilitySimilarity

[`ProbabilitySimilarity`](#ProbabilitySimilarity) bundles the divergence metrics: KullbackLeibler and JensenShannon.

```rust
pub trait ProbabilitySimilarity: KullbackLeibler + JensenShannon
```

Implementors: - `impl<Scalar: [KullbackLeibler](#KullbackLeibler) + [JensenShannon](#JensenShannon)> [ProbabilitySimilarity](#ProbabilitySimilarity) for Scalar`

