Skip to content

Compute the triangular variance from the side widths - #57

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/triangular-variance-offset-bounds
Sep 28, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/triangular-variance-offset-bounds

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #49

What changed

TriangularDistributionProvider.Variance used (a² + b² + c² − ab − ac − bc) / 18 on the raw bounds. When the bounds are large compared with their spread, those squares cancel away every significant digit. Triangular(1e9, 1e9+1, 1e9+2).Variance came out as 0. At 1e12 it came out negative, which made StandardDeviation return NaN.

  • Variance now uses the widths the provider already stores: (lw² + uw² + lw·uw) / 18. The two forms are algebraically identical, but this one depends only on the triangle's shape and not on where it sits.
  • Mean is now Minimum + (lowerWidth + width) / 3, so bounds near double.MaxValue no longer overflow the sum.

Tests

  • Added Triangular_Moments_Do_Not_Depend_On_Where_The_Triangle_Sits. It covers the three repro cases from the issue, the standard deviation at 1e12, and a mean near double.MaxValue.
  • With the old provider restored, the new test fails (1e9 case: expected 0.1667, got 0). With the fix it passes.
  • The full Essentials.Tests suite passes: 917/917.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VPis8BNX5ETFM2XytgJCz7


Generated by Claude Code

The textbook form squared the raw bounds, so bounds large next to their
spread cancelled to 0 or a negative variance. The mean is now measured
from the lower bound so it cannot overflow near double.MaxValue.

Fixes #49

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VPis8BNX5ETFM2XytgJCz7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VPis8BNX5ETFM2XytgJCz7
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants