Skip to main content

scirs2/stats/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use pyo3::exceptions::PyRuntimeError;
6use pyo3::prelude::*;
7use scirs2_stats::distributions::bernoulli::Bernoulli as RustBernoulli;
8use scirs2_stats::distributions::beta::Beta as RustBeta;
9use scirs2_stats::distributions::binomial::Binomial as RustBinomial;
10use scirs2_stats::distributions::cauchy::Cauchy as RustCauchy;
11use scirs2_stats::distributions::chi_square::ChiSquare as RustChiSquare;
12use scirs2_stats::distributions::exponential::Exponential as RustExponential;
13use scirs2_stats::distributions::f::F as RustF;
14use scirs2_stats::distributions::gamma::Gamma as RustGamma;
15use scirs2_stats::distributions::geometric::Geometric as RustGeometric;
16use scirs2_stats::distributions::hypergeometric::Hypergeometric as RustHypergeometric;
17use scirs2_stats::distributions::laplace::Laplace as RustLaplace;
18use scirs2_stats::distributions::logistic::Logistic as RustLogistic;
19use scirs2_stats::distributions::lognormal::Lognormal as RustLognormal;
20use scirs2_stats::distributions::negative_binomial::NegativeBinomial as RustNegativeBinomial;
21use scirs2_stats::distributions::normal::Normal as RustNormal;
22use scirs2_stats::distributions::pareto::Pareto as RustPareto;
23use scirs2_stats::distributions::poisson::Poisson as RustPoisson;
24use scirs2_stats::distributions::student_t::StudentT as RustStudentT;
25use scirs2_stats::distributions::uniform::Uniform as RustUniform;
26use scirs2_stats::distributions::weibull::Weibull as RustWeibull;
27use scirs2_stats::{ContinuousDistribution, DiscreteDistribution};
28
29/// Chi-square distribution
30#[pyclass(name = "chi2")]
31pub struct PyChiSquare {
32    dist: RustChiSquare<f64>,
33}
34#[pymethods]
35impl PyChiSquare {
36    /// Create a new Chi-square distribution
37    ///
38    /// Parameters:
39    /// - df: Degrees of freedom > 0
40    /// - loc: Location parameter (default: 0.0)
41    /// - scale: Scale parameter (default: 1.0)
42    #[new]
43    #[pyo3(signature = (df, loc = 0.0, scale = 1.0))]
44    fn new(df: f64, loc: f64, scale: f64) -> PyResult<Self> {
45        let dist = RustChiSquare::new(df, loc, scale).map_err(|e| {
46            PyRuntimeError::new_err(format!("Chi-square distribution creation failed: {}", e))
47        })?;
48        Ok(PyChiSquare { dist })
49    }
50    /// Probability density function
51    fn pdf(&self, x: f64) -> f64 {
52        self.dist.pdf(x)
53    }
54    /// Cumulative distribution function
55    fn cdf(&self, x: f64) -> f64 {
56        self.dist.cdf(x)
57    }
58    /// Percent point function (inverse CDF)
59    fn ppf(&self, q: f64) -> PyResult<f64> {
60        self.dist
61            .ppf(q)
62            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
63    }
64    /// Random variates
65    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
66        let arr = self
67            .dist
68            .rvs(size)
69            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
70        Ok(arr.to_vec())
71    }
72}
73/// Binomial distribution
74#[pyclass(name = "binom")]
75pub struct PyBinomial {
76    dist: RustBinomial<f64>,
77}
78#[pymethods]
79impl PyBinomial {
80    /// Create a new Binomial distribution
81    ///
82    /// Parameters:
83    /// - n: Number of trials
84    /// - p: Probability of success
85    #[new]
86    fn new(n: usize, p: f64) -> PyResult<Self> {
87        let dist = RustBinomial::new(n, p).map_err(|e| {
88            PyRuntimeError::new_err(format!("Binomial distribution creation failed: {}", e))
89        })?;
90        Ok(PyBinomial { dist })
91    }
92    /// Probability mass function
93    fn pmf(&self, k: f64) -> f64 {
94        self.dist.pmf(k)
95    }
96    /// Cumulative distribution function
97    fn cdf(&self, k: f64) -> f64 {
98        self.dist.cdf(k)
99    }
100    /// Percent point function (inverse CDF)
101    fn ppf(&self, q: f64) -> PyResult<f64> {
102        self.dist
103            .ppf(q)
104            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
105    }
106    /// Random variates
107    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
108        let arr = self
109            .dist
110            .rvs(size)
111            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
112        Ok(arr.to_vec())
113    }
114}
115/// Geometric distribution
116#[pyclass(name = "geom")]
117pub struct PyGeometric {
118    dist: RustGeometric<f64>,
119}
120#[pymethods]
121impl PyGeometric {
122    /// Create a new Geometric distribution
123    ///
124    /// Parameters:
125    /// - p: Success probability, 0 < p <= 1
126    #[new]
127    fn new(p: f64) -> PyResult<Self> {
128        let dist = RustGeometric::new(p).map_err(|e| {
129            PyRuntimeError::new_err(format!("Geometric distribution creation failed: {}", e))
130        })?;
131        Ok(PyGeometric { dist })
132    }
133    /// Probability mass function
134    fn pmf(&self, k: f64) -> f64 {
135        self.dist.pmf(k)
136    }
137    /// Cumulative distribution function
138    fn cdf(&self, k: f64) -> f64 {
139        self.dist.cdf(k)
140    }
141    /// Percent point function (inverse CDF)
142    fn ppf(&self, q: f64) -> PyResult<f64> {
143        self.dist
144            .ppf(q)
145            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
146    }
147    /// Random variates
148    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
149        let arr = self
150            .dist
151            .rvs(size)
152            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
153        Ok(arr.to_vec())
154    }
155}
156/// Lognormal distribution
157#[pyclass(name = "lognorm")]
158pub struct PyLognormal {
159    dist: RustLognormal<f64>,
160}
161#[pymethods]
162impl PyLognormal {
163    /// Create a new Lognormal distribution
164    ///
165    /// Parameters:
166    /// - mu: Mean of underlying normal distribution (default: 0.0)
167    /// - sigma: Standard deviation of underlying normal distribution (default: 1.0)
168    /// - loc: Location parameter (default: 0.0)
169    #[new]
170    #[pyo3(signature = (mu = 0.0, sigma = 1.0, loc = 0.0))]
171    fn new(mu: f64, sigma: f64, loc: f64) -> PyResult<Self> {
172        let dist = RustLognormal::new(mu, sigma, loc).map_err(|e| {
173            PyRuntimeError::new_err(format!("Lognormal distribution creation failed: {}", e))
174        })?;
175        Ok(PyLognormal { dist })
176    }
177    /// Probability density function
178    fn pdf(&self, x: f64) -> f64 {
179        self.dist.pdf(x)
180    }
181    /// Cumulative distribution function
182    fn cdf(&self, x: f64) -> f64 {
183        self.dist.cdf(x)
184    }
185    /// Percent point function (inverse CDF)
186    fn ppf(&self, q: f64) -> PyResult<f64> {
187        self.dist
188            .ppf(q)
189            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
190    }
191    /// Random variates
192    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
193        let arr = self
194            .dist
195            .rvs(size)
196            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
197        Ok(arr.to_vec())
198    }
199}
200/// Weibull distribution
201#[pyclass(name = "weibull_min")]
202pub struct PyWeibull {
203    dist: RustWeibull<f64>,
204}
205#[pymethods]
206impl PyWeibull {
207    /// Create a new Weibull distribution
208    ///
209    /// Parameters:
210    /// - shape: Shape parameter k > 0
211    /// - scale: Scale parameter lambda > 0 (default: 1.0)
212    /// - loc: Location parameter (default: 0.0)
213    #[new]
214    #[pyo3(signature = (shape, scale = 1.0, loc = 0.0))]
215    fn new(shape: f64, scale: f64, loc: f64) -> PyResult<Self> {
216        let dist = RustWeibull::new(shape, scale, loc).map_err(|e| {
217            PyRuntimeError::new_err(format!("Weibull distribution creation failed: {}", e))
218        })?;
219        Ok(PyWeibull { dist })
220    }
221    /// Probability density function
222    fn pdf(&self, x: f64) -> f64 {
223        self.dist.pdf(x)
224    }
225    /// Cumulative distribution function
226    fn cdf(&self, x: f64) -> f64 {
227        self.dist.cdf(x)
228    }
229    /// Percent point function (inverse CDF)
230    fn ppf(&self, q: f64) -> PyResult<f64> {
231        self.dist
232            .ppf(q)
233            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
234    }
235    /// Random variates
236    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
237        let arr = self
238            .dist
239            .rvs(size)
240            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
241        Ok(arr.to_vec())
242    }
243}
244/// Gamma distribution
245#[pyclass(name = "gamma")]
246pub struct PyGamma {
247    dist: RustGamma<f64>,
248}
249#[pymethods]
250impl PyGamma {
251    /// Create a new Gamma distribution
252    ///
253    /// Parameters:
254    /// - shape: Shape parameter k > 0
255    /// - scale: Scale parameter theta > 0 (default: 1.0)
256    /// - loc: Location parameter (default: 0.0)
257    #[new]
258    #[pyo3(signature = (shape, scale = 1.0, loc = 0.0))]
259    fn new(shape: f64, scale: f64, loc: f64) -> PyResult<Self> {
260        let dist = RustGamma::new(shape, scale, loc).map_err(|e| {
261            PyRuntimeError::new_err(format!("Gamma distribution creation failed: {}", e))
262        })?;
263        Ok(PyGamma { dist })
264    }
265    /// Probability density function
266    fn pdf(&self, x: f64) -> f64 {
267        self.dist.pdf(x)
268    }
269    /// Cumulative distribution function
270    fn cdf(&self, x: f64) -> f64 {
271        self.dist.cdf(x)
272    }
273    /// Percent point function (inverse CDF)
274    fn ppf(&self, q: f64) -> PyResult<f64> {
275        self.dist
276            .ppf(q)
277            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
278    }
279    /// Random variates
280    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
281        let arr = self
282            .dist
283            .rvs(size)
284            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
285        Ok(arr.to_vec())
286    }
287}
288/// Logistic distribution
289#[pyclass(name = "logistic")]
290pub struct PyLogistic {
291    dist: RustLogistic<f64>,
292}
293#[pymethods]
294impl PyLogistic {
295    /// Create a new Logistic distribution
296    ///
297    /// Parameters:
298    /// - loc: Location parameter (default: 0.0)
299    /// - scale: Scale parameter > 0 (default: 1.0)
300    #[new]
301    #[pyo3(signature = (loc = 0.0, scale = 1.0))]
302    fn new(loc: f64, scale: f64) -> PyResult<Self> {
303        let dist = RustLogistic::new(loc, scale).map_err(|e| {
304            PyRuntimeError::new_err(format!("Logistic distribution creation failed: {}", e))
305        })?;
306        Ok(PyLogistic { dist })
307    }
308    /// Probability density function
309    fn pdf(&self, x: f64) -> f64 {
310        self.dist.pdf(x)
311    }
312    /// Cumulative distribution function
313    fn cdf(&self, x: f64) -> f64 {
314        self.dist.cdf(x)
315    }
316    /// Percent point function (inverse CDF)
317    fn ppf(&self, q: f64) -> PyResult<f64> {
318        self.dist
319            .ppf(q)
320            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
321    }
322    /// Random variates
323    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
324        let arr = self
325            .dist
326            .rvs(size)
327            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
328        Ok(arr.to_vec())
329    }
330}
331/// Poisson distribution
332#[pyclass(name = "poisson")]
333pub struct PyPoisson {
334    dist: RustPoisson<f64>,
335}
336#[pymethods]
337impl PyPoisson {
338    /// Create a new Poisson distribution
339    ///
340    /// Parameters:
341    /// - mu: Expected number of events (lambda parameter)
342    #[new]
343    fn new(mu: f64) -> PyResult<Self> {
344        let dist = RustPoisson::new(mu, 0.0).map_err(|e| {
345            PyRuntimeError::new_err(format!("Poisson distribution creation failed: {}", e))
346        })?;
347        Ok(PyPoisson { dist })
348    }
349    /// Probability mass function
350    fn pmf(&self, k: f64) -> f64 {
351        self.dist.pmf(k)
352    }
353    /// Cumulative distribution function
354    fn cdf(&self, k: f64) -> f64 {
355        self.dist.cdf(k)
356    }
357    /// Percent point function (inverse CDF)
358    fn ppf(&self, q: f64) -> PyResult<f64> {
359        self.dist
360            .ppf(q)
361            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
362    }
363    /// Random variates
364    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
365        let arr = self
366            .dist
367            .rvs(size)
368            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
369        Ok(arr.to_vec())
370    }
371}
372/// Student's t distribution
373#[pyclass(name = "t")]
374pub struct PyStudentT {
375    dist: RustStudentT<f64>,
376}
377#[pymethods]
378impl PyStudentT {
379    /// Create a new Student's t distribution
380    ///
381    /// Parameters:
382    /// - df: Degrees of freedom > 0
383    /// - loc: Location parameter (default: 0.0)
384    /// - scale: Scale parameter (default: 1.0)
385    #[new]
386    #[pyo3(signature = (df, loc = 0.0, scale = 1.0))]
387    fn new(df: f64, loc: f64, scale: f64) -> PyResult<Self> {
388        let dist = RustStudentT::new(df, loc, scale).map_err(|e| {
389            PyRuntimeError::new_err(format!("Student's t distribution creation failed: {}", e))
390        })?;
391        Ok(PyStudentT { dist })
392    }
393    /// Probability density function
394    fn pdf(&self, x: f64) -> f64 {
395        self.dist.pdf(x)
396    }
397    /// Cumulative distribution function
398    fn cdf(&self, x: f64) -> f64 {
399        self.dist.cdf(x)
400    }
401    /// Percent point function (inverse CDF)
402    fn ppf(&self, q: f64) -> PyResult<f64> {
403        self.dist
404            .ppf(q)
405            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
406    }
407    /// Random variates
408    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
409        let arr = self
410            .dist
411            .rvs(size)
412            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
413        Ok(arr.to_vec())
414    }
415}
416/// Pareto distribution
417#[pyclass(name = "pareto")]
418pub struct PyPareto {
419    dist: RustPareto<f64>,
420}
421#[pymethods]
422impl PyPareto {
423    /// Create a new Pareto distribution
424    ///
425    /// Parameters:
426    /// - shape: Shape parameter alpha > 0
427    /// - scale: Scale parameter x_m > 0 (default: 1.0)
428    /// - loc: Location parameter (default: 0.0)
429    #[new]
430    #[pyo3(signature = (shape, scale = 1.0, loc = 0.0))]
431    fn new(shape: f64, scale: f64, loc: f64) -> PyResult<Self> {
432        let dist = RustPareto::new(shape, scale, loc).map_err(|e| {
433            PyRuntimeError::new_err(format!("Pareto distribution creation failed: {}", e))
434        })?;
435        Ok(PyPareto { dist })
436    }
437    /// Probability density function
438    fn pdf(&self, x: f64) -> f64 {
439        self.dist.pdf(x)
440    }
441    /// Cumulative distribution function
442    fn cdf(&self, x: f64) -> f64 {
443        self.dist.cdf(x)
444    }
445    /// Percent point function (inverse CDF)
446    fn ppf(&self, q: f64) -> PyResult<f64> {
447        self.dist
448            .ppf(q)
449            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
450    }
451    /// Random variates
452    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
453        let arr = self
454            .dist
455            .rvs(size)
456            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
457        Ok(arr.to_vec())
458    }
459}
460/// Exponential distribution
461#[pyclass(name = "expon")]
462pub struct PyExponential {
463    dist: RustExponential<f64>,
464}
465#[pymethods]
466impl PyExponential {
467    /// Create a new Exponential distribution
468    ///
469    /// Parameters:
470    /// - scale: Scale parameter (1/lambda) (default: 1.0)
471    #[new]
472    #[pyo3(signature = (scale = 1.0))]
473    fn new(scale: f64) -> PyResult<Self> {
474        let rate = 1.0 / scale;
475        let dist = RustExponential::new(rate, 0.0).map_err(|e| {
476            PyRuntimeError::new_err(format!("Exponential distribution creation failed: {}", e))
477        })?;
478        Ok(PyExponential { dist })
479    }
480    /// Probability density function
481    fn pdf(&self, x: f64) -> f64 {
482        self.dist.pdf(x)
483    }
484    /// Cumulative distribution function
485    fn cdf(&self, x: f64) -> f64 {
486        self.dist.cdf(x)
487    }
488    /// Percent point function (inverse CDF)
489    fn ppf(&self, q: f64) -> PyResult<f64> {
490        self.dist
491            .ppf(q)
492            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
493    }
494    /// Random variates
495    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
496        let arr = self
497            .dist
498            .rvs(size)
499            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
500        Ok(arr.to_vec())
501    }
502}
503/// Beta distribution
504#[pyclass(name = "beta")]
505pub struct PyBeta {
506    dist: RustBeta<f64>,
507}
508#[pymethods]
509impl PyBeta {
510    /// Create a new Beta distribution
511    ///
512    /// Parameters:
513    /// - alpha: Shape parameter alpha > 0
514    /// - beta: Shape parameter beta > 0
515    /// - loc: Location parameter (default: 0.0)
516    /// - scale: Scale parameter (default: 1.0)
517    #[new]
518    #[pyo3(signature = (alpha, beta, loc = 0.0, scale = 1.0))]
519    fn new(alpha: f64, beta: f64, loc: f64, scale: f64) -> PyResult<Self> {
520        let dist = RustBeta::new(alpha, beta, loc, scale).map_err(|e| {
521            PyRuntimeError::new_err(format!("Beta distribution creation failed: {}", e))
522        })?;
523        Ok(PyBeta { dist })
524    }
525    /// Probability density function
526    fn pdf(&self, x: f64) -> f64 {
527        self.dist.pdf(x)
528    }
529    /// Cumulative distribution function
530    fn cdf(&self, x: f64) -> f64 {
531        self.dist.cdf(x)
532    }
533    /// Percent point function (inverse CDF)
534    fn ppf(&self, q: f64) -> PyResult<f64> {
535        self.dist
536            .ppf(q)
537            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
538    }
539    /// Random variates
540    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
541        let arr = self
542            .dist
543            .rvs(size)
544            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
545        Ok(arr.to_vec())
546    }
547}
548/// Normal (Gaussian) distribution
549#[pyclass(name = "norm")]
550pub struct PyNormal {
551    dist: RustNormal<f64>,
552}
553#[pymethods]
554impl PyNormal {
555    /// Create a new Normal distribution
556    ///
557    /// Parameters:
558    /// - loc: Mean (location) parameter (default: 0.0)
559    /// - scale: Standard deviation (scale) parameter (default: 1.0)
560    #[new]
561    #[pyo3(signature = (loc = 0.0, scale = 1.0))]
562    fn new(loc: f64, scale: f64) -> PyResult<Self> {
563        let dist = RustNormal::new(loc, scale).map_err(|e| {
564            PyRuntimeError::new_err(format!("Normal distribution creation failed: {}", e))
565        })?;
566        Ok(PyNormal { dist })
567    }
568    /// Probability density function
569    fn pdf(&self, x: f64) -> f64 {
570        self.dist.pdf(x)
571    }
572    /// Cumulative distribution function
573    fn cdf(&self, x: f64) -> f64 {
574        self.dist.cdf(x)
575    }
576    /// Percent point function (inverse CDF)
577    fn ppf(&self, q: f64) -> PyResult<f64> {
578        self.dist
579            .ppf(q)
580            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
581    }
582    /// Random variates
583    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
584        let arr = self
585            .dist
586            .rvs(size)
587            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
588        Ok(arr.to_vec())
589    }
590}
591/// Laplace distribution
592#[pyclass(name = "laplace")]
593pub struct PyLaplace {
594    dist: RustLaplace<f64>,
595}
596#[pymethods]
597impl PyLaplace {
598    /// Create a new Laplace distribution
599    ///
600    /// Parameters:
601    /// - loc: Location parameter (default: 0.0)
602    /// - scale: Scale parameter > 0 (default: 1.0)
603    #[new]
604    #[pyo3(signature = (loc = 0.0, scale = 1.0))]
605    fn new(loc: f64, scale: f64) -> PyResult<Self> {
606        let dist = RustLaplace::new(loc, scale).map_err(|e| {
607            PyRuntimeError::new_err(format!("Laplace distribution creation failed: {}", e))
608        })?;
609        Ok(PyLaplace { dist })
610    }
611    /// Probability density function
612    fn pdf(&self, x: f64) -> f64 {
613        self.dist.pdf(x)
614    }
615    /// Cumulative distribution function
616    fn cdf(&self, x: f64) -> f64 {
617        self.dist.cdf(x)
618    }
619    /// Percent point function (inverse CDF)
620    fn ppf(&self, q: f64) -> PyResult<f64> {
621        self.dist
622            .ppf(q)
623            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
624    }
625    /// Random variates
626    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
627        let arr = self
628            .dist
629            .rvs(size)
630            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
631        Ok(arr.to_vec())
632    }
633}
634/// Cauchy distribution
635#[pyclass(name = "cauchy")]
636pub struct PyCauchy {
637    dist: RustCauchy<f64>,
638}
639#[pymethods]
640impl PyCauchy {
641    /// Create a new Cauchy distribution
642    ///
643    /// Parameters:
644    /// - loc: Location parameter (default: 0.0)
645    /// - scale: Scale parameter > 0 (default: 1.0)
646    #[new]
647    #[pyo3(signature = (loc = 0.0, scale = 1.0))]
648    fn new(loc: f64, scale: f64) -> PyResult<Self> {
649        let dist = RustCauchy::new(loc, scale).map_err(|e| {
650            PyRuntimeError::new_err(format!("Cauchy distribution creation failed: {}", e))
651        })?;
652        Ok(PyCauchy { dist })
653    }
654    /// Probability density function
655    fn pdf(&self, x: f64) -> f64 {
656        self.dist.pdf(x)
657    }
658    /// Cumulative distribution function
659    fn cdf(&self, x: f64) -> f64 {
660        self.dist.cdf(x)
661    }
662    /// Percent point function (inverse CDF)
663    fn ppf(&self, q: f64) -> PyResult<f64> {
664        self.dist
665            .ppf(q)
666            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
667    }
668    /// Random variates
669    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
670        let arr = self
671            .dist
672            .rvs(size)
673            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
674        Ok(arr.to_vec())
675    }
676}
677/// F distribution
678#[pyclass(name = "f")]
679pub struct PyF {
680    dist: RustF<f64>,
681}
682#[pymethods]
683impl PyF {
684    /// Create a new F distribution
685    ///
686    /// Parameters:
687    /// - dfn: Numerator degrees of freedom > 0
688    /// - dfd: Denominator degrees of freedom > 0
689    /// - loc: Location parameter (default: 0.0)
690    /// - scale: Scale parameter (default: 1.0)
691    #[new]
692    #[pyo3(signature = (dfn, dfd, loc = 0.0, scale = 1.0))]
693    fn new(dfn: f64, dfd: f64, loc: f64, scale: f64) -> PyResult<Self> {
694        let dist = RustF::new(dfn, dfd, loc, scale).map_err(|e| {
695            PyRuntimeError::new_err(format!("F distribution creation failed: {}", e))
696        })?;
697        Ok(PyF { dist })
698    }
699    /// Probability density function
700    fn pdf(&self, x: f64) -> f64 {
701        self.dist.pdf(x)
702    }
703    /// Cumulative distribution function
704    fn cdf(&self, x: f64) -> f64 {
705        self.dist.cdf(x)
706    }
707    /// Random variates
708    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
709        let arr = self
710            .dist
711            .rvs(size)
712            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
713        Ok(arr.to_vec())
714    }
715}
716/// Uniform distribution
717#[pyclass(name = "uniform")]
718pub struct PyUniform {
719    dist: RustUniform<f64>,
720}
721#[pymethods]
722impl PyUniform {
723    /// Create a new Uniform distribution
724    ///
725    /// Parameters:
726    /// - loc: Lower bound (default: 0.0)
727    /// - scale: Width (upper - lower) (default: 1.0)
728    #[new]
729    #[pyo3(signature = (loc = 0.0, scale = 1.0))]
730    fn new(loc: f64, scale: f64) -> PyResult<Self> {
731        let dist = RustUniform::new(loc, loc + scale).map_err(|e| {
732            PyRuntimeError::new_err(format!("Uniform distribution creation failed: {}", e))
733        })?;
734        Ok(PyUniform { dist })
735    }
736    /// Probability density function
737    fn pdf(&self, x: f64) -> f64 {
738        self.dist.pdf(x)
739    }
740    /// Cumulative distribution function
741    fn cdf(&self, x: f64) -> f64 {
742        self.dist.cdf(x)
743    }
744    /// Percent point function (inverse CDF)
745    fn ppf(&self, q: f64) -> PyResult<f64> {
746        self.dist
747            .ppf(q)
748            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
749    }
750    /// Random variates
751    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
752        let arr = self
753            .dist
754            .rvs(size)
755            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
756        Ok(arr.to_vec())
757    }
758}
759
760/// Bernoulli distribution
761#[pyclass(name = "bernoulli")]
762pub struct PyBernoulli {
763    dist: RustBernoulli<f64>,
764}
765#[pymethods]
766impl PyBernoulli {
767    /// Create a new Bernoulli distribution
768    ///
769    /// Parameters:
770    /// - p: Success probability, 0 <= p <= 1
771    #[new]
772    fn new(p: f64) -> PyResult<Self> {
773        let dist = RustBernoulli::new(p).map_err(|e| {
774            PyRuntimeError::new_err(format!("Bernoulli distribution creation failed: {}", e))
775        })?;
776        Ok(PyBernoulli { dist })
777    }
778    /// Probability mass function
779    fn pmf(&self, k: f64) -> f64 {
780        self.dist.pmf(k)
781    }
782    /// Cumulative distribution function
783    fn cdf(&self, k: f64) -> f64 {
784        self.dist.cdf(k)
785    }
786    /// Percent point function (inverse CDF)
787    fn ppf(&self, p_val: f64) -> PyResult<f64> {
788        self.dist
789            .ppf(p_val)
790            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
791    }
792    /// Random variates
793    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
794        self.dist
795            .rvs(size)
796            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))
797    }
798}
799
800/// Negative Binomial distribution
801#[pyclass(name = "nbinom")]
802pub struct PyNegativeBinomial {
803    dist: RustNegativeBinomial<f64>,
804}
805#[pymethods]
806impl PyNegativeBinomial {
807    /// Create a new Negative Binomial distribution
808    ///
809    /// Parameters:
810    /// - n: Number of successes (r parameter), r > 0
811    /// - p: Success probability, 0 < p <= 1
812    #[new]
813    fn new(n: f64, p: f64) -> PyResult<Self> {
814        let dist = RustNegativeBinomial::new(n, p).map_err(|e| {
815            PyRuntimeError::new_err(format!(
816                "Negative Binomial distribution creation failed: {}",
817                e
818            ))
819        })?;
820        Ok(PyNegativeBinomial { dist })
821    }
822    /// Probability mass function
823    fn pmf(&self, k: f64) -> f64 {
824        self.dist.pmf(k)
825    }
826    /// Cumulative distribution function
827    fn cdf(&self, k: f64) -> f64 {
828        self.dist.cdf(k)
829    }
830    /// Percent point function (inverse CDF)
831    fn ppf(&self, pval: f64) -> PyResult<f64> {
832        self.dist
833            .ppf(pval)
834            .map_err(|e| PyRuntimeError::new_err(format!("PPF failed: {}", e)))
835    }
836    /// Random variates
837    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
838        self.dist
839            .rvs(size)
840            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))
841    }
842}
843
844/// Hypergeometric distribution
845#[pyclass(name = "hypergeom")]
846pub struct PyHypergeometric {
847    dist: RustHypergeometric<f64>,
848}
849#[pymethods]
850impl PyHypergeometric {
851    /// Create a new Hypergeometric distribution
852    ///
853    /// Parameters:
854    /// - m: Total population size
855    /// - n: Number of success states in population
856    /// - k: Number of draws
857    #[new]
858    fn new(m: usize, n: usize, k: usize) -> PyResult<Self> {
859        let dist = RustHypergeometric::new(m, n, k, 0.0_f64).map_err(|e| {
860            PyRuntimeError::new_err(format!(
861                "Hypergeometric distribution creation failed: {}",
862                e
863            ))
864        })?;
865        Ok(PyHypergeometric { dist })
866    }
867    /// Probability mass function
868    fn pmf(&self, x: f64) -> f64 {
869        self.dist.pmf(x)
870    }
871    /// Cumulative distribution function
872    fn cdf(&self, x: f64) -> f64 {
873        self.dist.cdf(x)
874    }
875    /// Random variates
876    fn rvs(&self, size: usize) -> PyResult<Vec<f64>> {
877        let arr = self
878            .dist
879            .rvs(size)
880            .map_err(|e| PyRuntimeError::new_err(format!("RVS failed: {}", e)))?;
881        Ok(arr.to_vec())
882    }
883}