use derive_new::new;
use crate::utilities::iterators::general::TwoTypeIterator;
use crate::utilities::iterators::merge::hit::{HitMergeByPredicateTrait, IteratorsMergedInSortedOrder};
use crate::utilities::order::{OrderOperatorAutoReverse, JudgeOrder, JudgePartialOrder};
use crate::utilities::sequences_and_ordinals::{CombinationsReverse, SortedVec};
use itertools::{Dedup, KMerge, Itertools, Combinations};
use std::cmp::Ordering;
use std::iter::{Flatten, Cloned};
use std::slice::Iter;
use std::fmt::Debug;
#[derive(Clone,Debug,new)]
pub struct OrderOperatorTwistSimplex;
impl < Vertex: Ord >
JudgePartialOrder
< Vec< Vertex > > for
OrderOperatorTwistSimplex
{
fn judge_partial_cmp
( & self, lhs: & Vec< Vertex >, rhs: & Vec< Vertex > ) -> Option<Ordering>
{ Some( self.judge_cmp(lhs,rhs) ) }
}
impl < Vertex: Ord >
JudgeOrder
< Vec< Vertex > > for
OrderOperatorTwistSimplex
{
fn judge_cmp
( & self, lhs: & Vec< Vertex >, rhs: & Vec< Vertex > ) -> Ordering
{
let comp = rhs.len().cmp( & lhs.len() ); if comp != Ordering::Equal { return comp }
lhs.cmp( rhs )
}
}
pub fn insert_vertex< Vertex >( vertex: Vertex, simplex: & Vec< Vertex > )
-> ( Vec< Vertex >, usize )
where Vertex: Ord + Clone
{
if simplex.is_empty() {
return ( vec![ vertex ], 0 )
}
let mut i = 0;
while i < simplex.len() && simplex[ i ] < vertex {
i += 1;
}
let mut new_simplex = Vec::with_capacity( simplex.len() + 1 );
new_simplex.extend_from_slice( &simplex[ 0 .. i ] ); new_simplex.push( vertex ); new_simplex.extend_from_slice( &simplex[ i .. ] );
( new_simplex, i )
}
pub fn dimension_d_simplices_in_reverse_lexicographic_order_iter< Vertex >(
facets: &Vec< SortedVec< Vertex >>,
dim: isize
)
->
TwoTypeIterator<
std::iter::Empty< Vec<Vertex> >,
Dedup<
IteratorsMergedInSortedOrder<
CombinationsReverse< Vertex, &Vec< Vertex > >,
OrderOperatorAutoReverse,
>,
>,
>
where Vertex: Ord + Clone
{
if dim < -1 {
return TwoTypeIterator::Version1(
std::iter::empty()
)
}
let iter =
facets
.iter()
.map( |vertices| CombinationsReverse::from_vec( dim as usize +1, vertices.vec() ) )
.hit_merge_by_predicate( OrderOperatorAutoReverse )
.dedup();
return TwoTypeIterator::Version2(iter)
}
pub fn dimension_d_simplices_in_lexicographic_order_iter< Vertex >(
facets: & Vec< SortedVec< Vertex >>,
dim: isize
)
->
TwoTypeIterator<
std::iter::Empty< Vec<Vertex> >,
Dedup< KMerge< Combinations<Cloned<Iter<Vertex>>> > >,
>
where Vertex: Ord + Clone
{
if dim < -1 {
return TwoTypeIterator::Version1(
std::iter::empty()
)
}
let iter =
facets
.iter()
.map( |x| x.vec().iter().cloned().combinations( (dim + 1isize) as usize ) )
.kmerge()
.dedup();
return TwoTypeIterator::Version2(
iter
)
}
pub fn dimension_0_through_d_simplices_in_dimensionwise_lexicographic_order_iter< Vertex >(
facets: & Vec< SortedVec< Vertex >>,
max_dim: isize
)
->
Flatten<
std::vec::IntoIter<
TwoTypeIterator<
std::iter::Empty< Vec<Vertex> >,
Dedup< KMerge< Combinations<Cloned<Iter<Vertex>>> > >,
>
>
>
where
Vertex: Ord + Clone,
{
(0 .. max_dim + 1)
.map( |dim|
dimension_d_simplices_in_lexicographic_order_iter(facets, dim)
)
.collect_vec()
.into_iter()
.flatten()
}
pub fn dimension_0_through_d_simplices_in_reverse_dimensionwise_lexicographic_order_iter< Vertex >(
facets: &Vec< SortedVec< Vertex >>,
max_dim: isize
)
->
Flatten< std::vec::IntoIter<
TwoTypeIterator<
std::iter::Empty< Vec<Vertex> >,
Dedup<
IteratorsMergedInSortedOrder<
CombinationsReverse< Vertex, &Vec< Vertex > >,
OrderOperatorAutoReverse,
>,
>
>,
>>
where
Vertex: Ord + Clone,
{
(0 .. max_dim + 1)
.rev()
.map( |dim|
dimension_d_simplices_in_reverse_lexicographic_order_iter( facets, dim )
)
.collect_vec()
.into_iter()
.flatten()
}
pub fn dimension_0_through_d_simplices_in_ascending_dimension_descending_lexicographic_order_iter< Vertex >(
facets: &Vec< SortedVec< Vertex >>,
max_dim: isize
)
->
Flatten< std::vec::IntoIter<
TwoTypeIterator<
std::iter::Empty< Vec<Vertex> >,
Dedup<
IteratorsMergedInSortedOrder<
CombinationsReverse< Vertex, &Vec< Vertex > >,
OrderOperatorAutoReverse,
>,
>
>,
>>
where
Vertex: Ord + Clone,
{
(0 .. max_dim + 1)
.map( |dim|
dimension_d_simplices_in_reverse_lexicographic_order_iter( facets, dim )
)
.collect_vec()
.into_iter()
.flatten()
}
pub fn dimension_0_through_d_simplices_in_lexicographic_order_binned_by_dimension< Vertex >(
facets: & Vec< SortedVec< Vertex >>,
max_dim: isize
)
->
Vec< Vec< Vec< Vertex >>>
where Vertex: Ord + Clone
{
if max_dim < 0 { return Vec::new() } let mut seq = Vec::with_capacity( max_dim as usize );
for dim in 0 .. max_dim + 1 {
let vec: Vec<_> = dimension_d_simplices_in_lexicographic_order_iter(
facets,
dim
)
.collect();
seq.push( vec );
}
seq
}
pub fn dimension_0_through_d_simplices_in_dimensionwise_lexicographic_order_list< Vertex >(
facets: & Vec< SortedVec< Vertex >>,
max_dim: isize
)
->
Vec< Vec< Vertex >>
where Vertex: Ord + Clone
{
let mut a = dimension_0_through_d_simplices_in_lexicographic_order_binned_by_dimension( facets, max_dim );
let mut b = Vec::new();
for i in 0 .. a.len() {
b.append( &mut a[ i ] );
}
b
}
#[derive(Clone, Debug, PartialEq)]
pub struct FacetIteratorNoReturnAscendingLex< Vertex: Ord >
{
pub simplex: Vec< Vertex > ,
pub facet: Vec< Vertex >,
pub deleted_vertex_index: Option<usize>
}
impl < Vertex: Ord > FacetIteratorNoReturnAscendingLex < Vertex >
where Vertex: Clone
{
pub fn new( simplex: Vec< Vertex >, buffer: Option< Vec<Vertex> > ) -> Self {
let buffer = buffer.unwrap_or( Vec::with_capacity( simplex.len()-1 ) );
FacetIteratorNoReturnAscendingLex {
simplex,
facet: buffer,
deleted_vertex_index: None
}
}
pub fn reinitialize_with_simplex( &mut self, simplex: Vec< Vertex > ) {
if simplex.len() > 1 + self.facet.capacity() {
self.facet.reserve_exact(
simplex.len() - 1 - self.facet.capacity()
)
}
self.simplex = simplex;
self.facet.clear();
self.deleted_vertex_index = None;
}
}
impl < Vertex: Ord >
Iterator for
FacetIteratorNoReturnAscendingLex < Vertex >
where Vertex : Clone
{
type Item = ();
fn next( &mut self ) -> Option<()> {
if let Some( deleted_index ) = self.deleted_vertex_index {
if deleted_index == 0 {
self.deleted_vertex_index = None;
self.facet.clear();
None
} else {
let next_deleted_index = deleted_index - 1;
self.facet[ next_deleted_index ] = self.simplex[ deleted_index ].clone(); self.deleted_vertex_index = Some( next_deleted_index );
Some( () )
}
} else {
self.facet.clear();
for i in 0..self.simplex.len()-1 { self.facet.push( self.simplex[ i ].clone() )
}
self.deleted_vertex_index = Some( self.simplex.len()-1 ); Some(())
}
}
}
#[cfg(test)]
mod tests {
use crate::utilities::order::{is_sorted_strictly, OrderOperatorAuto};
use super::*;
#[test]
fn test_ordered_subsimplices_up_thru_dim() {
let facets = vec![
SortedVec::new(vec![0, 1, 2]).unwrap()
];
assert_eq!( dimension_0_through_d_simplices_in_lexicographic_order_binned_by_dimension( & facets, 2),
vec![
vec![ vec![0], vec![1], vec![2] ],
vec![ vec![0,1], vec![0,2], vec![1,2] ],
vec![ vec![0,1,2] ]
]
);
assert_eq!( dimension_0_through_d_simplices_in_dimensionwise_lexicographic_order_list( & facets, 2),
vec![
vec![0], vec![1], vec![2],
vec![0,1], vec![0,2], vec![1,2],
vec![0,1,2]
]
) ;
}
#[test]
fn test_ascending_facet_iterator_no_return()
{
let mut facet_iterator_noreturn = FacetIteratorNoReturnAscendingLex::new(
vec![0, 1, 2],
None
);
let mut answers = vec![
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 1, 2], facet: vec![0, 1], deleted_vertex_index: Some(2) },
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 1, 2], facet: vec![0, 2], deleted_vertex_index: Some(1) },
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 1, 2], facet: vec![1, 2], deleted_vertex_index: Some(0) },
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 1, 2], facet: vec![] , deleted_vertex_index: None },
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 1, 2], facet: vec![0, 1], deleted_vertex_index: Some(2) },
];
for i in 0..5 {
facet_iterator_noreturn.next();
assert_eq!( &facet_iterator_noreturn, &answers[ i ] )
}
facet_iterator_noreturn.reinitialize_with_simplex( vec![0 ,3] );
answers = vec![
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 3], facet: vec![0], deleted_vertex_index: Some(1) },
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 3], facet: vec![3], deleted_vertex_index: Some(0) },
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 3], facet: vec![] , deleted_vertex_index: None },
FacetIteratorNoReturnAscendingLex { simplex: vec![0, 3], facet: vec![0], deleted_vertex_index: Some(1) },
];
for i in 0..4 {
facet_iterator_noreturn.next();
assert_eq!( &facet_iterator_noreturn, &answers[ i ] )
}
}
fn test_all_enumeration_techniques() {
use crate::utilities::random::random_sequences;
let size_of_ambient_set = 12;
let cardinalities = 0 .. 13;
let max_dim = 5;
for probability in [0.0, 0.01, 0.05 ] {
let facets = random_sequences( 20, cardinalities.clone(), probability);
verify_simplex_enumeartion_methods_are_consistent( &facets, max_dim )
}
}
fn verify_simplex_enumeartion_methods_are_consistent(
facets: &Vec< SortedVec< usize >>,
max_dim: isize,
)
{
let simplices: Vec<_> = dimension_0_through_d_simplices_in_dimensionwise_lexicographic_order_iter( facets, max_dim ).collect();
let test = dimension_0_through_d_simplices_in_dimensionwise_lexicographic_order_list(facets, max_dim);
assert_eq!( & simplices, & test );
let test = dimension_0_through_d_simplices_in_lexicographic_order_binned_by_dimension(facets, max_dim)
.into_iter()
.flatten()
.collect::<Vec<_>>();
assert_eq!( & simplices, & test );
let mut test = dimension_0_through_d_simplices_in_ascending_dimension_descending_lexicographic_order_iter(facets, max_dim)
.collect::<Vec<_>>();
( &mut test ).sort_by(| a,b| b.len().cmp( &a.len() ) ); ( &mut test).reverse();
assert_eq!( & simplices, & test );
let mut test = dimension_0_through_d_simplices_in_reverse_dimensionwise_lexicographic_order_iter(facets, max_dim).collect::<Vec<_>>();
( &mut test).reverse();
assert_eq!( & simplices, & test );
let simplices_binned_by_dimension = dimension_0_through_d_simplices_in_lexicographic_order_binned_by_dimension(facets, max_dim);
for dim in 0 .. max_dim + 1 {
let test = dimension_d_simplices_in_lexicographic_order_iter( facets, dim ).collect_vec();
assert_eq!( & simplices_binned_by_dimension[ dim as usize ], & test );
let mut test = dimension_d_simplices_in_reverse_lexicographic_order_iter( facets, dim ).collect_vec();
( &mut test).reverse();
assert_eq!( & simplices_binned_by_dimension[ dim as usize ], & test );
}
let binned_simplices = dimension_0_through_d_simplices_in_lexicographic_order_binned_by_dimension(facets, max_dim);
for ( dim, simplices ) in binned_simplices.into_iter().enumerate() {
assert!( simplices.is_sorted() );
for simplex in simplices.iter() {
assert!( simplex.len() == dim + 1 )
}
}
for simplex in simplices.iter() {
assert!( is_sorted_strictly( & simplex, & OrderOperatorAuto::new() ) )
}
for simplex in simplices.iter() {
let order_certified_simplex = SortedVec::new( simplex.clone() ).unwrap();
let is_ok = facets
.iter()
.any(
|facet|
facet.contains_subset( & order_certified_simplex )
);
assert!( is_ok );
}
let simplices_var = subsequences_up_to_length_m_multi_source( facets, (max_dim + 1) as usize );
assert_eq!( & simplices, & simplices_var );
}
fn subsequences_up_to_length_m_multi_source<T: Clone + Ord >(sequences: &Vec< SortedVec<T> >, m: usize) -> Vec<Vec<T>> {
let mut simplices = Vec::new();
for sequence in sequences {
let subsequences = subsequences_up_to_length_m_single_source(sequence.vec(), m);
simplices.extend( subsequences.into_iter() );
}
simplices.sort();
simplices.dedup();
simplices
}
fn subsequences_up_to_length_m_single_source<T: Clone>(vec: &Vec<T>, m: usize) -> Vec<Vec<T>> {
let mut result = Vec::new();
let mut current = Vec::new();
generate_subsequences(vec, m, 0, &mut current, &mut result);
result
}
fn generate_subsequences<T: Clone>(
vec: &Vec<T>,
max_len: usize,
start: usize,
current: &mut Vec<T>,
result: &mut Vec<Vec<T>>
) {
if !current.is_empty() {
result.push(current.clone());
}
if current.len() < max_len {
for i in start..vec.len() {
current.push(vec[i].clone());
generate_subsequences(vec, max_len, i + 1, current, result);
current.pop();
}
}
}
}