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