statrs-dev / statrs

Statistical computation library for Rust
https://docs.rs/statrs/latest/statrs/
MIT License
546 stars 78 forks source link

fix: Fix laplace.inverse_cdf(). #161

Closed WarrenWeckesser closed 2 years ago

WarrenWeckesser commented 2 years ago

The expressions in the implementation of laplace.inverse_cdf() were missing calls to ln().

Tests for the cdf() and inverse_cdf() methods are included.

Closes gh-160.

WarrenWeckesser commented 2 years ago

I added the helper function test_rel_close to emulate the existing patterns used in the test module. To be honest, though, I'd be happy with something like this

    #[test]
    fn test_cdf() {
        let loc = 0.0f64;
        let scale = 1.0f64;
        let laplace = Laplace::new(loc, scale).unwrap();
        let reltol = 1e-15f64;

        // Expected value from Wolfram Alpha: CDF[LaplaceDistribution[0, 1], 1/2].
        let expected = 0.69673467014368328819810023250440977f64;
        assert_relative_eq!(laplace.cdf(0.5), expected, epsilon = 0.0, max_relative = reltol);

        // Wolfram Alpha: CDF[LaplaceDistribution[0, 1], -1/2]
        let expected = 0.30326532985631671180189976749559023f64;
        assert_relative_eq!(laplace.cdf(-0.5), expected, epsilon = 0.0, max_relative = reltol);

        // Wolfram Alpha: CDF[LaplaceDistribution[0, 1], -100]
        let expected = 1.8600379880104179814798479019315592e-44f64;
        assert_relative_eq!(laplace.cdf(-100.0), expected, epsilon = 0.0, max_relative = reltol);
    }

which has a little less abstraction and seems clearer to me.

(rustfmt doesn't like those long lines, so the calls of assert_relative_eq would actually end up with each parameter on a separate line.)