1 /* TriangulationWithTOPCOM.cpp -- Compute a triangulation using TOPCOM
2
3 Copyright 2006 Matthias Koeppe
4 Derived from the TOPCOM source files points2placingtriang.cc, ComputeTriangs.cc
5 which are copyright 1999 Joerg Rambau
6
7 This file is part of LattE.
8
9 LattE is free software; you can redistribute it and/or modify it
10 under the terms of the version 2 of the GNU General Public License
11 as published by the Free Software Foundation.
12
13 LattE is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with LattE; if not, write to the Free Software Foundation,
20 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 */
22
23 #include <list>
24 #include <iostream>
25 #include "config.h"
26 #include "triangulation/TriangulationWithTOPCOM.h"
27 #include "latte_gmp.h"
28 #include "latte_system.h"
29 #ifdef HAVE_TOPCOM_LIB
30 #include <Matrix.hh>
31 #include <PointConfiguration.hh>
32 #include <PlacingTriang.hh>
33 #include <Symmetry.hh>
34 #include <SymmetricBFS.hh>
35 #endif
36
37 using namespace std;
38
39 static vector<listVector *>
ray_array(listCone * cone)40 ray_array(listCone *cone)
41 {
42 int num_rays = lengthListVector(cone->rays);
43 vector<listVector *> rays(num_rays);
44 int j;
45 listVector *ray;
46 for (j = 0, ray = cone->rays; ray!=NULL; j++, ray = ray->rest)
47 rays[j] = ray;
48 return rays;
49 }
50
51
52 //
53 // Functions using the TOPCOM library.
54 //
55 #ifdef HAVE_TOPCOM_LIB
56 static void
triangulation_to_cones(const SimplicialComplex & sc,listCone * cone,ConeConsumer & consumer)57 triangulation_to_cones(const SimplicialComplex &sc,
58 listCone *cone,
59 ConeConsumer &consumer)
60 {
61 // Copy rays into an array, so we can index them.
62 vector<listVector *> rays = ray_array(cone);
63 // Iterate through simplices and collect them.
64 for (SimplicialComplex::const_iterator i = sc.begin(); i!=sc.end(); ++i) {
65 const Simplex &simplex = *i;
66 listCone *c = createListCone();
67 c->vertex = new Vertex(*cone->vertex);
68 for (Simplex::const_iterator j = simplex.begin(); j!=simplex.end(); ++j) {
69 size_t index = *j;
70 c->rays = new listVector(rays[index]->first, c->rays);
71 }
72 consumer.ConsumeCone(c);
73 }
74 }
75
76 static PointConfiguration
cone_to_point_configuration(listCone * cone,int numOfVars)77 cone_to_point_configuration(listCone *cone, int numOfVars)
78 {
79 int num_rays = lengthListVector(cone->rays);
80 Matrix matrix(numOfVars, num_rays);
81 size_type i, j;
82 listVector *ray;
83 for (j = 0, ray = cone->rays; ray!=NULL; j++, ray = ray->rest) {
84 for (i = 0; i<numOfVars; i++) {
85 mpz_class mpz = convert_ZZ_to_mpz(ray->first[i]);
86 matrix(i, j) = Rational(mpz.get_mpz_t());
87 }
88 }
89 PointConfiguration points(matrix);
90 return points;
91 }
92
93 void
triangulate_cone_with_TOPCOM(listCone * cone,int numOfVars,ConeConsumer & consumer)94 triangulate_cone_with_TOPCOM(listCone *cone, int numOfVars, ConeConsumer &consumer)
95 {
96 PointConfiguration points = cone_to_point_configuration(cone, numOfVars);
97 if (points.rank() > points.no()) {
98 std::cerr << "rank must not be larger than no of points." << std::endl;
99 exit(1);
100 }
101 Chirotope chiro(points, /*preprocess:*/ false);
102 PlacingTriang triang(chiro);
103 // std::cout << "Triangulation: " << triang << std::endl;
104 triangulation_to_cones(triang, cone, consumer);
105 }
106 #endif
107
108
109 //
110 // Functions using the TOPCOM binaries
111 //
112
113 #ifdef HAVE_TOPCOM_BIN
114
115 static void
read_TOPCOM_triangulation(istream & in,listCone * cone,ConeConsumer & consumer)116 read_TOPCOM_triangulation(istream &in,
117 listCone *cone,
118 ConeConsumer &consumer)
119 {
120 // Copy rays into an array, so we can index them.
121 vector<listVector *> rays = ray_array(cone);
122 // Read a triangulation in the TOPCOM format:
123 // T[1]:={{0,1,2,3,4,5,6,8},{0,1,2,3,4,5,7,8}};
124 char c;
125 // Find and consume left brace of triangulation.
126 do { in.get(c); } while (in.good() && c != '{');
127 bool result = false;
128 do {
129 // Consume left brace of simplex.
130 in.get(c);
131 if (!(in.good() && c == '{')) break;
132 listCone *simp = createListCone();
133 simp->vertex = new Vertex(*cone->vertex);
134 while (in.good() && in.peek()!='}') {
135 int index;
136 in >> index;
137 simp->rays = new listVector(rays[index]->first, simp->rays);
138 // Skip the ',' of simplex.
139 if (in.peek()==',') in.get(c);
140 }
141 consumer.ConsumeCone(simp);
142 if (!in.good()) break;
143 // Consume the '}' of simplex.
144 in.get(c);
145 // Expect ',' or '}' of triangulation.
146 in.get(c);
147 if (!in.good()) break;
148 if (c == '}') return;
149 } while (c == ',');
150 // Error situation:
151 cerr << "Failed to read triangulation from TOPCOM output" << endl;
152 exit(1);
153 }
154
155 static void
write_TOPCOM_point_configuration(ostream & out,listCone * cone,int numOfVars)156 write_TOPCOM_point_configuration(ostream &out,
157 listCone *cone, int numOfVars)
158 {
159 out << "[";
160 listVector *ray;
161 for (ray = cone->rays; ray!=NULL; ray=ray->rest) {
162 out << "[";
163 int i;
164 out << ray->first[0];
165 for (i = 1; i<numOfVars; i++)
166 out << ", " << ray->first[i];
167 out << "]";
168 if (ray->rest != NULL)
169 out << "," << endl;
170 }
171 out << "]" << endl;
172 }
173
174 #ifndef HAVE_TOPCOM_LIB
175 // Alternative implementation if the TOPCOM library cannot be used.
176 void
triangulate_cone_with_TOPCOM(listCone * cone,int numOfVars,ConeConsumer & consumer)177 triangulate_cone_with_TOPCOM(listCone *cone, int numOfVars, ConeConsumer &consumer)
178 {
179 string topcom_input_file_name = temporary_file_name("topcom_input");
180 string topcom_output_file_name = temporary_file_name("topcom_output");
181 {
182 ofstream topcom_input(topcom_input_file_name.c_str());
183 write_TOPCOM_point_configuration(topcom_input, cone, numOfVars);
184 }
185 system_with_error_check(TOPCOM_POINTS2PLACINGTRIANG " < " + topcom_input_file_name
186 + " > " + topcom_output_file_name);
187 ifstream topcom_output(topcom_output_file_name.c_str());
188 read_TOPCOM_triangulation(topcom_output, cone, consumer);
189 }
190 #endif
191
192 list<listCone *>
all_triangulations_of_cone_with_TOPCOM(listCone * cone,int numOfVars)193 all_triangulations_of_cone_with_TOPCOM(listCone *cone, int numOfVars)
194 {
195 string topcom_input_file_name = temporary_file_name("topcom_input");
196 string topcom_output_file_name = temporary_file_name("topcom_output");
197 {
198 ofstream topcom_input(topcom_input_file_name.c_str());
199 write_TOPCOM_point_configuration(topcom_input, cone, numOfVars);
200 }
201 system_with_error_check(TOPCOM_POINTS2TRIANGS " < " + topcom_input_file_name
202 + " > " + topcom_output_file_name);
203 ifstream topcom_output(topcom_output_file_name.c_str());
204 list<listCone *> triangulations;
205 while (topcom_output.good()) {
206 CollectingConeConsumer ccc;
207 read_TOPCOM_triangulation(topcom_output, cone, ccc);
208 listCone *triangulation = ccc.Collected_Cones;
209 if (!triangulation) break;
210 triangulations.push_front(triangulation);
211 }
212 return triangulations;
213 }
214
215 #endif
216