GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
//1// movable_complex.cpp2// Bistellar3//4// Created by Alexander Thumm on 07.10.11.5// Copyright 2011 -. All rights reserved.6//78#include "movable_complex.h"9#include "face.h"10#include "util.h"11#include <algorithm>12#include <iostream>1314MovableComplex::MovableComplex() : _faces(1, face_list_t(0)), _moves(1, bistellar_move_option_list_t(0)), _dimension(0)15{16}1718MovableComplex::MovableComplex(const face_list_t & facets, unsigned int dimension) : _faces(dimension+1), _moves(dimension+1), _dimension(dimension)19{2021#ifdef Bistellar_debug_output22std::cout << "Creating "<< dimension <<"-dimensional MovableComplex from Facets: ";23list_print(std::cout, facets.begin(), facets.end());24std::cout << std::endl;25#endif2627// init facets28_faces[dimension] = facets;2930// init lower dimensional faces31for (int codimension = 1; codimension < dimension+1; codimension++)32{33if(!_faces[dimension - codimension + 1].empty())34{35for (face_list_t::const_iterator it = _faces[dimension - codimension + 1].begin();36it != _faces[dimension - codimension + 1].end(); it++)37{38for (int i = 0; i < dimension - codimension + 2; i++)39{40Face * boundaryFace = it->createBoundaryFace(i);41// only add boundaryFace if it is not already contained in complex42if (std::find(_faces[dimension - codimension].begin(), _faces[dimension - codimension].end(), *boundaryFace) == _faces[dimension - codimension].end())43{44_faces[dimension - codimension].push_back(*boundaryFace);45}4647delete boundaryFace;48}49}50}51}5253// init moves54if (!_faces[dimension].empty())55{56for (face_list_t::const_iterator it = _faces[dimension].begin(); it != _faces[dimension].end(); it++)57{58// add all 0-moves59_moves[0].push_back(std::make_pair(BistellarMove(*it, Face()), true));60}61}62for (int codimension = 1; codimension < dimension+1; codimension++)63{64if (!_faces[dimension-codimension].empty())65{66for (face_list_t::const_iterator it = _faces[dimension-codimension].begin(); it != _faces[dimension-codimension].end(); it++)67{68std::deque< Face > linkFacets;69// copy all Facets that contain (*it) as a subface to linkFacets70if (!_faces[dimension].empty())71{72for (face_list_t::const_iterator it2 = _faces[dimension].begin(); it2 != _faces[dimension].end(); it2++)73{74if (it->isSubfaceOf(*it2))75linkFacets.push_back(*it2);76}77}7879if (linkFacets.size() == codimension+1)80{81// add the move option.82Face linkFace = Face::linkFace(*it, linkFacets);83if (linkFace.dimension() <= _dimension)84_moves[codimension].push_back(std::make_pair(BistellarMove(*it, linkFace), (std::find(_faces[linkFace.dimension()].begin(), _faces[linkFace.dimension()].end(), linkFace) == _faces[linkFace.dimension()].end())));85}86}87}88}8990#ifdef Bistellar_debug_output91for (int i = 0; i < dimension+1; i++)92{93std::cout << i << "-Moves: ";94if (!_moves[i].empty()) list_print(std::cout, _moves[i].begin(), _moves[i].end());95std::cout << std::endl;96}97#endif98}99100MovableComplex::MovableComplex(const MovableComplex & cpy)101{102_dimension = cpy._dimension;103_faces = cpy._faces;104_moves = cpy._moves;105}106107MovableComplex & MovableComplex::operator=(const MovableComplex & cpy)108{109if (this == &cpy)110return *this;111112_dimension = cpy._dimension;113_faces = cpy._faces;114_moves = cpy._moves;115116return *this;117}118119MovableComplex::~MovableComplex()120{121}122123unsigned int MovableComplex::dimension() const124{125return _dimension;126}127128unsigned int MovableComplex::f(unsigned int d) const129{130if (d <= _dimension)131return static_cast<unsigned int>(_faces[d].size());132133return 0;134}135136bool MovableComplex::hasValidMoves(unsigned int codimension) const137{138if (!_moves[codimension].empty())139{140for (bistellar_move_option_list_t::const_iterator it = _moves[codimension].begin(); it != _moves[codimension].end(); it++)141{142if(it->second)143return true;144}145}146147return false;148}149150bistellar_move_list_t MovableComplex::validMoves(unsigned int codimension) const151{152bistellar_move_list_t validMoves;153if (!_moves[codimension].empty())154{155for (bistellar_move_option_list_t::const_iterator it = _moves[codimension].begin(); it != _moves[codimension].end(); it++)156{157if(it->second)158validMoves.push_back(it->first);159}160}161return validMoves;162}163164void MovableComplex::moveComplex(const BistellarMove & move)165{166face_list_t::iterator faceIt = std::find(_faces[move.dimension()].begin(), _faces[move.dimension()].end(), move.face());167bistellar_move_option_list_t::iterator moveIt = std::find(_moves[move.codimension()].begin(), _moves[move.codimension()].end(), std::make_pair(move, true));168169if (faceIt != _faces[move.dimension()].end() && moveIt != _moves[move.codimension()].end() && moveIt->second)170{171#ifdef Bistellar_debug_output172std::cout << "Applying " << move << " to complex ";173list_print(std::cout, _faces[_dimension].begin(), _faces[_dimension].end());174std::cout << "." << std::endl;175#endif176if (move.codimension() == 0)177{178// remove face*∂link179_faces[move.dimension()].erase(faceIt);180_moves[move.codimension()].erase(moveIt);181182// add ∂face*link183vertex_t largestVertex = 0;184if (!_faces[0].empty())185{186for (face_list_t::const_iterator it = _faces[0].begin(); it != _faces[0].end(); it++)187{188if (vertex_t_compare(&largestVertex, &(it->vertex(0))) < 0)189largestVertex = it->vertex(0);190}191}192largestVertex++;193Face newVertex(&largestVertex, 0);194_faces[0].push_back(newVertex);195196face_list_t listOfSubfaces;197addSubfacesOfFace(move.face(), listOfSubfaces);198face_list_t listOfBoundaryfaces;199addBoundaryfacesOfFace(move.face(), listOfBoundaryfaces);200if (!listOfSubfaces.empty())201{202for (face_list_t::iterator it = listOfSubfaces.begin(); it != listOfSubfaces.end(); it++)203{204Face newFace = Face::unite(*it, newVertex);205// add new face to complex206_faces[newFace.dimension()].push_back(newFace);207208// add new move options209if (newFace.dimension() == this->dimension())210{211_moves[0].push_back(std::make_pair(BistellarMove(newFace, Face()), true));212}213else214{215face_list_t listOfLinkFaces;216for (face_list_t::iterator it2 = listOfBoundaryfaces.begin(); it2 != listOfBoundaryfaces.end(); it2++)217{218if (it->isSubfaceOf(*it2))219listOfLinkFaces.push_back(*it2);220}221if (listOfLinkFaces.size() == this->dimension() - it->dimension() + 1)222{223Face linkFace = Face::linkFace(*it, listOfLinkFaces);224if (linkFace.dimension() <= this->dimension())225_moves[this->dimension() - it->dimension()].push_back(std::make_pair(BistellarMove(*it, linkFace), false));226}227}228}229updateBallBoundary(*this, listOfSubfaces);230}231}232else233{234// remove face*∂link235face_list_t listOfLinkSubfaces;236addSubfacesOfFace(move.link(), listOfLinkSubfaces);237238_faces[move.dimension()].erase(faceIt);239_moves[move.codimension()].erase(moveIt);240if (!listOfLinkSubfaces.empty())241{242for (face_list_t::iterator it = listOfLinkSubfaces.begin(); it != listOfLinkSubfaces.end(); it++)243{244// remove old faces245Face oldFace = Face::unite(move.face(), *it);246face_list_t::iterator oldFaceIt = std::find(_faces[oldFace.dimension()].begin(), _faces[oldFace.dimension()].end(), oldFace);247if (oldFaceIt != _faces[oldFace.dimension()].end())248_faces[oldFace.dimension()].erase(oldFaceIt);249250// remove old moves251if (!_moves[this->dimension() - oldFace.dimension()].empty())252{253for (bistellar_move_option_list_t::iterator oldMoveIt = _moves[this->dimension() - oldFace.dimension()].begin(); oldMoveIt != _moves[this->dimension() - oldFace.dimension()].end(); oldMoveIt++)254{255if (oldMoveIt->first.face() == oldFace)256{257_moves[this->dimension() - oldFace.dimension()].erase(oldMoveIt);258break;259}260}261}262}263}264265// add ∂face*link266face_list_t listOfFaceSubfaces;267addSubfacesOfFace(move.face(), listOfFaceSubfaces);268listOfFaceSubfaces.push_back(Face());269if (!listOfFaceSubfaces.empty())270{271face_list_t listOfNewFacets;272face_list_t listOfBallInteriorFaces;273274// add the new faces275for (face_list_t::iterator it = listOfFaceSubfaces.begin(); it != listOfFaceSubfaces.end(); it++)276{277Face newFace = Face::unite(*it, move.link());278279if (_faces[newFace.dimension()].empty() || std::find(_faces[newFace.dimension()].begin(), _faces[newFace.dimension()].end(), newFace) == _faces[newFace.dimension()].end())280{281_faces[newFace.dimension()].push_back(newFace);282}283284if (newFace.dimension() == this->dimension())285{286listOfNewFacets.push_back(newFace);287}288else289{290listOfBallInteriorFaces.push_back(newFace);291}292}293294// add the new moves295for (face_list_t::iterator it = listOfFaceSubfaces.begin(); it != listOfFaceSubfaces.end(); it++)296{297Face newFace = Face::unite(*it, move.link());298if (newFace.dimension() == this->dimension())299{300_moves[0].push_back(std::make_pair(BistellarMove(newFace, Face()),true));301}302else303{304face_list_t listOfLinkFaces;305for (face_list_t::iterator it2 = listOfNewFacets.begin(); it2 != listOfNewFacets.end(); it2++)306{307if (newFace.isSubfaceOf(*it2))308listOfLinkFaces.push_back(*it2);309}310if (listOfLinkFaces.size() == this->dimension() - newFace.dimension() + 1)311{312Face linkFace = Face::linkFace(newFace, listOfLinkFaces);313if (linkFace.dimension() <= this->dimension())314_moves[this->dimension() - newFace.dimension()].push_back(std::make_pair(BistellarMove(newFace, linkFace), false));315}316}317}318319face_list_t listOfBallBounaryFaces;320if (!listOfNewFacets.empty())321{322for (face_list_t::iterator it = listOfNewFacets.begin(); it != listOfNewFacets.end(); it++)323{324face_list_t listOfNewFacetSubfaces;325addSubfacesOfFace(*it, listOfNewFacetSubfaces);326if (!listOfNewFacetSubfaces.empty())327{328for (face_list_t::iterator it2 = listOfNewFacetSubfaces.begin(); it2 != listOfNewFacetSubfaces.end(); it2++)329{330if ((listOfBallInteriorFaces.empty() || std::find(listOfBallInteriorFaces.begin(), listOfBallInteriorFaces.end(), *it2) == listOfBallInteriorFaces.end())331&& (listOfBallBounaryFaces.empty() || std::find(listOfBallBounaryFaces.begin(), listOfBallBounaryFaces.end(), *it2) == listOfBallBounaryFaces.end()))332listOfBallBounaryFaces.push_back(*it2);333}334}335}336}337338updateBallBoundary(*this, listOfBallBounaryFaces);339}340}341342updateMoveValidity(*this);343344#ifdef Bistellar_debug_output345std::cout << "Resulting complex is ";346list_print(std::cout, _faces[_dimension].begin(), _faces[_dimension].end());347std::cout << "." << std::endl;348for (int i = 0; i < _dimension+1; i++)349{350std::cout << _moves[i].size() << " " << i << "-Moves: ";351if (!_moves[i].empty()) list_print(std::cout, _moves[i].begin(), _moves[i].end());352std::cout << std::endl;353}354#endif355}356else357{358#ifdef Bistellar_debug_output359std::cout << move << " is not a valid move for the complex " << *this << std::endl;360#endif361}362}363364// used in the implementation of moveComplex365void updateBallBoundary(MovableComplex & complex, const face_list_t & ballBoundaryFaces)366{367if (!ballBoundaryFaces.empty())368{369for (face_list_t::const_iterator it = ballBoundaryFaces.begin(); it != ballBoundaryFaces.end(); it++)370{371face_list_t linkFacets;372// copy all facets that contain (*it) as a subface to linkFacets373if (!complex._faces[complex._dimension].empty())374{375for (face_list_t::const_iterator it2 = complex._faces[complex._dimension].begin(); it2 != complex._faces[complex._dimension].end(); it2++)376{377if (it->isSubfaceOf(*it2))378linkFacets.push_back(*it2);379}380}381382// remove the move option with (*it) as face383if (!complex._moves[complex._dimension - it->dimension()].empty())384{385if (!complex._moves[complex._dimension - it->dimension()].empty())386{387for (bistellar_move_option_list_t::iterator mIt = complex._moves[complex._dimension - it->dimension()].begin(); mIt != complex._moves[complex._dimension - it->dimension()].end(); mIt++)388{389if (mIt->first.face() == *it)390{391complex._moves[complex._dimension - it->dimension()].erase(mIt);392break;393}394}395}396}397398399if (linkFacets.size() == complex._dimension - it->dimension() + 1)400{401// add the move option.402Face linkFace = Face::linkFace(*it, linkFacets);403if (linkFace.dimension() <= complex._dimension)404complex._moves[complex._dimension - it->dimension()].push_back(std::make_pair(BistellarMove(*it, linkFace), (std::find(complex._faces[linkFace.dimension()].begin(), complex._faces[linkFace.dimension()].end(), linkFace) == complex._faces[linkFace.dimension()].end())));405}406}407}408}409void updateMoveValidity(MovableComplex & complex)410{411for (unsigned int i = 1; i < complex._dimension + 1; i++)412{413if (!complex._moves[i].empty())414{415for (bistellar_move_option_list_t::iterator it = complex._moves[i].begin(); it != complex._moves[i].end(); it++)416it->second = (std::find(complex._faces[it->first.link().dimension()].begin(), complex._faces[it->first.link().dimension()].end(), it->first.link()) == complex._faces[it->first.link().dimension()].end());417}418}419}420421// serialization methods422std::ostream & operator<< (std::ostream & os, const MovableComplex & complex)423{424if (!complex._faces[complex._dimension].empty())425{426list_print(os ,complex._faces[complex._dimension].begin(), complex._faces[complex._dimension].end());427}428else429{430os << "[]";431}432return os;433}434std::istream & operator>> (std::istream & is, MovableComplex & complex)435{436std::deque< Face > facets;437list_read(is, facets);438439if (facets.empty())440{441complex = MovableComplex();442}443else444{445complex = MovableComplex(facets, facets.begin()->dimension());446}447448return is;449}450451452