1 /*
2 4ti2 -- A software package for algebraic, geometric and combinatorial
3 problems on linear spaces.
4
5 Copyright (C) 2006 4ti2 team.
6 Main author(s): Peter Malkin.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23 #include "WalkAlgorithm.h"
24 #include "Completion.h"
25 #include "VectorStream.h"
26 #include "VectorArrayStream.h"
27 #include "BinomialSet.h"
28 #include "BinomialSetStream.h"
29 #include "FlipCompletion.h"
30 #include "BinomialFactory.h"
31 #include "Globals.h"
32
33 #include <iostream>
34 #include <iomanip>
35 #include <cstdlib>
36
37 //#define DEBUG_4ti2(X) X
38 #include "Debug.h"
39
40 using namespace _4ti2_;
41
WalkAlgorithm()42 WalkAlgorithm::WalkAlgorithm()
43 {
44 costnew_start = 0;
45 costnew_end = 0;
46 costold_start = 0;
47 costold_end = 0;
48 }
49
~WalkAlgorithm()50 WalkAlgorithm::~WalkAlgorithm()
51 {
52 }
53
54 void
compute(Feasible & feasible,const VectorArray & costold,VectorArray & vs,const VectorArray & costnew)55 WalkAlgorithm::compute(
56 Feasible& feasible,
57 const VectorArray& costold,
58 VectorArray& vs,
59 const VectorArray& costnew)
60 {
61 DEBUG_4ti2(*out << "Cost1:\n" << costold << "\n";)
62 DEBUG_4ti2(*out << "Cost2:\n" << costnew << "\n";)
63 DEBUG_4ti2(*out << "VS:\n" << vs << "\n";)
64 assert(costold.get_number() > 0 && costnew.get_number() > 0);
65 t.reset();
66
67 // TODO: We might need to add cost vectors to the old and new costs.
68 VectorArray costall(costnew);
69 costall.insert(costold);
70
71 BinomialFactory factory(feasible, costall);
72
73 costnew_start = Binomial::cost_start;
74 costnew_end = Binomial::cost_start+costnew.get_number();
75 costold_start = costnew_end;
76 costold_end = Binomial::cost_end;
77
78 BinomialSet bs;
79 factory.convert(vs, bs, false);
80
81 TermOrder term_order(costnew_start, costnew_end, Binomial::rs_end);
82
83 // TODO: Perhaps the following value should be an command line option.
84 const int reduction_freq = 200;
85
86 int iteration = 0;
87 DEBUG_4ti2(*out << "\nBefore BINOMIALS:\n" << bs << "\n";)
88 int n;
89 Binomial b;
90 FlipCompletion alg;
91 while(!next(bs, term_order, n))
92 {
93 if (iteration % Globals::output_freq == 0)
94 {
95 *out << "\r";
96 *out << std::setiosflags(std::ios_base::right);
97 *out << "Iteration = " << std::setw(6) << iteration;
98 *out << " Size = " << std::setw(6) << bs.get_number();
99 *out << " tvalue " << std::setw(6) << std::setprecision(4);
100 *out << std::resetiosflags(std::ios_base::right);
101 *out << std::setiosflags(std::ios_base::left);
102 *out << tvalue(bs[n]) << std::flush;
103 *out << std::resetiosflags(std::ios_base::left);
104 }
105 DEBUG_4ti2(*out << "Iteration " << iteration << "\n";)
106 DEBUG_4ti2(*out << "\nBefore BINOMIALS:\n" << bs << "\n";)
107 b = bs[n];
108 bs.remove(n);
109 if (!bs.reducable(b))
110 {
111 b.flip();
112 alg.algorithm(bs, b);
113 bs.add(b);
114 if (iteration % reduction_freq == 0)
115 { bs.minimal(); bs.reduced(); }
116 DEBUG_4ti2(*out << "Size: " << std::setw(6) << bs.get_number() << "\n";)
117 DEBUG_4ti2(*out << "After BINOMIALS:\n" << bs << "\n";)
118 ++iteration;
119 }
120 }
121 bs.minimal();
122 bs.reduced();
123 factory.convert(bs, vs);
124 vs.sort();
125 bs.clear();
126
127 DEBUG_4ti2(*out << "VS:\n" << vs << "\n";)
128 *out << "\r" << Globals::context;
129 *out << "Iteration = " << std::setw(6) << iteration;
130 *out << " Size: " << std::setw(6) << vs.get_number();
131 *out << ", Time: " << t << " / ";
132 *out << Timer::global << " secs. Done." << std::endl;
133 }
134
135 IntegerType
compare(const Binomial & b1,const Binomial & b2)136 WalkAlgorithm::compare(const Binomial& b1, const Binomial& b2)
137 {
138 IntegerType result;
139 for (int i = costnew_start; i < costnew_end; ++i)
140 {
141 for (int j = costold_start; j < costold_end; ++j)
142 {
143 result = b1[j]*b2[i]-b1[i]*b2[j];
144 if (result != 0) { return result; }
145 }
146 for (int j = 0; j < Binomial::rs_end; j++)
147 {
148 result = -b1[j]*b2[i]+b1[i]*b2[j];
149 if (result != 0) { return result; }
150 }
151 }
152 for (int i = 0; i < Binomial::rs_end; i++)
153 {
154 for (int j = costold_start; j < costold_end; ++j)
155 {
156 result = -b1[j]*b2[i]+b1[i]*b2[j];
157 if (result != 0) { return result; }
158 }
159 for (int j = 0; j < Binomial::rs_end; j++)
160 {
161 result = b1[j]*b2[i]-b1[i]*b2[j];
162 if (result != 0) { return result; }
163 }
164 }
165 std::cerr << "Software Error: unexpected execution.\n";
166 exit(1);
167 return 0;
168 }
169
170 RationalType
tvalue(const Binomial & b)171 WalkAlgorithm::tvalue(const Binomial& b)
172 {
173 if (b[costold_start]-b[costnew_start] == 0)
174 return 0; // Avoid division by zero
175 else
176 return (RationalType)b[costold_start]/(b[costold_start]-b[costnew_start]);
177 }
178
179 void
tvector(Vector & c1,Vector & c2,Vector & v,Vector & tv)180 WalkAlgorithm::tvector(Vector& c1, Vector& c2, Vector& v, Vector& tv)
181 {
182 Vector::sub(c2, Vector::dot(c1,v), c1, Vector::dot(c2,v), tv);
183 }
184
185 bool
next(const BinomialSet & bs,const TermOrder & term_order,int & min)186 WalkAlgorithm::next(const BinomialSet& bs, const TermOrder& term_order, int& min)
187 {
188 min = 0;
189 while (min < bs.get_number())
190 {
191 if (TermOrder::direction(term_order, bs[min]) < 0) { break; }
192 else { ++min; }
193 }
194 if (min == bs.get_number()) { return true; }
195 DEBUG_4ti2(*out << min << " tvalue = " << tvalue(bs[min]) << "\n";)
196 for (int i = min+1; i < bs.get_number(); ++i)
197 {
198 if (TermOrder::direction(term_order, bs[i]) < 0)
199 {
200 DEBUG_4ti2(*out << i << " tvalue = " << tvalue(bs[i]) << "\n";)
201 if (compare(bs[min], bs[i]) < 0) { min = i; }
202 }
203 }
204 DEBUG_4ti2(*out << min << " min tvalue = " << tvalue(bs[min]) << "\n";)
205 return false;
206 }
207