amalie 0.1.2

Mathmatical library written for rust and python
Documentation
use crate::unit::zz::py::*;
use pyo3::{PyAny, Bound, PyResult, wrap_pyfunction, pyfunction};
use pyo3::types::PyModule;
use pyo3::prelude::{PyModuleMethods, PyAnyMethods};
use num::BigInt;

pub fn py_alg(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(gcd, m)?)?;
    m.add_function(wrap_pyfunction!(egcd, m)?)?;
    m.add_function(wrap_pyfunction!(crt, m)?)?;
    m.add_function(wrap_pyfunction!(mod_inv, m)?)?;
    m.add_function(wrap_pyfunction!(totient, m)?)?;
    m.add_function(wrap_pyfunction!(is_prime, m)?)?;
    Ok(())
}

fn pyany_to_zz(value: &Bound<'_, PyAny>) -> PyResult<crate::ZZ> {
    if value.is_instance_of::<ZZ>() {
        let value: ZZ = value.extract()?;
        return Ok(value.v);
    }
    else {
        let value: BigInt = value.extract()?;
        let value: crate::ZZ = value.into();
        return Ok(value);
    }
}
fn pyany_to_veczz(value: &Vec<Bound<'_, PyAny>>) -> PyResult<Vec<crate::ZZ>> {
    let mut out = Vec::with_capacity(value.len());
    for x in value {
        out.push(pyany_to_zz(x)?);
    }
    Ok(out)
}

#[pyfunction]
fn gcd(a: Bound<'_, PyAny>, b: Bound<'_, PyAny>) -> PyResult<ZZ> {
    let a = pyany_to_zz(&a)?;
    let b = pyany_to_zz(&b)?;
    let v = crate::gcd(a, b);
    Ok(ZZ{v})
}
#[pyfunction]
fn egcd(a: Bound<'_, PyAny>, b: Bound<'_, PyAny>) -> PyResult<(ZZ, ZZ, ZZ)> {
    let a = pyany_to_zz(&a)?;
    let b = pyany_to_zz(&b)?;
    let (m, a, b) = crate::egcd(a, b);
    Ok((ZZ{v:m}, ZZ{v:a}, ZZ{v:b}))
}
#[pyfunction]
fn crt(v: Vec<Bound<'_, PyAny>>, m: Vec<Bound<'_, PyAny>>) -> PyResult<(ZZ, ZZ)> {
    let v = pyany_to_veczz(&v)?;
    let m = pyany_to_veczz(&m)?;
    let (v, n) = crate::crt(v, m);
    Ok((ZZ{v}, ZZ{v: n}))
}
#[pyfunction]
fn mod_inv(g: Bound<'_, PyAny>, exp: Bound<'_, PyAny>) -> PyResult<ZZ> {
    let g = pyany_to_zz(&g)?;
    let exp = pyany_to_zz(&exp)?;
    Ok(ZZ{v: crate::mod_inv(g, exp).expect("Could not compute the modular inverse")})
}
#[pyfunction]
fn totient(factors: Vec<Bound<'_, PyAny>>) -> PyResult<ZZ> {
    let factors = pyany_to_veczz(&factors)?;
    Ok(ZZ{v: crate::totient(factors)})
}
#[pyfunction]
fn is_prime(n: Bound<'_, PyAny>) -> PyResult<bool> {
    let n = pyany_to_zz(&n)?;
    Ok(crate::is_prime(n))
}
#[pyfunction]
fn pollard_rho(n: Bound<'_, PyAny>) -> PyResult<ZZ> {
    let n = pyany_to_zz(&n)?;
    Ok(ZZ{ v: crate::pollard_rho(n)? })
}