1use pyo3::prelude::*;
6use scirs2_core::python::numpy_compat::{scirs_to_numpy_array1, Array1};
7use scirs2_numpy::{PyArray1, PyReadonlyArray1};
8
9use scirs2_special::gamma::polygamma;
11use scirs2_special::{bessel, erf as erf_mod, gamma as gamma_fn};
12
13#[pyfunction]
19fn gamma_py(x: f64) -> PyResult<f64> {
20 Ok(gamma_fn(x))
21}
22
23#[pyfunction]
25fn lgamma_py(x: f64) -> PyResult<f64> {
26 Ok(scirs2_special::gamma::gammaln(x))
27}
28
29#[pyfunction]
31fn digamma_py(x: f64) -> PyResult<f64> {
32 Ok(scirs2_special::gamma::digamma(x))
33}
34
35#[pyfunction]
37fn beta_py(a: f64, b: f64) -> PyResult<f64> {
38 Ok(scirs2_special::gamma::beta(a, b))
39}
40
41#[pyfunction]
47fn j0_py(x: f64) -> PyResult<f64> {
48 Ok(bessel::j0(x))
49}
50
51#[pyfunction]
53fn j1_py(x: f64) -> PyResult<f64> {
54 Ok(bessel::j1(x))
55}
56
57#[pyfunction]
59fn jn_py(n: i32, x: f64) -> PyResult<f64> {
60 Ok(bessel::jn(n, x))
61}
62
63#[pyfunction]
65fn y0_py(x: f64) -> PyResult<f64> {
66 Ok(bessel::y0(x))
67}
68
69#[pyfunction]
71fn y1_py(x: f64) -> PyResult<f64> {
72 Ok(bessel::y1(x))
73}
74
75#[pyfunction]
77fn yn_py(n: i32, x: f64) -> PyResult<f64> {
78 Ok(bessel::yn(n, x))
79}
80
81#[pyfunction]
83fn i0_py(x: f64) -> PyResult<f64> {
84 Ok(bessel::i0(x))
85}
86
87#[pyfunction]
89fn i1_py(x: f64) -> PyResult<f64> {
90 Ok(bessel::i1(x))
91}
92
93#[pyfunction]
95fn k0_py(x: f64) -> PyResult<f64> {
96 Ok(bessel::k0(x))
97}
98
99#[pyfunction]
101fn k1_py(x: f64) -> PyResult<f64> {
102 Ok(bessel::k1(x))
103}
104
105#[pyfunction]
111fn erf_py(x: f64) -> PyResult<f64> {
112 Ok(erf_mod::erf(x))
113}
114
115#[pyfunction]
117fn erfc_py(x: f64) -> PyResult<f64> {
118 Ok(erf_mod::erfc(x))
119}
120
121#[pyfunction]
123fn erfinv_py(x: f64) -> PyResult<f64> {
124 Ok(erf_mod::erfinv(x))
125}
126
127#[pyfunction]
129fn erfcinv_py(x: f64) -> PyResult<f64> {
130 Ok(erf_mod::erfcinv(x))
131}
132
133#[pyfunction]
135fn erfcx_py(x: f64) -> PyResult<f64> {
136 Ok(erf_mod::erfcx(x))
137}
138
139#[pyfunction]
141fn erfi_py(x: f64) -> PyResult<f64> {
142 Ok(erf_mod::erfi(x))
143}
144
145#[pyfunction]
147fn dawsn_py(x: f64) -> PyResult<f64> {
148 Ok(erf_mod::dawsn(x))
149}
150
151#[pyfunction]
157fn factorial_py(n: u32) -> PyResult<f64> {
158 scirs2_special::factorial(n)
159 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
160}
161
162#[pyfunction]
164fn comb_py(n: u32, k: u32) -> PyResult<f64> {
165 scirs2_special::comb(n, k)
166 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
167}
168
169#[pyfunction]
171fn perm_py(n: u32, k: u32) -> PyResult<f64> {
172 scirs2_special::perm(n, k)
173 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
174}
175
176#[pyfunction]
182fn ellipk_py(m: f64) -> PyResult<f64> {
183 Ok(scirs2_special::elliptic_k(m))
184}
185
186#[pyfunction]
188fn ellipe_py(m: f64) -> PyResult<f64> {
189 Ok(scirs2_special::elliptic_e(m))
190}
191
192#[pyfunction]
194fn ellipkinc_py(phi: f64, m: f64) -> PyResult<f64> {
195 Ok(scirs2_special::elliptic_f(phi, m))
196}
197
198#[pyfunction]
200fn ellipeinc_py(phi: f64, m: f64) -> PyResult<f64> {
201 Ok(scirs2_special::elliptic_e_inc(phi, m))
202}
203
204#[pyfunction]
210fn polygamma_py(n: u32, x: f64) -> PyResult<f64> {
211 Ok(polygamma(n, x))
212}
213
214#[pyfunction]
220fn zeta_py(s: f64) -> PyResult<f64> {
221 scirs2_special::zeta(s).map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
222}
223
224#[pyfunction]
226fn hurwitz_zeta_py(s: f64, q: f64) -> PyResult<f64> {
227 scirs2_special::hurwitz_zeta(s, q)
228 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
229}
230
231#[pyfunction]
233fn zetac_py(s: f64) -> PyResult<f64> {
234 scirs2_special::zetac(s).map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
235}
236
237#[pyfunction]
243fn hyp0f1_py(v: f64, z: f64) -> PyResult<f64> {
244 scirs2_special::hyp0f1(v, z)
245 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
246}
247
248#[pyfunction]
250fn hyp1f1_py(a: f64, b: f64, z: f64) -> PyResult<f64> {
251 scirs2_special::hyp1f1(a, b, z)
252 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
253}
254
255#[pyfunction]
257fn hyp2f1_py(a: f64, b: f64, c: f64, z: f64) -> PyResult<f64> {
258 scirs2_special::hyp2f1(a, b, c, z)
259 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
260}
261
262#[pyfunction]
264fn hyperu_py(a: f64, b: f64, x: f64) -> PyResult<f64> {
265 scirs2_special::hyperu(a, b, x)
266 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
267}
268
269#[pyfunction]
275fn airy_ai_py(x: f64) -> PyResult<f64> {
276 Ok(scirs2_special::ai(x))
277}
278
279#[pyfunction]
281fn airy_aip_py(x: f64) -> PyResult<f64> {
282 Ok(scirs2_special::aip(x))
283}
284
285#[pyfunction]
287fn airy_bi_py(x: f64) -> PyResult<f64> {
288 Ok(scirs2_special::bi(x))
289}
290
291#[pyfunction]
293fn airy_bip_py(x: f64) -> PyResult<f64> {
294 Ok(scirs2_special::bip(x))
295}
296
297#[pyfunction]
303fn sici_si_py(x: f64) -> PyResult<f64> {
304 scirs2_special::si(x).map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
305}
306
307#[pyfunction]
309fn sici_ci_py(x: f64) -> PyResult<f64> {
310 scirs2_special::ci(x).map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
311}
312
313#[pyfunction]
315fn shichi_shi_py(x: f64) -> PyResult<f64> {
316 scirs2_special::shi(x).map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
317}
318
319#[pyfunction]
321fn shichi_chi_py(x: f64) -> PyResult<f64> {
322 scirs2_special::chi(x).map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
323}
324
325#[pyfunction]
331fn betainc_py(a: f64, b: f64, x: f64) -> PyResult<f64> {
332 scirs2_special::gamma::betainc_regularized(a, b, x)
333 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
334}
335
336#[pyfunction]
338fn betaincinv_py(a: f64, b: f64, p: f64) -> PyResult<f64> {
339 scirs2_special::gamma::betaincinv(a, b, p)
340 .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{e}")))
341}
342
343#[pyfunction]
349fn gamma_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
350 let input = x.as_array();
351 let output: Vec<f64> = input.iter().map(|&v| gamma_fn(v)).collect();
352 scirs_to_numpy_array1(Array1::from_vec(output), py)
353}
354
355#[pyfunction]
357fn erf_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
358 let input = x.as_array();
359 let output: Vec<f64> = input.iter().map(|&v| erf_mod::erf(v)).collect();
360 scirs_to_numpy_array1(Array1::from_vec(output), py)
361}
362
363#[pyfunction]
365fn j0_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
366 let input = x.as_array();
367 let output: Vec<f64> = input.iter().map(|&v| bessel::j0(v)).collect();
368 scirs_to_numpy_array1(Array1::from_vec(output), py)
369}
370
371#[pyfunction]
373fn lgamma_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
374 let input = x.as_array();
375 let output: Vec<f64> = input
376 .iter()
377 .map(|&v| scirs2_special::gamma::gammaln(v))
378 .collect();
379 scirs_to_numpy_array1(Array1::from_vec(output), py)
380}
381
382#[pyfunction]
384fn erfc_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
385 let input = x.as_array();
386 let output: Vec<f64> = input.iter().map(|&v| erf_mod::erfc(v)).collect();
387 scirs_to_numpy_array1(Array1::from_vec(output), py)
388}
389
390#[pyfunction]
392fn digamma_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
393 let input = x.as_array();
394 let output: Vec<f64> = input
395 .iter()
396 .map(|&v| scirs2_special::gamma::digamma(v))
397 .collect();
398 scirs_to_numpy_array1(Array1::from_vec(output), py)
399}
400
401#[pyfunction]
403fn j1_array_py(py: Python, x: PyReadonlyArray1<f64>) -> PyResult<Py<PyArray1<f64>>> {
404 let input = x.as_array();
405 let output: Vec<f64> = input.iter().map(|&v| bessel::j1(v)).collect();
406 scirs_to_numpy_array1(Array1::from_vec(output), py)
407}
408
409pub fn register_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
411 m.add_function(wrap_pyfunction!(gamma_py, m)?)?;
413 m.add_function(wrap_pyfunction!(lgamma_py, m)?)?;
414 m.add_function(wrap_pyfunction!(digamma_py, m)?)?;
415 m.add_function(wrap_pyfunction!(beta_py, m)?)?;
416
417 m.add_function(wrap_pyfunction!(j0_py, m)?)?;
419 m.add_function(wrap_pyfunction!(j1_py, m)?)?;
420 m.add_function(wrap_pyfunction!(jn_py, m)?)?;
421 m.add_function(wrap_pyfunction!(y0_py, m)?)?;
422 m.add_function(wrap_pyfunction!(y1_py, m)?)?;
423 m.add_function(wrap_pyfunction!(yn_py, m)?)?;
424 m.add_function(wrap_pyfunction!(i0_py, m)?)?;
425 m.add_function(wrap_pyfunction!(i1_py, m)?)?;
426 m.add_function(wrap_pyfunction!(k0_py, m)?)?;
427 m.add_function(wrap_pyfunction!(k1_py, m)?)?;
428
429 m.add_function(wrap_pyfunction!(erf_py, m)?)?;
431 m.add_function(wrap_pyfunction!(erfc_py, m)?)?;
432 m.add_function(wrap_pyfunction!(erfinv_py, m)?)?;
433 m.add_function(wrap_pyfunction!(erfcinv_py, m)?)?;
434 m.add_function(wrap_pyfunction!(erfcx_py, m)?)?;
435 m.add_function(wrap_pyfunction!(erfi_py, m)?)?;
436 m.add_function(wrap_pyfunction!(dawsn_py, m)?)?;
437
438 m.add_function(wrap_pyfunction!(factorial_py, m)?)?;
440 m.add_function(wrap_pyfunction!(comb_py, m)?)?;
441 m.add_function(wrap_pyfunction!(perm_py, m)?)?;
442
443 m.add_function(wrap_pyfunction!(ellipk_py, m)?)?;
445 m.add_function(wrap_pyfunction!(ellipe_py, m)?)?;
446 m.add_function(wrap_pyfunction!(ellipkinc_py, m)?)?;
447 m.add_function(wrap_pyfunction!(ellipeinc_py, m)?)?;
448
449 m.add_function(wrap_pyfunction!(polygamma_py, m)?)?;
451
452 m.add_function(wrap_pyfunction!(zeta_py, m)?)?;
454 m.add_function(wrap_pyfunction!(hurwitz_zeta_py, m)?)?;
455 m.add_function(wrap_pyfunction!(zetac_py, m)?)?;
456
457 m.add_function(wrap_pyfunction!(hyp0f1_py, m)?)?;
459 m.add_function(wrap_pyfunction!(hyp1f1_py, m)?)?;
460 m.add_function(wrap_pyfunction!(hyp2f1_py, m)?)?;
461 m.add_function(wrap_pyfunction!(hyperu_py, m)?)?;
462
463 m.add_function(wrap_pyfunction!(airy_ai_py, m)?)?;
465 m.add_function(wrap_pyfunction!(airy_aip_py, m)?)?;
466 m.add_function(wrap_pyfunction!(airy_bi_py, m)?)?;
467 m.add_function(wrap_pyfunction!(airy_bip_py, m)?)?;
468
469 m.add_function(wrap_pyfunction!(sici_si_py, m)?)?;
471 m.add_function(wrap_pyfunction!(sici_ci_py, m)?)?;
472 m.add_function(wrap_pyfunction!(shichi_shi_py, m)?)?;
473 m.add_function(wrap_pyfunction!(shichi_chi_py, m)?)?;
474
475 m.add_function(wrap_pyfunction!(betainc_py, m)?)?;
477 m.add_function(wrap_pyfunction!(betaincinv_py, m)?)?;
478
479 m.add_function(wrap_pyfunction!(gamma_array_py, m)?)?;
481 m.add_function(wrap_pyfunction!(lgamma_array_py, m)?)?;
482 m.add_function(wrap_pyfunction!(erf_array_py, m)?)?;
483 m.add_function(wrap_pyfunction!(erfc_array_py, m)?)?;
484 m.add_function(wrap_pyfunction!(digamma_array_py, m)?)?;
485 m.add_function(wrap_pyfunction!(j0_array_py, m)?)?;
486 m.add_function(wrap_pyfunction!(j1_array_py, m)?)?;
487
488 Ok(())
489}