gen_fun::substitute: normalize terms
[barvinok.git] / dpoly.cc
bloba20e0d28b5a84e37dda37874822b189635615c46
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, const vector<int>& powers, const ZZ& coeff)
104 if (coeff == 0)
105 return;
107 dpoly_r_term tmp;
108 tmp.powers = powers;
109 dpoly_r_term_list::iterator k = c[i].find(&tmp);
110 if (k != c[i].end()) {
111 (*k)->coeff += coeff;
112 return;
114 dpoly_r_term *t = new dpoly_r_term;
115 t->powers = powers;
116 t->coeff = coeff;
117 c[i].insert(t);
120 dpoly_r::dpoly_r(int len, int dim)
122 denom = 1;
123 this->len = len;
124 this->dim = dim;
125 c = new dpoly_r_term_list[len];
128 dpoly_r::dpoly_r(dpoly& num, int dim)
130 denom = 1;
131 len = num.coeff.length();
132 c = new dpoly_r_term_list[len];
133 this->dim = dim;
134 vector<int> powers(dim, 0);
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 dpoly_r_term_list[len];
147 this->dim = dim;
148 int powers[dim];
150 for (int i = 0; i < len; ++i) {
151 ZZ coeff = num.coeff[i];
152 vector<int> powers(dim, 0);
153 powers[pos] = 1;
155 add_term(i, powers, coeff);
157 for (int j = 1; j <= i; ++j) {
158 dpoly_r_term_list::iterator k;
159 for (k = c[i-j].begin(); k != c[i-j].end(); ++k) {
160 powers = (*k)->powers;
161 powers[pos]++;
162 coeff = -den.coeff[j-1] * (*k)->coeff;
163 add_term(i, powers, coeff);
167 //dump();
170 dpoly_r::dpoly_r(dpoly_r* num, dpoly& den, int pos, int dim)
172 denom = num->denom;
173 len = num->len;
174 c = new dpoly_r_term_list[len];
175 this->dim = dim;
176 ZZ coeff;
178 for (int i = 0 ; i < len; ++i) {
179 dpoly_r_term_list::iterator k;
180 for (k = num->c[i].begin(); k != num->c[i].end(); ++k) {
181 vector<int> powers = (*k)->powers;
182 powers[pos]++;
183 add_term(i, powers, (*k)->coeff);
186 for (int j = 1; j <= i; ++j) {
187 dpoly_r_term_list::iterator k;
188 for (k = c[i-j].begin(); k != c[i-j].end(); ++k) {
189 vector<int> powers = (*k)->powers;
190 powers[pos]++;
191 coeff = -den.coeff[j-1] * (*k)->coeff;
192 add_term(i, powers, coeff);
198 dpoly_r::~dpoly_r()
200 for (int i = 0 ; i < len; ++i)
201 for (dpoly_r_term_list::iterator k = c[i].begin(); k != c[i].end(); ++k) {
202 delete (*k);
204 delete [] c;
207 dpoly_r *dpoly_r::div(dpoly& d)
209 dpoly_r *rc = new dpoly_r(len, dim);
210 rc->denom = power(d.coeff[0], len);
211 ZZ inv_d = rc->denom / d.coeff[0];
212 ZZ coeff;
214 for (int i = 0; i < len; ++i) {
215 for (dpoly_r_term_list::iterator k = c[i].begin(); k != c[i].end(); ++k) {
216 coeff = (*k)->coeff * inv_d;
217 rc->add_term(i, (*k)->powers, coeff);
220 for (int j = 1; j <= i; ++j) {
221 dpoly_r_term_list::iterator k;
222 for (k = rc->c[i-j].begin(); k != rc->c[i-j].end(); ++k) {
223 coeff = - d.coeff[j] * (*k)->coeff / d.coeff[0];
224 rc->add_term(i, (*k)->powers, coeff);
228 return rc;
231 void dpoly_r::dump(void)
233 for (int i = 0; i < len; ++i) {
234 cerr << endl;
235 cerr << i << endl;
236 cerr << c[i].size() << endl;
237 for (dpoly_r_term_list::iterator j = c[i].begin(); j != c[i].end(); ++j) {
238 for (int k = 0; k < dim; ++k) {
239 cerr << (*j)->powers[k] << " ";
241 cerr << ": " << (*j)->coeff << "/" << denom << endl;
243 cerr << endl;