doc: document Polyhedron_Reduced_Basis and Polyhedron_Sample
[barvinok.git] / dpoly.cc
blobccc95d15b03693ecf4dc96f23115af1a4ba99564
1 #include <iostream>
2 #include <vector>
3 #include "dpoly.h"
5 using std::cerr;
6 using std::endl;
7 using std::vector;
9 dpoly::dpoly(int d, ZZ& degree, int offset)
11 coeff.SetLength(d+1);
13 int min = d + offset;
14 if (degree >= 0 && degree < ZZ(INIT_VAL, min))
15 min = to_int(degree);
17 ZZ c = ZZ(INIT_VAL, 1);
18 if (!offset)
19 coeff[0] = c;
20 for (int i = 1; i <= min; ++i) {
21 c *= (degree -i + 1);
22 c /= i;
23 coeff[i-offset] = c;
27 void dpoly::operator *= (dpoly& f)
29 assert(coeff.length() == f.coeff.length());
30 vec_ZZ old = coeff;
31 coeff = f.coeff[0] * coeff;
32 for (int i = 1; i < coeff.length(); ++i)
33 for (int j = 0; i+j < coeff.length(); ++j)
34 coeff[i+j] += f.coeff[i] * old[j];
37 mpq_t *dpoly::div(dpoly& d) const
39 int len = coeff.length();
40 Value tmp;
41 value_init(tmp);
42 mpq_t* c = new mpq_t[coeff.length()];
43 mpq_t qtmp;
44 mpq_init(qtmp);
45 for (int i = 0; i < len; ++i) {
46 mpq_init(c[i]);
47 zz2value(coeff[i], tmp);
48 mpq_set_z(c[i], tmp);
50 for (int j = 1; j <= i; ++j) {
51 zz2value(d.coeff[j], tmp);
52 mpq_set_z(qtmp, tmp);
53 mpq_mul(qtmp, qtmp, c[i-j]);
54 mpq_sub(c[i], c[i], qtmp);
57 zz2value(d.coeff[0], tmp);
58 mpq_set_z(qtmp, tmp);
59 mpq_div(c[i], c[i], qtmp);
61 value_clear(tmp);
62 mpq_clear(qtmp);
64 return c;
67 void dpoly::clear_div(mpq_t *c) const
69 int len = coeff.length();
71 for (int i = 0; i < len; ++i)
72 mpq_clear(c[i]);
73 delete [] c;
76 void dpoly::div(dpoly& d, mpq_t count, ZZ& sign)
78 int len = coeff.length();
79 mpq_t *c = div(d);
81 if (sign == -1)
82 mpq_sub(count, count, c[len-1]);
83 else
84 mpq_add(count, count, c[len-1]);
86 clear_div(c);
89 void dpoly::div(dpoly& d, mpq_t *count, const mpq_t& factor)
91 int len = coeff.length();
92 mpq_t *c = div(d);
94 for (int i = 0; i < len; ++i) {
95 mpq_mul(c[len-1 - i], c[len-1 - i], factor);
96 mpq_add(count[i], count[i], c[len-1 - i]);
99 clear_div(c);
102 void dpoly_r::add_term(int i, int * powers, ZZ& coeff)
104 if (coeff == 0)
105 return;
106 for (int k = 0; k < c[i].size(); ++k) {
107 if (memcmp(c[i][k]->powers, powers, dim * sizeof(int)) == 0) {
108 c[i][k]->coeff += coeff;
109 return;
112 dpoly_r_term *t = new dpoly_r_term;
113 t->powers = new int[dim];
114 memcpy(t->powers, powers, dim * sizeof(int));
115 t->coeff = coeff;
116 c[i].push_back(t);
119 dpoly_r::dpoly_r(int len, int dim)
121 denom = 1;
122 this->len = len;
123 this->dim = dim;
124 c = new vector< dpoly_r_term * > [len];
127 dpoly_r::dpoly_r(dpoly& num, int dim)
129 denom = 1;
130 len = num.coeff.length();
131 c = new vector< dpoly_r_term * > [len];
132 this->dim = dim;
133 int powers[dim];
134 memset(powers, 0, dim * sizeof(int));
136 for (int i = 0; i < len; ++i) {
137 ZZ coeff = num.coeff[i];
138 add_term(i, powers, coeff);
142 dpoly_r::dpoly_r(dpoly& num, dpoly& den, int pos, int dim)
144 denom = 1;
145 len = num.coeff.length();
146 c = new vector< dpoly_r_term * > [len];
147 this->dim = dim;
148 int powers[dim];
150 for (int i = 0; i < len; ++i) {
151 ZZ coeff = num.coeff[i];
152 memset(powers, 0, dim * sizeof(int));
153 powers[pos] = 1;
155 add_term(i, powers, coeff);
157 for (int j = 1; j <= i; ++j) {
158 for (int k = 0; k < c[i-j].size(); ++k) {
159 memcpy(powers, c[i-j][k]->powers, dim*sizeof(int));
160 powers[pos]++;
161 coeff = -den.coeff[j-1] * c[i-j][k]->coeff;
162 add_term(i, powers, coeff);
166 //dump();
169 dpoly_r::dpoly_r(dpoly_r* num, dpoly& den, int pos, int dim)
171 denom = num->denom;
172 len = num->len;
173 c = new vector< dpoly_r_term * > [len];
174 this->dim = dim;
175 int powers[dim];
176 ZZ coeff;
178 for (int i = 0 ; i < len; ++i) {
179 for (int k = 0; k < num->c[i].size(); ++k) {
180 memcpy(powers, num->c[i][k]->powers, dim*sizeof(int));
181 powers[pos]++;
182 add_term(i, powers, num->c[i][k]->coeff);
185 for (int j = 1; j <= i; ++j) {
186 for (int k = 0; k < c[i-j].size(); ++k) {
187 memcpy(powers, c[i-j][k]->powers, dim*sizeof(int));
188 powers[pos]++;
189 coeff = -den.coeff[j-1] * c[i-j][k]->coeff;
190 add_term(i, powers, coeff);
196 dpoly_r::~dpoly_r()
198 for (int i = 0 ; i < len; ++i)
199 for (int k = 0; k < c[i].size(); ++k) {
200 delete [] c[i][k]->powers;
201 delete c[i][k];
203 delete [] c;
206 dpoly_r *dpoly_r::div(dpoly& d)
208 dpoly_r *rc = new dpoly_r(len, dim);
209 rc->denom = power(d.coeff[0], len);
210 ZZ inv_d = rc->denom / d.coeff[0];
211 ZZ coeff;
213 for (int i = 0; i < len; ++i) {
214 for (int k = 0; k < c[i].size(); ++k) {
215 coeff = c[i][k]->coeff * inv_d;
216 rc->add_term(i, c[i][k]->powers, coeff);
219 for (int j = 1; j <= i; ++j) {
220 for (int k = 0; k < rc->c[i-j].size(); ++k) {
221 coeff = - d.coeff[j] * rc->c[i-j][k]->coeff / d.coeff[0];
222 rc->add_term(i, rc->c[i-j][k]->powers, coeff);
226 return rc;
229 void dpoly_r::dump(void)
231 for (int i = 0; i < len; ++i) {
232 cerr << endl;
233 cerr << i << endl;
234 cerr << c[i].size() << endl;
235 for (int j = 0; j < c[i].size(); ++j) {
236 for (int k = 0; k < dim; ++k) {
237 cerr << c[i][j]->powers[k] << " ";
239 cerr << ": " << c[i][j]->coeff << "/" << denom << endl;
241 cerr << endl;