1use pyo3::prelude::*;
6use scirs2_core::python::numpy_compat::{scirs_to_numpy_array1, Array1};
7use scirs2_numpy::{PyArray1, PyReadonlyArray1};
8
9use scirs2_special::{bessel, erf as erf_mod, gamma as gamma_fn};
11
12#[pyfunction]
18fn gamma_py(x: f64) -> PyResult<f64> {
19 Ok(gamma_fn(x))
20}
21
22#[pyfunction]
24fn lgamma_py(x: f64) -> PyResult<f64> {
25 Ok(scirs2_special::gamma::gammaln(x))
26}
27
28#[pyfunction]
30fn digamma_py(x: f64) -> PyResult<f64> {
31 Ok(scirs2_special::gamma::digamma(x))
32}
33
34#[pyfunction]
36fn beta_py(a: f64, b: f64) -> PyResult<f64> {
37 Ok(scirs2_special::gamma::beta(a, b))
38}
39
40#[pyfunction]
46fn j0_py(x: f64) -> PyResult<f64> {
47 Ok(bessel::j0(x))
48}
49
50#[pyfunction]
52fn j1_py(x: f64) -> PyResult<f64> {
53 Ok(bessel::j1(x))
54}
55
56#[pyfunction]
58fn jn_py(n: i32, x: f64) -> PyResult<f64> {
59 Ok(bessel::jn(n, x))
60}
61
62#[pyfunction]
64fn y0_py(x: f64) -> PyResult<f64> {
65 Ok(bessel::y0(x))
66}
67
68#[pyfunction]
70fn y1_py(x: f64) -> PyResult<f64> {
71 Ok(bessel::y1(x))
72}
73
74#[pyfunction]
76fn yn_py(n: i32, x: f64) -> PyResult<f64> {
77 Ok(bessel::yn(n, x))
78}
79
80#[pyfunction]
82fn i0_py(x: f64) -> PyResult<f64> {
83 Ok(bessel::i0(x))
84}
85
86#[pyfunction]
88fn i1_py(x: f64) -> PyResult<f64> {
89 Ok(bessel::i1(x))
90}
91
92#[pyfunction]
94fn k0_py(x: f64) -> PyResult<f64> {
95 Ok(bessel::k0(x))
96}
97
98#[pyfunction]
100fn k1_py(x: f64) -> PyResult<f64> {
101 Ok(bessel::k1(x))
102}
103
104#[pyfunction]
110fn erf_py(x: f64) -> PyResult<f64> {
111 Ok(erf_mod::erf(x))
112}
113
114#[pyfunction]
116fn erfc_py(x: f64) -> PyResult<f64> {
117 Ok(erf_mod::erfc(x))
118}
119
120#[pyfunction]
122fn erfinv_py(x: f64) -> PyResult<f64> {
123 Ok(erf_mod::erfinv(x))
124}
125
126#[pyfunction]
128fn erfcinv_py(x: f64) -> PyResult<f64> {
129 Ok(erf_mod::erfcinv(x))
130}
131
132#[pyfunction]
134fn erfcx_py(x: f64) -> PyResult<f64> {
135 Ok(erf_mod::erfcx(x))
136}
137
138#[pyfunction]
140fn erfi_py(x: f64) -> PyResult<f64> {
141 Ok(erf_mod::erfi(x))
142}
143
144#[pyfunction]
146fn dawsn_py(x: f64) -> PyResult<f64> {
147 Ok(erf_mod::dawsn(x))
148}
149
150#[pyfunction]
156fn factorial_py(n: u32) -> PyResult<f64> {
157 scirs2_special::factorial(n)
158 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
159}
160
161#[pyfunction]
163fn comb_py(n: u32, k: u32) -> PyResult<f64> {
164 scirs2_special::comb(n, k)
165 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
166}
167
168#[pyfunction]
170fn perm_py(n: u32, k: u32) -> PyResult<f64> {
171 scirs2_special::perm(n, k)
172 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
173}
174
175#[pyfunction]
181fn ellipk_py(m: f64) -> PyResult<f64> {
182 Ok(scirs2_special::elliptic_k(m))
183}
184
185#[pyfunction]
187fn ellipe_py(m: f64) -> PyResult<f64> {
188 Ok(scirs2_special::elliptic_e(m))
189}
190
191#[pyfunction]
193fn ellipkinc_py(phi: f64, m: f64) -> PyResult<f64> {
194 Ok(scirs2_special::elliptic_f(phi, m))
195}
196
197#[pyfunction]
199fn ellipeinc_py(phi: f64, m: f64) -> PyResult<f64> {
200 Ok(scirs2_special::elliptic_e_inc(phi, m))
201}
202
203#[pyfunction]
209fn gamma_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
210 let input = x.as_array();
211 let output: Vec<f64> = input.iter().map(|&v| gamma_fn(v)).collect();
212 scirs_to_numpy_array1(Array1::from_vec(output), py)
213}
214
215#[pyfunction]
217fn erf_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
218 let input = x.as_array();
219 let output: Vec<f64> = input.iter().map(|&v| erf_mod::erf(v)).collect();
220 scirs_to_numpy_array1(Array1::from_vec(output), py)
221}
222
223#[pyfunction]
225fn j0_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
226 let input = x.as_array();
227 let output: Vec<f64> = input.iter().map(|&v| bessel::j0(v)).collect();
228 scirs_to_numpy_array1(Array1::from_vec(output), py)
229}
230
231pub fn register_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
233 m.add_function(wrap_pyfunction!(gamma_py, m)?)?;
235 m.add_function(wrap_pyfunction!(lgamma_py, m)?)?;
236 m.add_function(wrap_pyfunction!(digamma_py, m)?)?;
237 m.add_function(wrap_pyfunction!(beta_py, m)?)?;
238
239 m.add_function(wrap_pyfunction!(j0_py, m)?)?;
241 m.add_function(wrap_pyfunction!(j1_py, m)?)?;
242 m.add_function(wrap_pyfunction!(jn_py, m)?)?;
243 m.add_function(wrap_pyfunction!(y0_py, m)?)?;
244 m.add_function(wrap_pyfunction!(y1_py, m)?)?;
245 m.add_function(wrap_pyfunction!(yn_py, m)?)?;
246 m.add_function(wrap_pyfunction!(i0_py, m)?)?;
247 m.add_function(wrap_pyfunction!(i1_py, m)?)?;
248 m.add_function(wrap_pyfunction!(k0_py, m)?)?;
249 m.add_function(wrap_pyfunction!(k1_py, m)?)?;
250
251 m.add_function(wrap_pyfunction!(erf_py, m)?)?;
253 m.add_function(wrap_pyfunction!(erfc_py, m)?)?;
254 m.add_function(wrap_pyfunction!(erfinv_py, m)?)?;
255 m.add_function(wrap_pyfunction!(erfcinv_py, m)?)?;
256 m.add_function(wrap_pyfunction!(erfcx_py, m)?)?;
257 m.add_function(wrap_pyfunction!(erfi_py, m)?)?;
258 m.add_function(wrap_pyfunction!(dawsn_py, m)?)?;
259
260 m.add_function(wrap_pyfunction!(factorial_py, m)?)?;
262 m.add_function(wrap_pyfunction!(comb_py, m)?)?;
263 m.add_function(wrap_pyfunction!(perm_py, m)?)?;
264
265 m.add_function(wrap_pyfunction!(ellipk_py, m)?)?;
267 m.add_function(wrap_pyfunction!(ellipe_py, m)?)?;
268 m.add_function(wrap_pyfunction!(ellipkinc_py, m)?)?;
269 m.add_function(wrap_pyfunction!(ellipeinc_py, m)?)?;
270
271 m.add_function(wrap_pyfunction!(gamma_array_py, m)?)?;
273 m.add_function(wrap_pyfunction!(erf_array_py, m)?)?;
274 m.add_function(wrap_pyfunction!(j0_array_py, m)?)?;
275
276 Ok(())
277}