politopix  5.0.0
IO_Polytope.cpp
Go to the documentation of this file.
1 // politopix allows to make computations on polytopes such as finding vertices, intersecting, Minkowski sums, ...
2 // Copyright (C) 2011-2015 : Delos Vincent
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
19 // I2M (UMR CNRS 5295 / University of Bordeaux)
20 
21 #include <cmath>
22 #include "Rn.h"
23 #include "IO_Polytope.h"
24 
25 
26 void IO_Polytope::load(const std::string& filename, boost::shared_ptr<PolyhedralCone_Rn> POLY) {
27 
28  int dimension, numberOfGenerators, numberOfHalfSpaces;
29  std::ifstream file(filename.c_str(), std::ifstream::in);
30 
31  if (!file) {
32  std::string s("Unable to open ");
33  s += filename;
34  s += "\n";
35  throw std::ios_base::failure(s);
36  }
37 
38  // Temp array to store constraints.
39  std::vector< boost::shared_ptr<HalfSpace_Rn> > HSvect;
40  std::string line;
41  // Read the comment line.
42  std::getline(file,line);
43  // Get the 3 integers : space dimension, number of generators and facets.
44  std::getline(file,line);
45  std::istringstream iline(line);
46  iline >> dimension;
47  iline >> numberOfHalfSpaces;
48  iline >> numberOfGenerators;
49  double val;
51  // Facets block //
53  if (numberOfHalfSpaces != 0) {
54  // Read the comment line.
55  std::getline(file,line);
56  // H : a0 + a1.x1 + ... + an.xn >= 0.
57  boost::shared_ptr<HalfSpace_Rn> HS;
58  for (int hyp_count=0; hyp_count<numberOfHalfSpaces; hyp_count++) {
59  HS.reset(new HalfSpace_Rn(dimension));
60  std::getline(file,line);
61  std::istringstream iline3(line);
62  // The second member b
63  iline3 >> val;
64  HS->setConstant(val);
65  // The normal vector
66  for (int coord_count=0; coord_count<dimension; coord_count++) {
67  iline3 >> val;
68  HS->setCoefficient(coord_count, val);
69  }
70  POLY->addHalfSpace(HS);
71  HSvect.push_back(HS);
72  }
73  }
74  // When we only have the half-spaces, use the truncating algorithm to compute the generators.
75  if (numberOfGenerators == 0) {
76  file.close();
77  return;
78  }
79  else {
81  // Generators block //
83  // Read the comment line.
84  std::getline(file,line);
85  // V = (v1, ..., vn)
86  boost::shared_ptr<Generator_Rn> VX;
87  for (int vtx_count=0; vtx_count<numberOfGenerators; vtx_count++) {
88  VX.reset(new Generator_Rn(dimension));
89  std::getline(file,line);
90  std::istringstream iline2(line);
91  VX->load(iline2);
92  //for (int coord_count=0; coord_count<dimension; coord_count++) {
93  //iline2 >> val;
94  //std::cout << "val=" << val << " ";
95  //VX->setCoordinate(coord_count, val);
96  //}
97  POLY->addGenerator(VX);
98  }
100  // Facets per vertex block //
102  if (numberOfHalfSpaces != 0 && numberOfGenerators != 0) {
103  // Read the comment line.
104  std::getline(file,line);
105  // {Fi1, Fi2, ... }
106  for (int vtx_count=0; vtx_count<numberOfGenerators; vtx_count++) {
107  VX = POLY->getGenerator(vtx_count);
108  std::string lineOfFacets;
109  std::getline(file, lineOfFacets);
110  std::istringstream stream(lineOfFacets);
111  int facetForGenerator;
112  while (stream >> facetForGenerator) {
113  if (facetForGenerator < 0 || facetForGenerator >= numberOfHalfSpaces) {
114  std::ostringstream stream_;
115  stream_ << "Facet number ";
116  stream_ << facetForGenerator;
117  stream_ << " is outside the range [0, ";
118  stream_ << numberOfHalfSpaces;
119  stream_ << "] in function IO_Polytope::load() ";
120  std::string valString = stream_.str();
121  throw std::out_of_range(valString);
122  }
123  boost::shared_ptr<HalfSpace_Rn> Fi = HSvect[facetForGenerator];
124  VX->setFacet(Fi);
125  }
126  }
127  }
128  }
129  file.close();
130 }
131 
132 void IO_Polytope::save(const std::string& filename, boost::shared_ptr<PolyhedralCone_Rn> POLY) {
133  std::ofstream ofs(filename.c_str());
134 
135  if (!ofs) {
136  std::string s("Unable to open ");
137  s += filename;
138  s += "\n";
139  throw std::ios_base::failure(s);
140  }
141 
142  // Make sure we print on the stream values consistent with the tolerance in use.
143  ofs.precision(15);
144 
145  ofs << "# Dimension NumberOfHalfspaces NumberOfGenerators" << std::endl;
146  ofs << POLY->dimension() << " ";
147  ofs << POLY->numberOfHalfSpaces() << " ";
148  ofs << POLY->numberOfGenerators() << std::endl;
150  // Facet block //
152  if (POLY->numberOfHalfSpaces() != 0) {
153  ofs << "# HALFSPACES : a0 + a1.x1 + ... + an.xn >= 0." << std::endl;
154  // H : a0 + a1.x1 + ... + an.xn >= 0.
156  iteHS(POLY->getListOfHalfSpaces());
157  for (iteHS.begin(); iteHS.end()!=true; iteHS.next()) {
158  boost::shared_ptr<HalfSpace_Rn> HS = iteHS.current();
159  // The second member b
160  ofs << HS->getConstant() << " ";
161  for (unsigned int coord_count=0; coord_count<POLY->dimension(); coord_count++) {
162  ofs << HS->getCoefficient(coord_count) << " ";
163  }
164  ofs << std::endl;
165  }
166  }
167  ofs << "# GENERATORS : V = (v1, ..., vn)" << std::endl;
169  // Generator block //
171  // V = (v1, ..., vn)
172  boost::shared_ptr<Generator_Rn> VX;
173  for (unsigned int vtx_count=0; vtx_count<POLY->numberOfGenerators(); vtx_count++) {
174  VX = POLY->getGenerator(vtx_count);
175  VX->save(ofs);
176  //for (unsigned int coord_count=0; coord_count<Rn::getDimension(); coord_count++) {
177  //ofs << VX->getCoordinate(coord_count) << " ";
178  //}
179  ofs << std::endl;
180  }
182  // Facets per vertex block //
184  if (POLY->numberOfHalfSpaces() != 0) {
185  ofs << "# GENERATOR CONNECTION : Ha, Hb, ..." << std::endl;
186  // {Fi1, Fi2, ... }
187  for (unsigned int vtx_count=0; vtx_count<POLY->numberOfGenerators(); vtx_count++) {
188  VX = POLY->getGenerator(vtx_count);
189  for (unsigned int ngb_count=0; ngb_count<VX->numberOfFacets(); ngb_count++) {
190  boost::shared_ptr<HalfSpace_Rn> Fi = VX->getFacet(ngb_count);
191  ofs << POLY->getHalfSpaceNumber(Fi) << " ";
192  }
193  ofs << std::endl;
194  }
195  }
196  ofs.close();
197 }
constIteratorOfListOfGeometricObjects::current
const GEOMETRIC_OBJECT current()
Return the current geometric element.
Definition: GeometricObjectIterator_Rn.h:177
constIteratorOfListOfGeometricObjects::end
bool end() const
Tell whether we have reached the end of the list.
Definition: GeometricObjectIterator_Rn.h:174
HalfSpace_Rn
A half-space whose frontier is a linear (n-1) dimension space. _constant + _coefficients[0]....
Definition: HalfSpace_Rn.h:40
Rn.h
constIteratorOfListOfGeometricObjects
This class is designed to run the list of all geometric objects representing a polytope.
Definition: GeometricObjectIterator_Rn.h:142
Generator_Rn
A n-coordinates generator, which can be a vertex or an edge whether it is contained by a polytope or ...
Definition: Generator_Rn.h:39
constIteratorOfListOfGeometricObjects::begin
void begin()
Move the iterator at the beginning of the list.
Definition: GeometricObjectIterator_Rn.h:150
IO_Polytope::load
static polito_EXPORT void load(const std::string &filename, boost::shared_ptr< PolyhedralCone_Rn > POLY)
Load the main data format to store polytopes.
Definition: IO_Polytope.cpp:26
IO_Polytope.h
constIteratorOfListOfGeometricObjects::next
void next()
Move the iterator one step forward.
Definition: GeometricObjectIterator_Rn.h:153
IO_Polytope::save
static polito_EXPORT void save(const std::string &filename, boost::shared_ptr< PolyhedralCone_Rn > POLY)
Save the polytope to the main data format.
Definition: IO_Polytope.cpp:132