politopix  4.1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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 Lesser 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 Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser 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  throw (std::ios_base::failure,std::out_of_range) {
28 
29  int dimension, numberOfGenerators, numberOfHalfSpaces;
30  std::ifstream file(filename.c_str(), std::ifstream::in);
31 
32  if (!file) {
33  std::string s("Unable to open ");
34  s += filename;
35  s += "\n";
36  throw std::ios_base::failure(s);
37  }
38 
39  // Temp array to store constraints.
40  std::vector< boost::shared_ptr<HalfSpace_Rn> > HSvect;
41  std::string line;
42  // Read the comment line.
43  std::getline(file,line);
44  // Get the 3 integers : space dimension, number of generators and facets.
45  std::getline(file,line);
46  std::istringstream iline(line);
47  iline >> dimension;
48  iline >> numberOfHalfSpaces;
49  iline >> numberOfGenerators;
50  double val;
52  // Facets block //
54  if (numberOfHalfSpaces != 0) {
55  // Read the comment line.
56  std::getline(file,line);
57  // H : a0 + a1.x1 + ... + an.xn >= 0.
58  boost::shared_ptr<HalfSpace_Rn> HS;
59  for (int hyp_count=0; hyp_count<numberOfHalfSpaces; hyp_count++) {
60  HS.reset(new HalfSpace_Rn(dimension));
61  std::getline(file,line);
62  std::istringstream iline3(line);
63  // The second member b
64  iline3 >> val;
65  HS->setConstant(val);
66  // The normal vector
67  for (int coord_count=0; coord_count<dimension; coord_count++) {
68  iline3 >> val;
69  HS->setCoefficient(coord_count, val);
70  }
71  POLY->addHalfSpace(HS);
72  HSvect.push_back(HS);
73  }
74  }
75  // When we only have the half-spaces, use the truncating algorithm to compute the generators.
76  if (numberOfGenerators == 0) {
77  file.close();
78  return;
79  }
80  else {
82  // Generators block //
84  // Read the comment line.
85  std::getline(file,line);
86  // V = (v1, ..., vn)
87  boost::shared_ptr<Generator_Rn> VX;
88  for (int vtx_count=0; vtx_count<numberOfGenerators; vtx_count++) {
89  VX.reset(new Generator_Rn(dimension));
90  std::getline(file,line);
91  std::istringstream iline2(line);
92  VX->load(iline2);
93  //for (int coord_count=0; coord_count<dimension; coord_count++) {
94  //iline2 >> val;
95  //std::cout << "val=" << val << " ";
96  //VX->setCoordinate(coord_count, val);
97  //}
98  POLY->addGenerator(VX);
99  }
101  // Facets per vertex block //
103  if (numberOfHalfSpaces != 0 && numberOfGenerators != 0) {
104  // Read the comment line.
105  std::getline(file,line);
106  // {Fi1, Fi2, ... }
107  for (int vtx_count=0; vtx_count<numberOfGenerators; vtx_count++) {
108  VX = POLY->getGenerator(vtx_count);
109  std::string lineOfFacets;
110  std::getline(file, lineOfFacets);
111  std::istringstream stream(lineOfFacets);
112  int facetForGenerator;
113  while (stream >> facetForGenerator) {
114  if (facetForGenerator < 0 || facetForGenerator >= numberOfHalfSpaces) {
115  std::ostringstream stream_;
116  stream_ << "Facet number ";
117  stream_ << facetForGenerator;
118  stream_ << " is outside the range [0, ";
119  stream_ << numberOfHalfSpaces;
120  stream_ << "] in function IO_Polytope::load() ";
121  std::string valString = stream_.str();
122  throw std::out_of_range(valString);
123  }
124  boost::shared_ptr<HalfSpace_Rn> Fi = HSvect[facetForGenerator];
125  VX->setFacet(Fi);
126  }
127  }
128  }
129  }
130  file.close();
131 }
132 
133 void IO_Polytope::save(const std::string& filename, boost::shared_ptr<PolyhedralCone_Rn> POLY) throw (std::ios_base::failure) {
134  std::ofstream ofs(filename.c_str());
135 
136  if (!ofs) {
137  std::string s("Unable to open ");
138  s += filename;
139  s += "\n";
140  throw std::ios_base::failure(s);
141  }
142 
143  // Make sure we print on the stream values consistent with the tolerance in use.
144  ofs.precision(15);
145 
146  ofs << "# Dimension NumberOfHalfspaces NumberOfGenerators" << std::endl;
147  ofs << POLY->dimension() << " ";
148  ofs << POLY->numberOfHalfSpaces() << " ";
149  ofs << POLY->numberOfGenerators() << std::endl;
151  // Facet block //
153  if (POLY->numberOfHalfSpaces() != 0) {
154  ofs << "# HALFSPACES : a0 + a1.x1 + ... + an.xn >= 0." << std::endl;
155  // H : a0 + a1.x1 + ... + an.xn >= 0.
157  iteHS(POLY->getListOfHalfSpaces());
158  for (iteHS.begin(); iteHS.end()!=true; iteHS.next()) {
159  boost::shared_ptr<HalfSpace_Rn> HS = iteHS.current();
160  // The second member b
161  ofs << HS->getConstant() << " ";
162  for (unsigned int coord_count=0; coord_count<POLY->dimension(); coord_count++) {
163  ofs << HS->getCoefficient(coord_count) << " ";
164  }
165  ofs << std::endl;
166  }
167  }
168  ofs << "# GENERATORS : V = (v1, ..., vn)" << std::endl;
170  // Generator block //
172  // V = (v1, ..., vn)
173  boost::shared_ptr<Generator_Rn> VX;
174  for (unsigned int vtx_count=0; vtx_count<POLY->numberOfGenerators(); vtx_count++) {
175  VX = POLY->getGenerator(vtx_count);
176  VX->save(ofs);
177  //for (unsigned int coord_count=0; coord_count<Rn::getDimension(); coord_count++) {
178  //ofs << VX->getCoordinate(coord_count) << " ";
179  //}
180  ofs << std::endl;
181  }
183  // Facets per vertex block //
185  if (POLY->numberOfHalfSpaces() != 0) {
186  ofs << "# GENERATOR CONNECTION : Ha, Hb, ..." << std::endl;
187  // {Fi1, Fi2, ... }
188  for (unsigned int vtx_count=0; vtx_count<POLY->numberOfGenerators(); vtx_count++) {
189  VX = POLY->getGenerator(vtx_count);
190  for (unsigned int ngb_count=0; ngb_count<VX->numberOfFacets(); ngb_count++) {
191  boost::shared_ptr<HalfSpace_Rn> Fi = VX->getFacet(ngb_count);
192  ofs << POLY->getHalfSpaceNumber(Fi) << " ";
193  }
194  ofs << std::endl;
195  }
196  }
197  ofs.close();
198 }
A half-space whose frontier is a linear (n-1) dimension space. _constant + _coefficients[0].x1 + ... + _coefficients[n-1].xn >= 0.
Definition: HalfSpace_Rn.h:37
const GEOMETRIC_OBJECT current()
Return the current geometric element.
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
static polito_EXPORT void save(const std::string &filename, boost::shared_ptr< PolyhedralCone_Rn > POLY)
Save the polytope to the main data format.
A n-coordinates generator, which can be a vertex or an edge whether it is contained by a polytope or ...
Definition: Generator_Rn.h:38
This class is designed to run the list of all geometric objects representing a polytope.