Skip to content

[BUG]: stats/base/dists/geometric/mgf returns the MGF for the number of trials instead of the number of failures #15780

Open

Description

@SajalDevX

Description

stdlib's geometric distribution counts the number of failures before the first success (support 0, 1, 2, ...), per the pmf, mean, and variance packages. Its MGF should be p / (1 - (1-p) e^t), but geometric/mgf returns p e^t / (1 - (1-p) e^t), which is the MGF for the number of trials. Every value is off by a factor of e^t.

Reproduction

var mgf = require( '@stdlib/stats/base/dists/geometric/mgf' );
var pmf = require( '@stdlib/stats/base/dists/geometric/pmf' );
var mean = require( '@stdlib/stats/base/dists/geometric/mean' );

var s = 0.0;
var k;
for ( k = 0; k < 2000; k++ ) {
    s += Math.exp( 0.1*k ) * pmf( k, 0.3 );
}
console.log( mgf( 0.1, 0.3 ), s );
// => 1.4646 1.3252

console.log( ( mgf( 1e-6, 0.3 ) - mgf( -1e-6, 0.3 ) ) / 2e-6, mean( 0.3 ) );
// => 3.3333 2.3333

console.log( mgf( 0.5, 1.0 ) );
// => 1.6487 (X is always 0 when p = 1, so this should be 1)

Expected Results

mgf( 0.1, 0.3 ) ≈ 1.3252, and mgf( t, 1.0 ) = 1 for all valid t. The negative binomial MGF in stdlib, (p / (1 - (1-p) e^t))^r, already uses the failures convention. With r = 1 it gives the correct geometric value.

Actual Results

Values are too large by a factor of e^t. The Julia fixtures were generated with Distributions.jl 0.23.8. That version had the same trials-based formula. Current Distributions.jl evaluates p / (p - (1-p) expm1(t)).

Version

develop (25751e9)

Environments

Node.js

Activity

  1. stdlib-bot commented on Oct 2, 2026

    @stdlib-bot
    Contributor

    👋 Hi there! 👋

    And thank you for opening your first issue! We will get back to you shortly. 🏃 💨

    If you have any further questions while waiting for a response, please join our Zulip community to chat with project maintainers and other community members.

  2. kgryte commented on Oct 2, 2026

    @kgryte
    Member

    @SajalDevX I am not sure you are correct here. There are two formulations of the geometric distribution (see Wikipedia: https://en.wikipedia.org/wiki/Geometric_distribution). Both are correct.

    @Planeshifter Would you be willing to comment here?

  3. ghost added on Oct 2, 2026
  4. ghost
    self-assigned this
    on Oct 2, 2026
  5. SajalDevX commented on Oct 2, 2026

    @SajalDevX
    Author

    Thanks for taking a look! Agreed that both parameterizations are valid. The reason I flagged this is that the rest of the geometric namespace uses the number-of-failures form: pmf is (1-p)^x p for x = 0, 1, 2, ..., mean is (1-p)/p, and cdf is 1-(1-p)^(floor(x)+1). mgf is the only one using the number-of-trials form, so it doesn't match the other functions in the package.

    For example, with p = 0.3, the derivative of the current mgf at t = 0 is 1/p ≈ 3.33, while mean( 0.3 ) returns 0.7/0.3 ≈ 2.33. Summing exp(t*x) * pmf(x, p) directly for t = 0.1, p = 0.3 gives 1.3252, which matches p / (1 - (1-p)e^t), while the current implementation returns about 1.4646.

    If you'd rather keep the current formula, I'm happy to change the PR to only update the README/docs to say it describes the number of trials. But that would leave mgf describing a different random variable than the rest of the package.

  6. kgryte commented on Oct 2, 2026

    @kgryte
    Member

    I'll defer to @Planeshifter here.

  7. Planeshifter commented on Oct 2, 2026

    @Planeshifter
    Member

    Yes, this report is accurate. Julia's Distribution package had the same parameterization inconsistency, causing us to carry it forward. They fixed it in https://github.com/JuliaStats/Distributions.jl/pull/1604. Per the linked PR, it would be worthwhile to also confirm whether the same issue is present in the negative binomial MGF package.

  8. ghost removed on Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions