use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use pyo3::types::IntoPyDict;
use oat_rust::algebra::chains::barcode::Bar;
use oat_rust::utilities::optimization::minimize_l1::minimize_l1;
use oat_rust::topology::simplicial::simplices::filtered::SimplexFiltered;
use itertools::Itertools;
use num::rational::Ratio;
use ordered_float::OrderedFloat;
use std::fmt::Debug;
use std::hash::Hash;
#[pyclass]
#[derive(Clone)]
pub struct SimplexFilteredPy{ simplex: SimplexFiltered<OrderedFloat<f64>> }
#[pymethods]
impl SimplexFilteredPy {
pub fn filtration( &self ) -> f64 { self.simplex.filtration().clone().into_inner() }
pub fn vertices( &self ) -> Vec<u16> { self.simplex.vertices().clone() }
pub fn dimension( &self ) -> usize { self.simplex.dimension() }
}
impl SimplexFilteredPy {
pub fn simplex( &self ) -> &SimplexFiltered<OrderedFloat<f64>> { &self.simplex }
pub fn new( simplex: SimplexFiltered<OrderedFloat<f64>> ) -> SimplexFilteredPy
{ SimplexFilteredPy{ simplex } }
}
pub fn convert_chain_to_python( chain: & Vec< (SimplexFiltered< OrderedFloat<f64> >, Ratio<isize> ) > )
->
Vec< ( SimplexFilteredPy, (isize, isize) ) > {
chain.iter()
.map(|x|
(
SimplexFilteredPy::new( x.0.clone() ),
(x.1.numer().clone(), x.1.denom().clone())
)
)
.collect_vec()
}
#[pyclass]
#[derive(Clone,Debug)]
pub struct BarPySimplexFilteredRational{
bar: Bar<
SimplexFiltered< OrderedFloat< f64 > >,
( SimplexFiltered< OrderedFloat< f64 > >, Ratio<isize> )
>
}
#[pymethods]
impl BarPySimplexFilteredRational{
pub fn id_number(&self) -> usize { self.bar.id_number().clone() }
#[pyo3(text_signature = "($self)")]
pub fn dimension(&self) -> isize { self.bar.dimension() }
#[pyo3(text_signature = "($self)")]
pub fn birth(&self) -> f64 { self.bar.birth_f64() }
#[pyo3(text_signature = "($self)")]
pub fn death(&self) -> f64 { self.bar.death_f64() }
#[pyo3(text_signature = "($self)")]
pub fn birth_column(&self) -> SimplexFilteredPy { SimplexFilteredPy::new( self.bar.birth_column().clone() ) }
#[pyo3(text_signature = "($self)")]
pub fn death_column(&self) -> Option< SimplexFilteredPy > { self.bar.death_column().clone().map(|x| SimplexFilteredPy::new(x) ) }
#[pyo3(text_signature = "($self)")]
pub fn cycle_representative(&self) -> Option< Vec< ( SimplexFilteredPy, (isize, isize) ) > > {
self.bar.cycle_representative().clone().map(|x| convert_chain_to_python(&x) )
}
#[pyo3(text_signature = "($self)")]
pub fn bounding_chain(&self) -> Option< Vec< ( SimplexFilteredPy, (isize, isize) ) > > {
self.bar.bounding_chain().clone().map(|x| convert_chain_to_python(&x) )
}
}
impl BarPySimplexFilteredRational{
pub fn peek(&self) -> &Bar<
SimplexFiltered< OrderedFloat< f64 > >,
( SimplexFiltered< OrderedFloat< f64 > >, Ratio<isize> )
>
{ & self.bar }
pub fn disolve( self )
->
Bar<
SimplexFiltered< OrderedFloat< f64 > >,
( SimplexFiltered< OrderedFloat< f64 > >, Ratio<isize> )
>
{ self.bar }
}
#[pyclass]
#[derive(Clone)]
pub struct BarcodePySimplexFilteredRational{
barcode: oat_rust::algebra::chains::barcode::Barcode<
SimplexFiltered< OrderedFloat< f64 > >,
( SimplexFiltered< OrderedFloat< f64 > >, Ratio<isize> )
>
}
impl BarcodePySimplexFilteredRational{
pub fn new( barcode: oat_rust::algebra::chains::barcode::Barcode<
SimplexFiltered< OrderedFloat< f64 > >,
( SimplexFiltered< OrderedFloat< f64 > >, Ratio<isize> )
>
) -> Self {
BarcodePySimplexFilteredRational{ barcode }
}
}
#[pymethods]
impl BarcodePySimplexFilteredRational{
#[new]
pub fn py_new( list: Vec< BarPySimplexFilteredRational > ) -> Self {
let barcode
= oat_rust::algebra::chains::barcode::Barcode::new(
list.into_iter().map(|x| x.disolve() )
);
BarcodePySimplexFilteredRational{ barcode }
}
#[pyo3( signature = ( bar_id_number, / )) ]
pub fn bar(&self, bar_id_number: usize ) -> PyResult< BarPySimplexFilteredRational > {
Ok( BarPySimplexFilteredRational{ bar: self.barcode.bar(bar_id_number).clone() } )
}
pub fn bars( &self ) -> Vec< BarPySimplexFilteredRational > {
self.barcode.iter().map(|x| BarPySimplexFilteredRational{ bar: x.clone() } ).collect()
}
#[args( bar_id_number = "0", )]
pub fn bars_in_dim( &self, dim: isize ) -> Vec< BarPySimplexFilteredRational > {
self.barcode.iter().filter(|x| x.dimension()==dim ).map(|x| BarPySimplexFilteredRational{ bar: x.clone() } ).collect()
}
pub fn intervals( &self, dim: isize) -> Vec< (f64, f64, usize ) > {
self.barcode.intervals_f64( dim )
}
pub fn betti_curve( &self, dim: isize ) -> Vec< ( f64, usize ) > {
self.barcode.betti_curve(dim).into_iter().map(|x| (x.0.into_inner(), x.1)).collect_vec()
}
pub fn endpoints( &self ) -> Vec< f64 >{
self.barcode.endpoints_ordf64().into_iter().map(|x|x.into_inner()).collect_vec()
}
pub fn max_finite_endpoint( &self ) -> Option<f64> {
self.barcode.max_finite_endpoint().map(|x| x.into_inner())
}
pub fn max_finite_endpoint_or( &self, default: f64 ) -> f64 {
self.barcode.max_finite_endpoint().map(|x| x.into_inner()).unwrap_or( default )
}
}