/// Returns the omnitruncate of a polytope, along with the flags that make
/// up its respective vertices.
///
/// # Panics
/// You must call [`Polytope::element_sort`] before calling this method.
Returns the omnitruncate of a polytope, along with the flags that make
up its respective vertices.
Returns the omnitruncate of a polytope along with the flags that make up its respective vertices .
pub fn omnitruncate_and_flags(&self) -> (Self, Vec<Flag>) {
        let mut flag_sets = vec![FlagSet::new_all(self)];
        let mut new_flag_sets = Vec::new();
        let rank = self.rank();
        // The elements of each rank... backwards.
        let mut ranks = Vec::with_capacity(rank + 1);
        // Adds elements of each rank, except for vertices and the minimal
        // element.
        for _ in (2..=rank).rev() {
            let mut subelements = SubelementList::new();
            // Gets the subelements of each element.
            for flag_set in flag_sets {
                let mut subs = Subelements::new();
                // Each subset represents a new element.
                // todo: just return an iterator here.
                for subset in flag_set.subsets(self) {
                    // We do a brute-force check to see if we've found this
                    // element before.
                    //
                    // TODO: think of something better?
                    match new_flag_sets
                        .iter()
                        .enumerate()
                        .find(|(_, new_flag_set)| subset == **new_flag_set)
                    {
                        // This is a repeat element.
                        Some((idx, _)) => {
                            subs.push(idx);
                        }
                        // This is a new element.
                        None => {
                            subs.push(new_flag_sets.len());
                            new_flag_sets.push(subset);
                        }
                    }
                }
                subelements.push(subs);
            }
            ranks.push(subelements);
            flag_sets = new_flag_sets;
            new_flag_sets = Vec::new();
        }
        // todo: it might be better to just return an iterator.
        let mut flags = Vec::new();
        for flag_set in flag_sets {
            debug_assert_eq!(flag_set.len(), 1);
            flags.push(flag_set.flags.into_iter().next().unwrap());
        }
        ranks.push(SubelementList::vertices(flags.len()));
        ranks.push(SubelementList::min());
        let builder: AbstractBuilder = ranks.into_iter().rev().collect();
        // Safety: we've built an omnitruncate based on the polytope. For a
        // proof that this construction yields a valid abstract polytope, see
        // [TODO: write proof].
        (unsafe { builder.build() }, flags)
    }
pub fn omnitruncate_and_flags ( & self ) -> ( Self , Vec < Flag > ) { let mut flag_sets = vec ! [ FlagSet new_all ( self ) ] ; let mut new_flag_sets = Vec :: new ( ) ; let rank = self . rank ( ) ; // The elements of each rank... backwards. let mut ranks = Vec :: with_capacity ( rank + 1 ) ; // Adds elements of each rank, except for vertices and the minimal // element. for _ in ( 2 ..= rank ) . rev ( ) { let mut subelements = SubelementList :: new ( ) ; // Gets the subelements of each element. for flag_set in flag_sets { let mut subs = Subelements :: new ( ) ; // Each subset represents a new element. // todo: just return an iterator here. for subset in flag_set . subsets ( self ) { // We do a brute-force check to see if we've found this // element before. // // TODO: think of something better? match new_flag_sets . iter ( ) . enumerate ( ) . find ( | ( _ , new_flag_set ) | subset == * * new_flag_set ) { // This is a repeat element. Some ( ( idx , _ ) ) => { subs . push ( idx ) ; } // This is a new element. None => { subs . push ( new_flag_sets . len ( ) ) ; new_flag_sets . push ( subset ) ; } } } subelements . push ( subs ) ; } ranks . push ( subelements ) ; flag_sets = new_flag_sets ; new_flag_sets = Vec :: new ( ) ; } // todo: it might be better to just return an iterator. let mut flags = Vec :: new ( ) ; for flag_set in flag_sets { debug_assert_eq ! ( flag_set len ( ) 1 ) ; flags . push ( flag_set . flags . into_iter ( ) . next ( ) . unwrap ( ) ) ; } ranks . push ( SubelementList :: vertices ( flags . len ( ) ) ) ; ranks . push ( SubelementList :: min ( ) ) ; let builder : AbstractBuilder = ranks . into_iter ( ) . rev ( ) . collect ( ) ; // Safety: we've built an omnitruncate based on the polytope. For a // proof that this construction yields a valid abstract polytope, see // [TODO: write proof]. ( unsafe { builder . build ( ) } , flags ) }
Returns the omnitruncate of a polytope, along with the flags that make
up its respective vertices.
Returns the omnitruncate of a polytope along with the flags that make up its respective vertices .
&self
panics
You must call [`Polytope::element_sort`] before calling this method.
You must call [ ` Polytope :: element_sort ` ] before calling this method .