packages feed

probability-dist-0.1.0.0: README.md

# probability-dist

A Haskell library providing probability distributions and related probability functions.

The library is designed around a small, explicit public API. Discrete and continuous probability distributions are exposed through separate modules, allowing applications to depend only on the functionality they need.

## Features

* Discrete probability distributions
* Continuous probability distributions
* Probability mass functions (PMF)
* Probability density functions (PDF)
* Cumulative distribution functions (CDF)
* Distribution-specific moments where implemented
* Numerically stable logarithmic calculations for combinatorial and special functions
* Explicit error handling through `Either`

## Requirements

* GHC 9.10.3 or compatible GHC version
* Cabal 3.16.1.0 or compatible Cabal version
* `base >= 4.20 && < 5`

## Installation

Clone the repository and build it with Cabal:

```bash
git clone <repository-url>
cd probability-dist
cabal build
```

Run the test suite with:

```bash
cabal test
```

The package can also be built as a source distribution:

```bash
cabal sdist
```

## Public API

The library exposes two public modules.

### Discrete distributions

```haskell
import Probability.Discrete
```

This module contains the discrete probability distributions implemented by the package.

Current distributions include:

* Binomial
* Negative Binomial
* Geometric
* Multinomial

### Continuous distributions

```haskell
import Probability.Continuous
```

This module contains the continuous probability distributions implemented by the package.

Current distributions include:

* Normal
* Exponential
* Gamma
* Uniform

The modules are intentionally separated so that an application requiring only discrete or only continuous distributions does not need to import both APIs.

## Basic Usage

### Binomial distribution

The binomial PMF is exposed through `binomialPMF`.

```haskell
import Probability.Discrete

main :: IO ()
main = do
    print (binomialPMF 3 10 0.5)
```

The parameters are:

```text
k  n  p
```

where:

* `k` is the number of successes
* `n` is the number of trials
* `p` is the probability of success

The result is returned as an `Either` value, allowing invalid parameters to be handled explicitly.

For example:

```haskell
binomialPMF 3 10 0.5
```

returns a `Right` value containing the probability.

An invalid success count produces an error:

```haskell
binomialPMF 11 10 0.5
```

which returns a `Left` value.

## Negative Binomial and Geometric Distributions

The geometric distribution is implemented as the special case of the negative binomial distribution where:

```text
r = 1
```

For example:

```haskell
import Probability.Discrete

main :: IO ()
main = do
    print (negativeBinomialPMF 2 1 0.5)
    print (geometricPMF 2 0.5)
```

The geometric distribution is therefore provided as a convenience function rather than requiring users to manually express it as a negative binomial distribution with `r = 1`.

## Multinomial Distribution

The multinomial PMF accepts the total number of trials, a vector of category counts, and a corresponding probability vector.

```haskell
import Probability.Discrete

main :: IO ()
main = do
    print $
        multinomialPMF
            10
            [4, 3, 3]
            [0.4, 0.3, 0.3]
```

The count vector and probability vector must be dimensionally compatible.

Invalid input is represented through the package's error type rather than silently producing an invalid probability.

## Normal Distribution

The normal distribution provides PDF and CDF functionality.

```haskell
import Probability.Continuous

main :: IO ()
main = do
    print (normalPDF 0.0 0.0 1.0)
    print (normalCDF 0.0 0.0 1.0)
```

For the standard normal distribution:

```text
μ = 0
σ = 1
```

the CDF at zero is:

```text
0.5
```

The standard deviation is validated explicitly; non-positive values result in an error.

## Exponential Distribution

The exponential distribution is parameterized by its rate `λ`.

```haskell
import Probability.Continuous

main :: IO ()
main = do
    print (exponentialPDF 1.0 2.0)
    print (exponentialCDF 1.0 2.0)
```

The implementation uses numerically appropriate calculations for expressions such as:

```text
1 - exp(-λx)
```

in order to improve numerical behavior for small values.

## Gamma Distribution

The Gamma distribution is parameterized by shape and rate parameters.

```haskell
import Probability.Continuous

main :: IO ()
main = do
    print (gammaPDF 1.0 2.0 1.0)
    print (gammaMean 2.0 1.0)
    print (gammaVar 2.0 1.0)
```

The package also provides the corresponding mean and variance functions.

The exponential distribution can be viewed as a special case of the Gamma distribution with shape parameter equal to one.

## Uniform Distribution

The continuous uniform distribution is parameterized by its lower and upper bounds.

```haskell
import Probability.Continuous

main :: IO ()
main = do
    print (uniformPDF 0.5 0.0 1.0)
    print (uniformCDF 0.5 0.0 1.0)
    print (uniformMean 0.0 1.0)
    print (uniformVar 0.0 1.0)
```

Invalid bounds are reported through the package's error handling mechanism.

## Error Handling

Public distribution functions return results using `Either`.

This makes invalid statistical parameters explicit instead of relying on exceptions or silently returning meaningless numerical values.

For example:

```haskell
case binomialPMF 11 10 0.5 of
    Right probability ->
        print probability

    Left err ->
        print err
```

The package defines distribution-related errors in its internal error module and exposes the resulting error values through the public functions.

## Numerical Design

Several calculations involved in probability distributions can become numerically unstable when performed directly.

The package therefore uses logarithmic forms where appropriate, particularly for:

* factorial-related calculations
* combinations
* Gamma functions
* Beta functions
* probability expressions involving products of many terms

Internally, the package provides mathematical support functions such as:

* `logFactorial`
* `logCombination`
* `logGamma`
* `logBeta`
* `erf`

These functions are implementation details and are kept outside the public API.

This separation allows the public distribution modules to remain focused on probability distributions while the numerical machinery remains internal to the package.

## Testing

The project includes a Cabal test suite covering:

* ordinary distribution values
* boundary conditions
* invalid parameters
* probability constraints
* dimensional consistency
* numerical results
* degenerate cases
* error handling

Run all tests with:

```bash
cabal test
```

The package is also checked with:

```bash
cabal check
```

and can be packaged with:

```bash
cabal sdist
```

## Project Structure

```text
probability-dist/
├── src/
│   └── Probability/
│       ├── Continuous.hs
│       ├── Discrete.hs
│       ├── Error.hs
│       └── Math.hs
├── test/
│   └── Main.hs
├── LICENSE
├── README.md
├── probability-dist.cabal
└── CHANGELOG.md
```

`Probability.Discrete` and `Probability.Continuous` form the public API.

`Probability.Math` and `Probability.Error` are internal implementation modules.

## License

This project is licensed under the BSD 3-Clause License.

See the `LICENSE` file for the complete license text.