1use crate::distribution::{Continuous, ContinuousCDF};
2use crate::function::erf;
3use crate::statistics::*;
4use crate::{consts, Result, StatsError};
5use rand::Rng;
6use std::f64;
7
8#[derive(Debug, Copy, Clone, PartialEq)]
24pub struct LogNormal {
25 location: f64,
26 scale: f64,
27}
28
29impl LogNormal {
30 pub fn new(location: f64, scale: f64) -> Result<LogNormal> {
50 if location.is_nan() || scale.is_nan() || scale <= 0.0 {
51 Err(StatsError::BadParams)
52 } else {
53 Ok(LogNormal { location, scale })
54 }
55 }
56}
57
58impl ::rand::distributions::Distribution<f64> for LogNormal {
59 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
60 super::normal::sample_unchecked(rng, self.location, self.scale).exp()
61 }
62}
63
64impl ContinuousCDF<f64, f64> for LogNormal {
65 fn cdf(&self, x: f64) -> f64 {
78 if x <= 0.0 {
79 0.0
80 } else if x.is_infinite() {
81 1.0
82 } else {
83 0.5 * erf::erfc((self.location - x.ln()) / (self.scale * f64::consts::SQRT_2))
84 }
85 }
86
87 fn sf(&self, x: f64) -> f64 {
108 if x <= 0.0 {
109 1.0
110 } else if x.is_infinite() {
111 0.0
112 } else {
113 0.5 * erf::erfc((x.ln() - self.location) / (self.scale * f64::consts::SQRT_2))
114 }
115 }
116}
117
118impl Min<f64> for LogNormal {
119 fn min(&self) -> f64 {
128 0.0
129 }
130}
131
132impl Max<f64> for LogNormal {
133 fn max(&self) -> f64 {
142 f64::INFINITY
143 }
144}
145
146impl Distribution<f64> for LogNormal {
147 fn mean(&self) -> Option<f64> {
157 Some((self.location + self.scale * self.scale / 2.0).exp())
158 }
159 fn variance(&self) -> Option<f64> {
169 let sigma2 = self.scale * self.scale;
170 Some((sigma2.exp() - 1.0) * (self.location + self.location + sigma2).exp())
171 }
172 fn entropy(&self) -> Option<f64> {
182 Some(0.5 + self.scale.ln() + self.location + consts::LN_SQRT_2PI)
183 }
184 fn skewness(&self) -> Option<f64> {
194 let expsigma2 = (self.scale * self.scale).exp();
195 Some((expsigma2 + 2.0) * (expsigma2 - 1.0).sqrt())
196 }
197}
198
199impl Median<f64> for LogNormal {
200 fn median(&self) -> f64 {
210 self.location.exp()
211 }
212}
213
214impl Mode<Option<f64>> for LogNormal {
215 fn mode(&self) -> Option<f64> {
225 Some((self.location - self.scale * self.scale).exp())
226 }
227}
228
229impl Continuous<f64, f64> for LogNormal {
230 fn pdf(&self, x: f64) -> f64 {
241 if x <= 0.0 || x.is_infinite() {
242 0.0
243 } else {
244 let d = (x.ln() - self.location) / self.scale;
245 (-0.5 * d * d).exp() / (x * consts::SQRT_2PI * self.scale)
246 }
247 }
248
249 fn ln_pdf(&self, x: f64) -> f64 {
260 if x <= 0.0 || x.is_infinite() {
261 f64::NEG_INFINITY
262 } else {
263 let d = (x.ln() - self.location) / self.scale;
264 (-0.5 * d * d) - consts::LN_SQRT_2PI - (x * self.scale).ln()
265 }
266 }
267}
268
269#[rustfmt::skip]
270#[cfg(all(test, feature = "nightly"))]
271mod tests {
272 use crate::statistics::*;
273 use crate::distribution::{ContinuousCDF, Continuous, LogNormal};
274 use crate::distribution::internal::*;
275 use crate::consts::ACC;
276
277 fn try_create(mean: f64, std_dev: f64) -> LogNormal {
278 let n = LogNormal::new(mean, std_dev);
279 assert!(n.is_ok());
280 n.unwrap()
281 }
282
283 fn bad_create_case(mean: f64, std_dev: f64) {
284 let n = LogNormal::new(mean, std_dev);
285 assert!(n.is_err());
286 }
287
288 fn get_value<F>(mean: f64, std_dev: f64, eval: F) -> f64
289 where F: Fn(LogNormal) -> f64
290 {
291 let n = try_create(mean, std_dev);
292 eval(n)
293 }
294
295 fn test_case<F>(mean: f64, std_dev: f64, expected: f64, eval: F)
296 where F: Fn(LogNormal) -> f64
297 {
298 let x = get_value(mean, std_dev, eval);
299 assert_eq!(expected, x);
300 }
301
302 fn test_almost<F>(mean: f64, std_dev: f64, expected: f64, acc: f64, eval: F)
303 where F: Fn(LogNormal) -> f64
304 {
305 let x = get_value(mean, std_dev, eval);
306 assert_almost_eq!(expected, x, acc);
307 }
308
309 #[test]
310 fn test_create() {
311 try_create(10.0, 0.1);
312 try_create(-5.0, 1.0);
313 try_create(0.0, 10.0);
314 try_create(10.0, 100.0);
315 try_create(-5.0, f64::INFINITY);
316 }
317
318 #[test]
319 fn test_bad_create() {
320 bad_create_case(0.0, 0.0);
321 bad_create_case(f64::NAN, 1.0);
322 bad_create_case(1.0, f64::NAN);
323 bad_create_case(f64::NAN, f64::NAN);
324 bad_create_case(1.0, -1.0);
325 }
326
327 #[test]
328 fn test_mean() {
329 let mean = |x: LogNormal| x.mean().unwrap();
330 test_case(-1.0, 0.1, 0.369723444544058982601, mean);
331 test_case(-1.0, 1.5, 1.133148453066826316829, mean);
332 test_case(-1.0, 2.5, 8.372897488127264663205, mean);
333 test_case(-1.0, 5.5, 1362729.18425285481771, mean);
334 test_case(-0.1, 0.1, 0.9093729344682314204933, mean);
335 test_case(-0.1, 1.5, 2.787095460565850768514, mean);
336 test_case(-0.1, 2.5, 20.59400471119602917533, mean);
337 test_almost(-0.1, 5.5, 3351772.941252693807591, 1e-9, mean);
338 test_case(0.1, 0.1, 1.110710610355705232259, mean);
339 test_case(0.1, 1.5, 3.40416608279081898632, mean);
340 test_almost(0.1, 2.5, 25.15357415581836182776, 1e-14, mean);
341 test_almost(0.1, 5.5, 4093864.715172665106863, 1e-8, mean);
342 test_almost(1.5, 0.1, 4.50415363028848413209, 1e-15, mean);
343 test_case(1.5, 1.5, 13.80457418606709491926, mean);
344 test_case(1.5, 2.5, 102.0027730826996844534, mean);
345 test_case(1.5, 5.5, 16601440.05723477471392, mean);
346 test_almost(2.5, 0.1, 12.24355896580102707724, 1e-14, mean);
347 test_almost(2.5, 1.5, 37.52472315960099891407, 1e-11, mean);
348 test_case(2.5, 2.5, 277.2722845231339804081, mean);
349 test_case(2.5, 5.5, 45127392.83383337999291, mean);
350 test_almost(5.5, 0.1, 245.9184556788219446833, 1e-13, mean);
351 test_case(5.5, 1.5, 753.7042125545612656606, mean);
352 test_case(5.5, 2.5, 5569.162708566004074422, mean);
353 test_case(5.5, 5.5, 906407915.0111549133446, mean);
354 }
355
356 #[test]
357 fn test_variance() {
358 let variance = |x: LogNormal| x.variance().unwrap();
359 test_almost(-1.0, 0.1, 0.001373811865368952608715, 1e-16, variance);
360 test_case(-1.0, 1.5, 10.898468544015731954, variance);
361 test_case(-1.0, 2.5, 36245.39726189994988081, variance);
362 test_almost(-1.0, 5.5, 2.5481629178024539E+25, 1e10, variance);
363 test_almost(-0.1, 0.1, 0.008311077467909703803238, 1e-16, variance);
364 test_case(-0.1, 1.5, 65.93189259328902509552, variance);
365 test_almost(-0.1, 2.5, 219271.8756420929704707, 1e-10, variance);
366 test_almost(-0.1, 5.5, 1.541548733459471E+26, 1e12, variance);
367 test_almost(0.1, 0.1, 0.01239867063063756838894, 1e-15, variance);
368 test_almost(0.1, 1.5, 98.35882573290010981464, 1e-13, variance);
369 test_almost(0.1, 2.5, 327115.1995809995715014, 1e-10, variance);
370 test_almost(0.1, 5.5, 2.299720473192458E+26, 1e12, variance);
371 test_almost(1.5, 0.1, 0.2038917589520099120699, 1e-14, variance);
372 test_almost(1.5, 1.5, 1617.476145997433210727, 1e-12, variance);
373 test_almost(1.5, 2.5, 5379293.910566451644527, 1e-9, variance);
374 test_almost(1.5, 5.5, 3.7818090853910142E+27, 1e12, variance);
375 test_almost(2.5, 0.1, 1.506567645006046841936, 1e-13, variance);
376 test_almost(2.5, 1.5, 11951.62198145717670088, 1e-11, variance);
377 test_case(2.5, 2.5, 39747904.47781154725843, variance);
378 test_almost(2.5, 5.5, 2.7943999487399818E+28, 1e13, variance);
379 test_almost(5.5, 0.1, 607.7927673399807484235, 1e-11, variance);
380 test_case(5.5, 1.5, 4821628.436260521100027, variance);
381 test_case(5.5, 2.5, 16035449147.34799637823, variance);
382 test_case(5.5, 5.5, 1.127341399856331737823E+31, variance);
383 }
384
385 #[test]
386 fn test_entropy() {
387 let entropy = |x: LogNormal| x.entropy().unwrap();
388 test_case(-1.0, 0.1, -1.8836465597893728867265104870209210873020761202386, entropy);
389 test_case(-1.0, 1.5, 0.82440364131283712375834285186996677643338789710028, entropy);
390 test_case(-1.0, 2.5, 1.335229265078827806963856948173628711311498693546, entropy);
391 test_case(-1.0, 5.5, 2.1236866254430979764250411929125703716076041932149, entropy);
392 test_almost(-0.1, 0.1, -0.9836465597893728922776256101467037894202344606927, 1e-15, entropy);
393 test_case(-0.1, 1.5, 1.7244036413128371182072277287441840743152295566462, entropy);
394 test_case(-0.1, 2.5, 2.2352292650788278014127418250478460091933403530919, entropy);
395 test_case(-0.1, 5.5, 3.0236866254430979708739260697867876694894458527608, entropy);
396 test_almost(0.1, 0.1, -0.7836465597893728811753953638951383851839177797845, 1e-15, entropy);
397 test_almost(0.1, 1.5, 1.9244036413128371293094579749957494785515462375544, 1e-15, entropy);
398 test_case(0.1, 2.5, 2.4352292650788278125149720712994114134296570340001, entropy);
399 test_case(0.1, 5.5, 3.223686625443097981976156316038353073725762533669, entropy);
400 test_almost(1.5, 0.1, 0.6163534402106271132734895129790789126979238797614, 1e-15, entropy);
401 test_case(1.5, 1.5, 3.3244036413128371237583428518699667764333878971003, entropy);
402 test_case(1.5, 2.5, 3.835229265078827806963856948173628711311498693546, entropy);
403 test_case(1.5, 5.5, 4.6236866254430979764250411929125703716076041932149, entropy);
404 test_case(2.5, 0.1, 1.6163534402106271132734895129790789126979238797614, entropy);
405 test_almost(2.5, 1.5, 4.3244036413128371237583428518699667764333878971003, 1e-15, entropy);
406 test_case(2.5, 2.5, 4.835229265078827806963856948173628711311498693546, entropy);
407 test_case(2.5, 5.5, 5.6236866254430979764250411929125703716076041932149, entropy);
408 test_case(5.5, 0.1, 4.6163534402106271132734895129790789126979238797614, entropy);
409 test_almost(5.5, 1.5, 7.3244036413128371237583428518699667764333878971003, 1e-15, entropy);
410 test_case(5.5, 2.5, 7.835229265078827806963856948173628711311498693546, entropy);
411 test_case(5.5, 5.5, 8.6236866254430979764250411929125703716076041932149, entropy);
412 }
413
414 #[test]
415 fn test_skewness() {
416 let skewness = |x: LogNormal| x.skewness().unwrap();
417 test_almost(-1.0, 0.1, 0.30175909933883402945387113824982918009810212213629, 1e-14, skewness);
418 test_case(-1.0, 1.5, 33.46804679732172529147579024311650645764144530123, skewness);
419 test_almost(-1.0, 2.5, 11824.007933610287521341659465200553739278936344799, 1e-11, skewness);
420 test_almost(-1.0, 5.5, 50829064464591483629.132631635472412625371367420496, 1e4, skewness);
421 test_almost(-0.1, 0.1, 0.30175909933883402945387113824982918009810212213629, 1e-14, skewness);
422 test_case(-0.1, 1.5, 33.46804679732172529147579024311650645764144530123, skewness);
423 test_almost(-0.1, 2.5, 11824.007933610287521341659465200553739278936344799, 1e-11, skewness);
424 test_almost(-0.1, 5.5, 50829064464591483629.132631635472412625371367420496, 1e4, skewness);
425 test_almost(0.1, 0.1, 0.30175909933883402945387113824982918009810212213629, 1e-14, skewness);
426 test_case(0.1, 1.5, 33.46804679732172529147579024311650645764144530123, skewness);
427 test_almost(0.1, 2.5, 11824.007933610287521341659465200553739278936344799, 1e-11, skewness);
428 test_almost(0.1, 5.5, 50829064464591483629.132631635472412625371367420496, 1e4, skewness);
429 test_almost(1.5, 0.1, 0.30175909933883402945387113824982918009810212213629, 1e-14, skewness);
430 test_case(1.5, 1.5, 33.46804679732172529147579024311650645764144530123, skewness);
431 test_almost(1.5, 2.5, 11824.007933610287521341659465200553739278936344799, 1e-11, skewness);
432 test_almost(1.5, 5.5, 50829064464591483629.132631635472412625371367420496, 1e4, skewness);
433 test_almost(2.5, 0.1, 0.30175909933883402945387113824982918009810212213629, 1e-14, skewness);
434 test_case(2.5, 1.5, 33.46804679732172529147579024311650645764144530123, skewness);
435 test_almost(2.5, 2.5, 11824.007933610287521341659465200553739278936344799, 1e-11, skewness);
436 test_almost(2.5, 5.5, 50829064464591483629.132631635472412625371367420496, 1e4, skewness);
437 test_almost(5.5, 0.1, 0.30175909933883402945387113824982918009810212213629, 1e-14, skewness);
438 test_case(5.5, 1.5, 33.46804679732172529147579024311650645764144530123, skewness);
439 test_almost(5.5, 2.5, 11824.007933610287521341659465200553739278936344799, 1e-11, skewness);
440 test_almost(5.5, 5.5, 50829064464591483629.132631635472412625371367420496, 1e4, skewness);
441 }
442
443 #[test]
444 fn test_mode() {
445 let mode = |x: LogNormal| x.mode().unwrap();
446 test_case(-1.0, 0.1, 0.36421897957152331652213191863106773137983085909534, mode);
447 test_case(-1.0, 1.5, 0.03877420783172200988689983526759614326014406193602, mode);
448 test_case(-1.0, 2.5, 0.0007101743888425490635846003705775444086763023873619, mode);
449 test_case(-1.0, 5.5, 0.000000000000026810038677818032221548731163905979029274677187036, mode);
450 test_case(-0.1, 0.1, 0.89583413529652823774737070060865897390995185639633, mode);
451 test_case(-0.1, 1.5, 0.095369162215549610417813418326627245539514227574881, mode);
452 test_case(-0.1, 2.5, 0.0017467471362611196181003627521060283221112106850165, mode);
453 test_case(-0.1, 5.5, 0.00000000000006594205454219929159167575814655534255162059017114, mode);
454 test_case(0.1, 0.1, 1.0941742837052103542285651753780976842292770841345, mode);
455 test_case(0.1, 1.5, 0.11648415777349696821514223131929465848700730137808, mode);
456 test_case(0.1, 2.5, 0.0021334817700377079925027678518795817076296484352472, mode);
457 test_case(0.1, 5.5, 0.000000000000080541807296590798973741710866097756565304960216803, mode);
458 test_case(1.5, 0.1, 4.4370955190036645692996309927420381428715912422597, mode);
459 test_case(1.5, 1.5, 0.47236655274101470713804655094326791297020357913648, mode);
460 test_case(1.5, 2.5, 0.008651695203120634177071503957250390848166331197708, mode);
461 test_case(1.5, 5.5, 0.00000000000032661313427874471360158184468030186601222739665225, mode);
462 test_case(2.5, 0.1, 12.061276120444720299113038763305617245808510584994, mode);
463 test_case(2.5, 1.5, 1.2840254166877414840734205680624364583362808652815, mode);
464 test_case(2.5, 2.5, 0.023517745856009108236151185100432939470067655273072, mode);
465 test_case(2.5, 5.5, 0.00000000000088782654784596584473099190326928541185172970391855, mode);
466 test_case(5.5, 0.1, 242.2572068579541371904816252345031593584721473492, mode);
467 test_case(5.5, 1.5, 25.790339917193062089080107669377221876655268848954, mode);
468 test_case(5.5, 2.5, 0.47236655274101470713804655094326791297020357913648, mode);
469 test_case(5.5, 5.5, 0.000000000017832472908146389493511850431527026413424899198327, mode);
470 }
471
472 #[test]
473 fn test_median() {
474 let median = |x: LogNormal| x.median();
475 test_case(-1.0, 0.1, 0.36787944117144232159552377016146086744581113103177, median);
476 test_case(-1.0, 1.5, 0.36787944117144232159552377016146086744581113103177, median);
477 test_case(-1.0, 2.5, 0.36787944117144232159552377016146086744581113103177, median);
478 test_case(-1.0, 5.5, 0.36787944117144232159552377016146086744581113103177, median);
479 test_case(-0.1, 0.1, 0.90483741803595956814139238421693559530906465375738, median);
480 test_case(-0.1, 1.5, 0.90483741803595956814139238421693559530906465375738, median);
481 test_case(-0.1, 2.5, 0.90483741803595956814139238421693559530906465375738, median);
482 test_case(-0.1, 5.5, 0.90483741803595956814139238421693559530906465375738, median);
483 test_case(0.1, 0.1, 1.1051709180756476309466388234587796577416634163742, median);
484 test_case(0.1, 1.5, 1.1051709180756476309466388234587796577416634163742, median);
485 test_case(0.1, 2.5, 1.1051709180756476309466388234587796577416634163742, median);
486 test_case(0.1, 5.5, 1.1051709180756476309466388234587796577416634163742, median);
487 test_case(1.5, 0.1, 4.4816890703380648226020554601192758190057498683697, median);
488 test_case(1.5, 1.5, 4.4816890703380648226020554601192758190057498683697, median);
489 test_case(1.5, 2.5, 4.4816890703380648226020554601192758190057498683697, median);
490 test_case(1.5, 5.5, 4.4816890703380648226020554601192758190057498683697, median);
491 test_case(2.5, 0.1, 12.182493960703473438070175951167966183182767790063, median);
492 test_case(2.5, 1.5, 12.182493960703473438070175951167966183182767790063, median);
493 test_case(2.5, 2.5, 12.182493960703473438070175951167966183182767790063, median);
494 test_case(2.5, 5.5, 12.182493960703473438070175951167966183182767790063, median);
495 test_case(5.5, 0.1, 244.6919322642203879151889495118393501842287101075, median);
496 test_case(5.5, 1.5, 244.6919322642203879151889495118393501842287101075, median);
497 test_case(5.5, 2.5, 244.6919322642203879151889495118393501842287101075, median);
498 test_case(5.5, 5.5, 244.6919322642203879151889495118393501842287101075, median);
499 }
500
501 #[test]
502 fn test_min_max() {
503 let min = |x: LogNormal| x.min();
504 let max = |x: LogNormal| x.max();
505 test_case(0.0, 0.1, 0.0, min);
506 test_case(-3.0, 10.0, 0.0, min);
507 test_case(0.0, 0.1, f64::INFINITY, max);
508 test_case(-3.0, 10.0, f64::INFINITY, max);
509 }
510
511 #[test]
512 fn test_pdf() {
513 let pdf = |arg: f64| move |x: LogNormal| x.pdf(arg);
514 test_almost(-0.1, 0.1, 1.7968349035073582236359415565799753846986440127816e-104, 1e-118, pdf(0.1));
515 test_almost(-0.1, 0.1, 0.00000018288923328441197822391757965928083462391836798722, 1e-21, pdf(0.5));
516 test_case(-0.1, 0.1, 2.3363114904470413709866234247494393485647978367885, pdf(0.8));
517 test_almost(-0.1, 1.5, 0.90492497850024368541682348133921492204585092983646, 1e-15, pdf(0.1));
518 test_almost(-0.1, 1.5, 0.49191985207660942803818797602364034466489243416574, 1e-16, pdf(0.5));
519 test_case(-0.1, 1.5, 0.33133347214343229148978298237579567194870525187207, pdf(0.8));
520 test_case(-0.1, 2.5, 1.0824698632626565182080576574958317806389057196768, pdf(0.1));
521 test_almost(-0.1, 2.5, 0.31029619474753883558901295436486123689563749784867, 1e-16, pdf(0.5));
522 test_almost(-0.1, 2.5, 0.19922929916156673799861939824205622734205083805245, 1e-16, pdf(0.8));
523
524test_almost(1.5, 0.1, 2.8602688726477103843476657332784045661507239533567e-104, 1e-116, pdf(0.5));
529 test_case(1.5, 0.1, 1.6670425710002183246335601541889400558525870482613e-64, pdf(0.8));
530 test_almost(1.5, 1.5, 0.10698412103361841220076392503406214751353235895732, 1e-16, pdf(0.1));
531 test_almost(1.5, 1.5, 0.18266125308224685664142384493330155315630876975024, 1e-16, pdf(0.5));
532 test_almost(1.5, 1.5, 0.17185785323404088913982425377565512294017306418953, 1e-16, pdf(0.8));
533 test_almost(1.5, 2.5, 0.50186885259059181992025035649158160252576845315332, 1e-15, pdf(0.1));
534 test_almost(1.5, 2.5, 0.21721369314437986034957451699565540205404697589349, 1e-16, pdf(0.5));
535 test_case(1.5, 2.5, 0.15729636000661278918949298391170443742675565300598, pdf(0.8));
536 test_case(2.5, 0.1, 5.6836826548848916385760779034504046896805825555997e-500, pdf(0.1));
537 test_almost(2.5, 0.1, 3.1225608678589488061206338085285607881363155340377e-221, 1e-233, pdf(0.5));
538 test_almost(2.5, 0.1, 4.6994713794671660918554320071312374073172560048297e-161, 1e-173, pdf(0.8));
539 test_almost(2.5, 1.5, 0.015806486291412916772431170442330946677601577502353, 1e-16, pdf(0.1));
540 test_almost(2.5, 1.5, 0.055184331257528847223852028950484131834529030116388, 1e-16, pdf(0.5));
541 test_case(2.5, 1.5, 0.063982134749859504449658286955049840393511776984362, pdf(0.8));
542 test_almost(2.5, 2.5, 0.25212505662402617595900822552548977822542300480086, 1e-15, pdf(0.1));
543 test_almost(2.5, 2.5, 0.14117186955911792460646517002386088579088567275401, 1e-16, pdf(0.5));
544 test_almost(2.5, 2.5, 0.11021452580363707866161369621432656293405065561317, 1e-16, pdf(0.8));
545 }
546
547 #[test]
548 fn test_neg_pdf() {
549 let pdf = |arg: f64| move |x: LogNormal| x.pdf(arg);
550 test_case(0.0, 1.0, 0.0, pdf(0.0));
551 }
552
553 #[test]
554 fn test_ln_pdf() {
555 let ln_pdf = |arg: f64| move |x: LogNormal| x.ln_pdf(arg);
556 test_case(-0.1, 0.1, -238.88282294119596467794686179588610665317241097599, ln_pdf(0.1));
557 test_almost(-0.1, 0.1, -15.514385149961296196003163062199569075052113039686, 1e-14, ln_pdf(0.5));
558 test_case(-0.1, 0.1, 0.84857339958981283964373051826407417105725729082041, ln_pdf(0.8));
559 test_almost(-0.1, 1.5, -0.099903235403144611051953094864849327288457482212211, 1e-15, ln_pdf(0.1));
560 test_almost(-0.1, 1.5, -0.70943947804316122682964396008813828577195771418027, 1e-15, ln_pdf(0.5));
561 test_almost(-0.1, 1.5, -1.1046299420497998262946038709903250420774183529995, 1e-15, ln_pdf(0.8));
562 test_almost(-0.1, 2.5, 0.07924534056485078867266307735371665927517517183681, 1e-16, ln_pdf(0.1));
563 test_case(-0.1, 2.5, -1.1702279707433794860424967893989374511050637417043, ln_pdf(0.5));
564 test_case(-0.1, 2.5, -1.6132988605030400828957768752511536087538109996183, ln_pdf(0.8));
565 test_case(1.5, 0.1, -719.29643782024317312262673764204041218720576249741, ln_pdf(0.1));
566 test_almost(1.5, 0.1, -238.41793403955250272430898754048547661932857086122, 1e-13, ln_pdf(0.5));
567 test_case(1.5, 0.1, -146.85439481068371057247137024006716189469284256628, ln_pdf(0.8));
568 test_almost(1.5, 1.5, -2.2350748570877992856465076624973458117562108140674, 1e-15, ln_pdf(0.1));
569 test_almost(1.5, 1.5, -1.7001219175524556705452882616787223585705662860012, 1e-15, ln_pdf(0.5));
570 test_almost(1.5, 1.5, -1.7610875785399045023354101841009649273236721172008, 1e-15, ln_pdf(0.8));
571 test_almost(1.5, 2.5, -0.68941644324162489418137656699398207513321602763104, 1e-15, ln_pdf(0.1));
572 test_case(1.5, 2.5, -1.5268736489667254857801287379715477173125628275598, ln_pdf(0.5));
573 test_case(1.5, 2.5, -1.8496236096394777662704671479709839674424623547308, ln_pdf(0.8));
574 test_almost(2.5, 0.1, -1149.5549471196476523788026360929146688367845019398, 1e-12, ln_pdf(0.1));
575 test_almost(2.5, 0.1, -507.73265209554698134113704985174959301922196605736, 1e-12, ln_pdf(0.5));
576 test_almost(2.5, 0.1, -369.16874994210463740474549611573497379941224077335, 1e-13, ln_pdf(0.8));
577 test_almost(2.5, 1.5, -4.1473348984184862316495477617980296904955324113457, 1e-15, ln_pdf(0.1));
578 test_almost(2.5, 1.5, -2.8970762200235424747307247601045786110485663457169, 1e-15, ln_pdf(0.5));
579 test_case(2.5, 1.5, -2.7491513791239977024488074547907467152956602019989, ln_pdf(0.8));
580 test_almost(2.5, 2.5, -1.3778300581206721947424710027422282714793718026513, 1e-15, ln_pdf(0.1));
581 test_case(2.5, 2.5, -1.9577771978563167352868858774048559682046428490575, ln_pdf(0.5));
582 test_case(2.5, 2.5, -2.2053265778497513183112901654193054111123780652581, ln_pdf(0.8));
583 }
584
585 #[test]
586 fn test_neg_ln_pdf() {
587 let ln_pdf = |arg: f64| move |x: LogNormal| x.ln_pdf(arg);
588 test_case(0.0, 1.0, f64::NEG_INFINITY, ln_pdf(0.0));
589 }
590
591 #[test]
592 fn test_cdf() {
593 let cdf = |arg: f64| move |x: LogNormal| x.cdf(arg);
594 test_almost(-0.1, 0.1, 0.0, 1e-107, cdf(0.1));
595 test_almost(-0.1, 0.1, 0.0000000015011556178148777579869633555518882664666520593658, 1e-19, cdf(0.5));
596 test_almost(-0.1, 0.1, 0.10908001076375810900224507908874442583171381706127, 1e-11, cdf(0.8));
597 test_almost(-0.1, 1.5, 0.070999149762464508991968731574953594549291668468349, 1e-11, cdf(0.1));
598 test_case(-0.1, 1.5, 0.34626224992888089297789445771047690175505847991946, cdf(0.5));
599 test_case(-0.1, 1.5, 0.46728530589487698517090261668589508746353129242404, cdf(0.8));
600 test_almost(-0.1, 2.5, 0.18914969879695093477606645992572208111152994999076, 1e-10, cdf(0.1));
601 test_case(-0.1, 2.5, 0.40622798321378106125020505907901206714868922279347, cdf(0.5));
602 test_case(-0.1, 2.5, 0.48035707589956665425068652807400957345208517749893, cdf(0.8));
603 test_almost(1.5, 0.1, 0.0, 1e-315, cdf(0.1));
604 test_almost(1.5, 0.1, 0.0, 1e-106, cdf(0.5));
605 test_almost(1.5, 0.1, 0.0, 1e-66, cdf(0.8));
606 test_almost(1.5, 1.5, 0.005621455876973168709588070988239748831823850202953, 1e-12, cdf(0.1));
607 test_almost(1.5, 1.5, 0.07185716187918271235246980951571040808235628115265, 1e-11, cdf(0.5));
608 test_almost(1.5, 1.5, 0.12532699044614938400496547188720940854423187977236, 1e-11, cdf(0.8));
609 test_almost(1.5, 2.5, 0.064125647996943514411570834861724406903677144126117, 1e-11, cdf(0.1));
610 test_almost(1.5, 2.5, 0.19017302281590810871719754032332631806011441356498, 1e-10, cdf(0.5));
611 test_almost(1.5, 2.5, 0.24533064397555500690927047163085419096928289095201, 1e-16, cdf(0.8));
612 test_case(2.5, 0.1, 0.0, cdf(0.1));
613 test_almost(2.5, 0.1, 0.0, 1e-223, cdf(0.5));
614 test_almost(2.5, 0.1, 0.0, 1e-162, cdf(0.8));
615 test_almost(2.5, 1.5, 0.00068304052220788502001572635016579586444611070077399, 1e-13, cdf(0.1));
616 test_almost(2.5, 1.5, 0.016636862816580533038130583128179878924863968664206, 1e-12, cdf(0.5));
617 test_almost(2.5, 1.5, 0.034729001282904174941366974418836262996834852343018, 1e-11, cdf(0.8));
618 test_almost(2.5, 2.5, 0.027363708266690978870139978537188410215717307180775, 1e-11, cdf(0.1));
619 test_almost(2.5, 2.5, 0.10075543423327634536450625420610429181921642201567, 1e-11, cdf(0.5));
620 test_almost(2.5, 2.5, 0.13802019192453118732001307556787218421918336849121, 1e-11, cdf(0.8));
621 }
622
623 #[test]
624 fn test_sf() {
625 let sf = |arg: f64| move |x: LogNormal| x.sf(arg);
626
627 test_almost(-0.1, 0.1, 1.0, 1e-107, sf(0.1));
629
630 test_almost(-0.1, 0.1, 0.890919989231123, 1e-14, sf(0.8));
632
633 test_almost(1.5, 1.0, 0.957568715612642, 1e-14, sf(0.8));
635
636 test_almost(2.5, 1.5, 0.9993169594777358, 1e-14, sf(0.1));
638 }
639
640 #[test]
641 fn test_neg_cdf() {
642 let cdf = |arg: f64| move |x: LogNormal| x.cdf(arg);
643 test_case(0.0, 1.0, 0.0, cdf(0.0));
644 }
645
646
647 #[test]
648 fn test_neg_sf() {
649 let sf = |arg: f64| move |x: LogNormal| x.sf(arg);
650 test_case(0.0, 1.0, 1.0, sf(0.0));
651 }
652
653 #[test]
654 fn test_continuous() {
655 test::check_continuous_distribution(&try_create(0.0, 0.25), 0.0, 10.0);
656 test::check_continuous_distribution(&try_create(0.0, 0.5), 0.0, 10.0);
657 }
658}