Skip to content

CauchyDistribution::getCumulativeProbability delegates to StudentT incomplete-beta; should use closed-form arctan #48

Description

@OldCrow

Summary

CauchyDistribution is implemented as a delegation wrapper over StudentTDistribution(ν=1). While mathematically correct, this means getCumulativeProbability evaluates the regularised incomplete-beta function — an expensive iterative algorithm — when the Cauchy CDF has a trivial closed form:

F(x; x₀, γ) = (1/π) · arctan((x − x₀) / γ) + 0.5

One arctan per element, no iteration.

Evidence

From the benchmarks/scipy_comparison.py cross-machine run (v0.3.2, scipy 1.18.0):

Machine SIMD Cauchy CDF N=1k N=10k N=100k N=1M
Zen4 / AVX-512 (Windows) AVX-512 0.4× 0.2× 0.2× 0.3×
Kaby Lake / AVX2+FMA (macOS) AVX2+FMA 0.8× 0.9× 1.0× 1.1×

On Kaby Lake the delegation is merely at parity with scipy; on Zen4 (where scipy can exploit AVX-512 vectorised arctan) Cauchy CDF is 3–5× slower than scipy. The gap widens with SIMD width, meaning this will worsen on any wider future architecture.

For comparison, Cauchy PDF and log_pdf are competitive (3–9× faster than scipy at all sizes), confirming the issue is specific to the CDF path.

Root cause

src/cauchy.cpp getCumulativeProbability(double) delegates to StudentTDistribution::getCumulativeProbability, which calls the regularised incomplete-beta path. scipy's cauchy.cdf uses the arctan closed form, which is both faster and simpler.

Proposed fix

Implement getCumulativeProbability directly in CauchyDistribution:

double CauchyDistribution::getCumulativeProbability(double x) const noexcept {
    return 0.5 + std::atan((x - x0_) / gamma_) * detail::INV_PI;
}

The batch span overload should call vector_atan (or scalar loop until a SIMD atan primitive is available). This also removes one delegation indirection from every scalar CDF call.

Related

If a vector_atan SIMD primitive is added, the batch CDF path would benefit immediately. The existing dispatch table already includes vector_cos; vector_atan follows the same pattern.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions