Path: blob/master/src/sage/geometry/triangulation/data.cc
8817 views
#include <iostream>1#include <fstream>2#include <set>3#include <functional>4#include <vector>5#include <algorithm>6#include "functions.h"7#include "data.h"89101112// ------- class vertices ----------------------------1314int vertices::n=0;1516int vertices::d=0;1718vertices_lookup vertices::lookup=vertices_lookup();192021void vertices::set_dimensions(int N, int D)22{23n=N; d=D;24lookup.generate_tables(n,d);25}262728vertices::vertices()29{30}313233vertices::vertices(const simplex& S)34{35simplex_to_vertices(S);36}373839const simplex vertices::vertices_to_simplex() const40{41simplex s=1;42vertex k=1, l;43const_iterator l_iterator=begin();44for (vertex i=1; i<=d; ++i) {45l = (*l_iterator)+1;46for (vertex j=k; j<=l-1; ++j)47s=s+lookup.get_binomial(n-j,d-i);48k=l+1;49++l_iterator;50}51return(s);52}535455const vertices & vertices::simplex_to_vertices(const simplex & S)56{57(*this) = lookup.simplex_to_vertices(S);58return(*this);59}606162std::ostream & operator << (std::ostream & out, const vertices & v)63{64out << *( v.begin() );65vertices::const_iterator i=v.begin(); i++;66for (; i!=v.end(); ++i)67out << "_" << *i;68return(out);69}707172bool vertices_order::operator()(const vertices & a, const vertices & b) const73{74size_t n1=a.size(), n2=b.size();75if (n1<n2) return(true);76if (n1>n2) return(false);77// a,b have same size78for (vertices::iterator i=a.begin(), j=b.begin();79i!=a.end() && j!=b.end(); ++i, ++j) {80if (*i < *j) return(true);81if (*i > *j) return(false);82}83// a == b84return(false);85}868788bool operator==(const vertices & a, const vertices & b)89{90return( std::set<vertex,std::less<vertex> >(a) ==91std::set<vertex,std::less<vertex> >(b) );92}939495// ------- class vertices_lookup --------------------9697const vertices & vertices_lookup::simplex_to_vertices(const simplex & S) const98{99return( SimplexToVertices[S-1] );100}101102103// this one is messy, but it only reverses vertices_to_simplex()104vertices vertices_lookup::manual_vertices_to_simplex(const simplex & S) const105{106vertices result;107simplex s=S;108simplex b;109vertex i,j,l=0,k;110for (k=1; k<d; k++) {111l++; i=l; j=1;112b=binomial(n-l,d-k);113while (s>b && b>0) {114j++; l++;115s=s-b;116b=binomial(n-l,d-k);117}118result.insert(result.begin(),l-1);119}120result.insert(result.begin(),s+l-1);121return(result);122}123124// tweaked for special (e.g. negative) values125int vertices_lookup::get_binomial(int i, int j) const126{127if (i>=0 && i<=n && j>=0 && j<=d && j<=i)128return(fast_binomial[i][j]);129else130return(1);131}132133134void vertices_lookup::generate_tables(int N, int D)135{136n=N; d=D;137fast_binomial.erase(fast_binomial.begin(),fast_binomial.end());138for(int i=0; i<=n; ++i) {139std::vector<int> row;140for(int j=0; j<=i && j<=d; j++)141row.push_back( binomial(i,j) );142fast_binomial.push_back( row );143}144SimplexToVertices.erase(SimplexToVertices.begin(),SimplexToVertices.end());145for(int s=1; s<=binomial(n,d); ++s)146SimplexToVertices.push_back(manual_vertices_to_simplex(s));147}148149150151152// ------- class compact_simplices -------------------153154compact_simplices::compact_simplices()155{156reserve(50);157}158159compact_simplices::~compact_simplices()160{161}162163std::ostream & operator << (std::ostream & out, const compact_simplices & t)164{165out << "[" << *( t.begin() );166for (compact_simplices::const_iterator i=t.begin()+1; i!=t.end(); ++i)167out << "," << *i;168out << "]";169return(out);170}171172const bool operator==(const compact_simplices & a, const compact_simplices & b)173{174// friendship is not inherited175return( std::vector<simplex>(a) == std::vector<simplex>(b) );176}177178hash_value compact_simplices::hash_function() const179{180hash_value result=0;181int n=101;182for (const_iterator i=begin(); i!=end(); ++i, n+=37)183result += n* (*i) + n*n;184return(result);185}186187188189190191// ------- class simplices ---------------------------192193simplices::simplices(const compact_simplices & s)194:compact_simplices(s)195{196decompress(); // de-compress vertex information197}198199simplices::simplices(const std::set<vertices,vertices_order> & s)200{201v.erase(v.begin(), v.end());202copy(s.begin(), s.end(), back_inserter(v) );203compress();204}205206207simplices::~simplices()208{209}210211void simplices::compress()212{213erase(begin(),end());214for (std::vector<vertices>::const_iterator i=v.begin(); i!=v.end(); i++)215push_back( (*i).vertices_to_simplex() );216std::sort(begin(),end());217}218219220void simplices::decompress()221{222v.erase(v.begin(),v.end());223for (const_iterator i=begin(); i!=end(); i++)224v.push_back( vertices().simplex_to_vertices(*i) );225}226227228bool simplices::starshaped(const vertex origin) const229{230bool result = true;231for (std::vector<vertices>::const_iterator232vi=v.begin(); vi!=v.end(); vi++) {233result=result && (find(vi->begin(),vi->end(),origin)!=vi->end());234}235return(result);236}237238239bool simplices::fine() const240{241vertices support;242for (std::vector<vertices>::const_iterator243vi=v.begin(); vi!=v.end(); vi++) {244support.insert(vi->begin(), vi->end());245}246return support.full_set();247}248249250std::ostream & operator << (std::ostream & out, const simplices & s)251{252out << "[" << s.v.front();253for (std::vector<vertices>::const_iterator254si=s.v.begin()+1; si!=s.v.end(); si++)255out << ", " << *si;256out << "]";257return(out);258}259260// ------- class flip --------------------------------261262flip::flip()263{264deltaplus.reserve(10);265deltaminus.reserve(10);266}267268flip::flip(const std::vector<vertices>& pos, const std::vector<vertices>& neg)269: deltaplus(pos), deltaminus(neg)270{}271272flip::flip(const flip & copyfrom)273{274deltaplus.reserve(10);275deltaminus.reserve(10);276(*this)=copyfrom;277}278279flip::~flip()280{281}282283flip & flip::operator =(const flip & copyfrom)284{285deltaplus = copyfrom.get_deltaplus();286deltaminus = copyfrom.get_deltaminus();287return(*this);288}289290std::ostream & operator << (std::ostream & out, const flip & f)291{292out << "< ";293for (std::vector<vertices>::const_iterator i=f.get_deltaplus().begin();294i!=f.get_deltaplus().end(); ++i) {295std::cout << *i << " ";296}297out << "| ";298for (std::vector<vertices>::const_iterator i=f.get_deltaminus().begin();299i!=f.get_deltaminus().end(); ++i) {300std::cout << *i << " ";301}302out << ">";303return(out);304}305306void flip::mirror()307{308swap(deltaplus,deltaminus);309}310311312313314// ------- class flips -------------------------------315316flips::flips()317{318}319320flips::~flips()321{322}323324325// ------- class goodcircuit -------------------------326327328goodcircuit::goodcircuit(const simplices & s, const flip & f)329:supporter(f)330{331const std::vector<vertices> & deltaplus = f.get_deltaplus();332const std::vector<vertices> & v = s.get_vertices();333supported.reserve(deltaplus.size());334good=true;335336337// find simplices that include members of deltaplus338std::vector<vertices> empty_result;339for (size_t n=0; n<deltaplus.size(); n++) {340supported.push_back(empty_result); supported[n].reserve(10);341bool found_match=false;342for (std::vector<vertices>::const_iterator i=v.begin(); i!=v.end(); ++i) {343if (includes( (*i).begin(), (*i).end(),344deltaplus[n].begin(), deltaplus[n].end() )) {345found_match=true;346supported[n].push_back(*i);347}348}349good=good && found_match;350if (!good) return;351}352353// check that all links are equal354for (size_t n=0; n<deltaplus.size(); n++) {355std::set<vertices,vertices_order> l;356for (std::vector<vertices>::const_iterator i=supported[n].begin();357i!=supported[n].end(); ++i) {358vertices one_simplex;359std::insert_iterator<vertices>360ins(one_simplex,one_simplex.begin());361set_difference( (*i).begin(), (*i).end(),362deltaplus[n].begin(), deltaplus[n].end(),363ins );364l.insert(l.begin(),one_simplex);365}366link.push_back(l);367if (n>0 && link[0]!=link[n]) {368good=false;369return;370}371}372}373374375void goodcircuit::do_flip(const simplices & s, const flip & f)376{377bistellarneighbor.erase(bistellarneighbor.begin(), bistellarneighbor.end());378379const std::set<vertices,vertices_order> & use_link = link[0];380const std::vector<vertices> & v = s.get_vertices();381const std::vector<vertices> & deltaplus = f.get_deltaplus();382const std::vector<vertices> & deltaminus = f.get_deltaminus();383384// start with all simplices385std::set<vertices,vertices_order> tri;386copy(v.begin(), v.end(), inserter(tri,tri.begin()) );387388// remove all suported simplices389std::set<vertices,vertices_order> to_remove;390391for (std::set<vertices,vertices_order>::const_iterator i=use_link.begin();392i!=use_link.end(); ++i)393for (std::vector<vertices>::const_iterator j=deltaplus.begin();394j!=deltaplus.end(); ++j) {395vertices one_simplex;396set_union( (*j).begin(), (*j).end(),397(*i).begin(), (*i).end(),398inserter(one_simplex,one_simplex.begin()) );399to_remove.insert(to_remove.begin(),one_simplex);400}401set_difference( tri.begin(), tri.end(),402to_remove.begin(), to_remove.end(),403inserter(bistellarneighbor,bistellarneighbor.begin()),404vertices_order() );405406// now add the flip of the supported simplices407for (std::set<vertices,vertices_order>::const_iterator i=use_link.begin();408i!=use_link.end(); ++i)409for (std::vector<vertices>::const_iterator j=deltaminus.begin();410j!=deltaminus.end(); j++) {411vertices one_simplex;412set_union( (*j).begin(), (*j).end(),413(*i).begin(), (*i).end(),414inserter(one_simplex,one_simplex.begin()) );415bistellarneighbor.insert( bistellarneighbor.begin(), one_simplex );416}417}418419420421422423424425426427428429430431432433