Path: blob/master/sage/geometry/triangulation/triangulations.cc
4097 views
#include <algorithm>1#include "triangulations.h"234//------------ traverse the edges of the secondary polytope ------------5triangulations::triangulations(const flips& all_flips)6: hash_max(10000),7hash_list(hash_max,hash_max),8bistellar_flips(all_flips),9position(0),10star(-1),11fine(false),12need_resize(false)13{}141516// find the correct position for t in the hash17void triangulations::find_hash_position(const compact_simplices& t,18hash_value& pos, bool& is_new) const19{20hash_value freespace;21const hash_value initial_guess = t.hash_function() % hash_max;2223for (hash_value i=0; i<hash_max; ++i) {24pos = (initial_guess+i) % hash_max;25if (hash_list[pos]==hash_max) {26// found empty place in hash27is_new=true;28if (i>5)29need_resize = true;30return;31}32else if ((*this)[hash_list[pos]]==t) {33// found ourselves in hash34is_new = false;35return;36}37// hash collision: continue38}39assert(false); // the need_resize was not honored, bug?40}414243void triangulations::add_triang_if_new(const compact_simplices & new_triang)44{45hash_value pos;46bool is_new;47find_hash_position(new_triang, pos, is_new);48if (!is_new) return;4950while (need_resize) {51hash_max = 2*hash_max+1;52hash_list = std::vector<size_t>(hash_max, hash_max);53for (size_t i=0; i<size(); i++) {54find_hash_position( (*this)[i], pos, is_new);55assert(is_new);56hash_list[pos] = i;57}58need_resize = false;59find_hash_position(new_triang, pos, is_new);60}6162push_back(new_triang);63hash_list[pos] = size()-1;64}656667void triangulations::add_neighbours(const simplices & s)68{69for (flips::const_iterator70f=bistellar_flips.begin(); f!=bistellar_flips.end(); ++f) {71goodcircuit goody(s,*f);72if (goody.is_good()) {73goody.do_flip(s,*f);74compact_simplices new_triang=goody.get_neighbor();75add_triang_if_new(new_triang);76}77}78}798081bool triangulations::have_more_triangulations()82{83while (position != this->size()) {84// eat all non-star triangulations85simplices triangulation((*this)[position]);8687if ((star>=0) && !(triangulation.starshaped(star))) {88next_triangulation();89continue;90}91// eat non-fine triangulations92if (fine && !(triangulation.fine())) {93next_triangulation();94continue;95}96return true;97}98return false;99}100101102const compact_simplices& triangulations::next_triangulation()103{104add_neighbours((*this)[position]);105return (*this)[position++];106}107108109110111//------------ to be called from Python -------------------------112triangulations_ptr init_triangulations113(int n, int d, int star, bool fine, PyObject* py_seed, PyObject* py_flips)114{115vertices().set_dimensions(n,d);116117compact_simplices seed;118for (int i=0; i<PySequence_Size(py_seed); i++) {119PyObject* simplex = PySequence_GetItem(py_seed,i);120seed.push_back(PyInt_AS_LONG(simplex));121Py_DECREF(simplex);122}123124flips all_flips;125for (int i=0; i<PySequence_Size(py_flips); i++) {126PyObject* py_flip = PySequence_GetItem(py_flips,i);127PyObject* py_flip_pos = PySequence_GetItem(py_flip,0);128PyObject* py_flip_neg = PySequence_GetItem(py_flip,1);129130std::vector<vertices> pos;131for (int j=0; j<PySequence_Size(py_flip_pos); j++) {132PyObject* py_simplex = PySequence_GetItem(py_flip_pos,j);133vertices simplex;134for (int k=0; k<PySequence_Size(py_simplex); k++) {135PyObject* py_vertex = PySequence_GetItem(py_simplex,k);136simplex.insert(simplex.begin(), PyInt_AS_LONG(py_vertex));137Py_DECREF(py_vertex);138}139pos.push_back(simplex);140Py_DECREF(py_simplex);141}142143std::vector<vertices> neg;144for (int j=0; j<PySequence_Size(py_flip_neg); j++) {145PyObject* py_simplex = PySequence_GetItem(py_flip_neg,j);146vertices simplex;147for (int k=0; k<PySequence_Size(py_simplex); k++) {148PyObject* py_vertex = PySequence_GetItem(py_simplex,k);149simplex.insert(simplex.begin(), PyInt_AS_LONG(py_vertex));150Py_DECREF(py_vertex);151}152neg.push_back(simplex);153Py_DECREF(py_simplex);154}155156all_flips.push_back(flip(pos,neg));157all_flips.push_back(flip(neg,pos));158Py_DECREF(py_flip_pos);159Py_DECREF(py_flip_neg);160Py_DECREF(py_flip);161}162163// print data so we can see that it worked164/*165std::cout << "\n" << "Seed triangulation: " << seed << "\n";166{167std::cout << "Vertices of seed triangulation: ";168simplices s(seed);169std::cout << s << "\n";170}171std::cout << "All flips:\n";172for (flips::const_iterator i=all_flips.begin(); i!=all_flips.end(); ++i)173std::cout << *i << std::endl;174*/175176triangulations_ptr t = new triangulations(all_flips);177178if (star>=0)179t->require_star_triangulation(star);180181if (fine)182t->require_fine_triangulation(fine);183184t->add_triang_if_new(seed);185186return t;187}188189190PyObject* next_triangulation(triangulations_ptr t)191{192if (!t->have_more_triangulations())193return PyTuple_New(0);194195const compact_simplices& triang = t->next_triangulation();196PyObject* py_triang = PyTuple_New(triang.size());197for (int i=0; i<triang.size(); i++)198PyTuple_SET_ITEM(py_triang, i, PyInt_FromLong(triang[i]));199200return py_triang;201}202203204void delete_triangulations(triangulations_ptr t)205{206delete(t);207}208209210211