use derive_getters::Dissolve;
use derive_new::new;
use itertools::Itertools;
use num::Bounded;
use ordered_float::OrderedFloat;
use pyo3::types::{PyDict, PyDictMethods};
use pyo3::{pyclass, IntoPyObject, Py, PyAny};
use crate::algebra::matrices::query::MatrixOracle;
use crate::algebra::rings::traits::RingOperations;
use crate::algebra::vectors::entries::KeyValNew;
use crate::topology::simplicial::from::graph_weighted::{AgileBoundaryIteratorLexicographicOrder, AgileCoboundaryIterartorLexicographicOrder, VietorisRipsComplex};
use crate::utilities::order::{JudgeOrder, JudgePartialOrder};
use std::cmp::Ordering;
use std::hash::Hash;
use std::fmt::Debug;
use std::sync::Arc;
type Vertex = u16;
#[derive(Clone,Debug,new)]
pub struct OrderOperatorTwistWeightedSimplex;
impl < FilVal: Ord + Clone + Debug >
JudgePartialOrder
< WeightedSimplex< FilVal > > for
OrderOperatorTwistWeightedSimplex
{
fn judge_partial_cmp( & self, lhs: &WeightedSimplex< FilVal >, rhs: &WeightedSimplex< FilVal > ) -> Option<Ordering> {
Some(self.judge_cmp(lhs,rhs))
}
}
impl < FilVal: Ord + Clone + Debug >
JudgeOrder
< WeightedSimplex< FilVal > > for
OrderOperatorTwistWeightedSimplex
{
fn judge_cmp( & self, lhs: &WeightedSimplex< FilVal >, rhs: &WeightedSimplex< FilVal > ) -> Ordering {
let mut comp = rhs.vertices.len().cmp( & lhs.vertices.len() ); if comp != Ordering::Equal { return comp }
comp = lhs.weight.cmp( & rhs.weight );
if comp != Ordering::Equal { return comp }
lhs.vertices.cmp( & rhs.vertices )
}
}
#[derive(Debug, PartialEq, Clone, Eq, Hash, Dissolve, new)]
pub struct WeightedSimplex<FilVal: Clone + Debug>{
pub weight: FilVal, pub vertices: Vec<Vertex> }
impl <FilVal: Clone + Debug>
WeightedSimplex<FilVal> {
pub fn number_of_vertices(&self) -> usize { self.vertices.len() }
pub fn dimension(&self) -> usize { self.vertices.len() - 1 }
pub fn weight(&self) -> FilVal { self.weight.clone() }
pub fn filtration(&self) -> FilVal { self.weight.clone() }
pub fn vertices(&self) -> &Vec<Vertex> { &self.vertices }
pub fn agile_boundary_iterator_lexicographic_order
< DissimilarityMatrix, RingOperator >
(
self,
vietoris_rips_complex: Arc< VietorisRipsComplex< DissimilarityMatrix, RingOperator > >,
)
->
AgileBoundaryIteratorLexicographicOrder< DissimilarityMatrix, RingOperator >
where
DissimilarityMatrix: Clone + MatrixOracle<
ColumnIndex = usize,
RowIndex = usize,
Coefficient = FilVal,
RowEntry: KeyValNew,
Row: Clone,
>,
DissimilarityMatrix::Coefficient: Ord + Bounded,
RingOperator: Clone + RingOperations,
FilVal: Copy,
{
AgileBoundaryIteratorLexicographicOrder::new(
vietoris_rips_complex,
self,
false, )
}
pub fn agile_coboundary_iterator_lexicographic_order
< DissimilarityMatrix, RingOperator >
(
self,
vietoris_rips_complex: Arc< VietorisRipsComplex< DissimilarityMatrix, RingOperator > >,
)
->
Result<
AgileCoboundaryIterartorLexicographicOrder< DissimilarityMatrix, RingOperator >,
Vec<Vertex>,
>
where
DissimilarityMatrix: Clone + MatrixOracle<
ColumnIndex = usize,
RowIndex = usize,
Coefficient = FilVal,
RowEntry: KeyValNew,
Row: Clone,
>,
DissimilarityMatrix::Coefficient: Ord + Bounded,
RingOperator: Clone + RingOperations,
FilVal: Copy,
{
let iterator = AgileCoboundaryIterartorLexicographicOrder::new(
self.vertices().clone(),
vietoris_rips_complex.dissimilarity_matrix.clone(),
vietoris_rips_complex.ring_operator(),
)?;
if iterator.facet_filtration != self.filtration() {
println!("Error: the weight of this simplex does not match its filtration value in the Vietoris-Rips complex.");
return Err( self.vertices.clone() );
}
Ok(iterator)
}
}
impl <FilVal>
PartialOrd for WeightedSimplex<FilVal>
where FilVal: Eq + PartialEq + Ord + PartialOrd + Clone + Debug
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl <FilVal>
Ord for WeightedSimplex<FilVal>
where FilVal: Eq + PartialEq + Ord + PartialOrd + Clone + Debug
{
fn cmp(&self, other: &Self) -> Ordering {
let comp = self.weight.cmp( & other.weight );
if comp != Ordering::Equal { return comp }
self.vertices.cmp( & other.vertices )
}
}