LogProb

:logprob is a small, focused libary to store, compare, and format probabilities in a safe way—without forcing you to become a math expert. You don’t have to “do math in log space” yourself.

Work with probabilities in a way that is:

Instead of juggling raw probabilities like 0.0000001234, store their logarithm (the "log probability") and convert back only when you need a normal number or a percentage.

Why “log” probabilities at all?

When you multiply several probabilities together (for example, combining independent chances), the numbers get very small very fast. Conceptually, computers can lose precision or round them down to zero.

Example:

With logs:

Installation

Add to mix.exs:

def deps do
  [
    {:logprob, "~> 0.1.0"}
  ]
end

Plain Language Usage

A LogProb is just a tiny wrapper around Decimal:

%LogProb{value: #Decimal<-2.3025850929940455>}

That decimal is the natural log (:math.log/1) of an ordinary probability between 0.0 and 1.0.

Smaller probabilities = more negative log values.

Creating LogProb values

Pick the constructor that matches what you have on hand.

# From a raw log value (float):
LogProb.new(-1.386294361)

# From a normal probability (0.0–1.0):
LogProb.from_probability(0.25)

# From a string (including "-Infinity"):
LogProb.new("-Infinity")

# From an existing Decimal:
LogProb.new(Decimal.new("-2.3026"))

Converting back

lp = LogProb.from_probability(0.4)

LogProb.to_probability(lp)
#=> 0.4 (plain float)

LogProb.to_percent(lp)
#=> "40.00"

LogProb.to_percent(lp, decimals: 1, percentage_symbol: true)
#=> "40.0%"

Comparing

LogProb.compare/2 returns:

Greater means “represents a higher probability”.

a = LogProb.from_probability(0.6)
b = LogProb.from_probability(0.2)
LogProb.compare(a, b)
#=> :gt

FAQ

Q: Do I need to know logarithms to use this? A: No. Treat LogProb as a probability wrapper.

Q: Why are the numbers negative? A: Because logs of numbers between 0 and 1 are negative. Closer to zero = more likely.

Q: Can I add two LogProb values? A: Not yet. Today this library focuses on representation, conversion, and comparison. Future versions might include safe combination helpers.

Q: What about base-10 logs? A: This uses natural log (base e). That’s standard for probability work.

Q: Will precision drift? A: Internally we store a Decimal, and convert through floats only when necessary (e.g. :math.exp). Decimal does an excellent job in its concerns so we expect our (very slight) extension here to be fine for typical application-level usage.