genfun.cc: add gen_fun::summate method
[barvinok.git] / dpoly.cc
blob5f561fc618c612d9972ae9d7e89301d90668cdfb
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 void dpoly::div(dpoly& d, mpq_t count, ZZ& sign)
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 if (sign == -1)
62 mpq_sub(count, count, c[len-1]);
63 else
64 mpq_add(count, count, c[len-1]);
66 value_clear(tmp);
67 mpq_clear(qtmp);
68 for (int i = 0; i < len; ++i)
69 mpq_clear(c[i]);
70 delete [] c;
73 void dpoly_r::add_term(int i, int * powers, ZZ& coeff)
75 if (coeff == 0)
76 return;
77 for (int k = 0; k < c[i].size(); ++k) {
78 if (memcmp(c[i][k]->powers, powers, dim * sizeof(int)) == 0) {
79 c[i][k]->coeff += coeff;
80 return;
83 dpoly_r_term *t = new dpoly_r_term;
84 t->powers = new int[dim];
85 memcpy(t->powers, powers, dim * sizeof(int));
86 t->coeff = coeff;
87 c[i].push_back(t);
90 dpoly_r::dpoly_r(int len, int dim)
92 denom = 1;
93 this->len = len;
94 this->dim = dim;
95 c = new vector< dpoly_r_term * > [len];
98 dpoly_r::dpoly_r(dpoly& num, int dim)
100 denom = 1;
101 len = num.coeff.length();
102 c = new vector< dpoly_r_term * > [len];
103 this->dim = dim;
104 int powers[dim];
105 memset(powers, 0, dim * sizeof(int));
107 for (int i = 0; i < len; ++i) {
108 ZZ coeff = num.coeff[i];
109 add_term(i, powers, coeff);
113 dpoly_r::dpoly_r(dpoly& num, dpoly& den, int pos, int dim)
115 denom = 1;
116 len = num.coeff.length();
117 c = new vector< dpoly_r_term * > [len];
118 this->dim = dim;
119 int powers[dim];
121 for (int i = 0; i < len; ++i) {
122 ZZ coeff = num.coeff[i];
123 memset(powers, 0, dim * sizeof(int));
124 powers[pos] = 1;
126 add_term(i, powers, coeff);
128 for (int j = 1; j <= i; ++j) {
129 for (int k = 0; k < c[i-j].size(); ++k) {
130 memcpy(powers, c[i-j][k]->powers, dim*sizeof(int));
131 powers[pos]++;
132 coeff = -den.coeff[j-1] * c[i-j][k]->coeff;
133 add_term(i, powers, coeff);
137 //dump();
140 dpoly_r::dpoly_r(dpoly_r* num, dpoly& den, int pos, int dim)
142 denom = num->denom;
143 len = num->len;
144 c = new vector< dpoly_r_term * > [len];
145 this->dim = dim;
146 int powers[dim];
147 ZZ coeff;
149 for (int i = 0 ; i < len; ++i) {
150 for (int k = 0; k < num->c[i].size(); ++k) {
151 memcpy(powers, num->c[i][k]->powers, dim*sizeof(int));
152 powers[pos]++;
153 add_term(i, powers, num->c[i][k]->coeff);
156 for (int j = 1; j <= i; ++j) {
157 for (int k = 0; k < c[i-j].size(); ++k) {
158 memcpy(powers, c[i-j][k]->powers, dim*sizeof(int));
159 powers[pos]++;
160 coeff = -den.coeff[j-1] * c[i-j][k]->coeff;
161 add_term(i, powers, coeff);
167 dpoly_r::~dpoly_r()
169 for (int i = 0 ; i < len; ++i)
170 for (int k = 0; k < c[i].size(); ++k) {
171 delete [] c[i][k]->powers;
172 delete c[i][k];
174 delete [] c;
177 dpoly_r *dpoly_r::div(dpoly& d)
179 dpoly_r *rc = new dpoly_r(len, dim);
180 rc->denom = power(d.coeff[0], len);
181 ZZ inv_d = rc->denom / d.coeff[0];
182 ZZ coeff;
184 for (int i = 0; i < len; ++i) {
185 for (int k = 0; k < c[i].size(); ++k) {
186 coeff = c[i][k]->coeff * inv_d;
187 rc->add_term(i, c[i][k]->powers, coeff);
190 for (int j = 1; j <= i; ++j) {
191 for (int k = 0; k < rc->c[i-j].size(); ++k) {
192 coeff = - d.coeff[j] * rc->c[i-j][k]->coeff / d.coeff[0];
193 rc->add_term(i, rc->c[i-j][k]->powers, coeff);
197 return rc;
200 void dpoly_r::dump(void)
202 for (int i = 0; i < len; ++i) {
203 cerr << endl;
204 cerr << i << endl;
205 cerr << c[i].size() << endl;
206 for (int j = 0; j < c[i].size(); ++j) {
207 for (int k = 0; k < dim; ++k) {
208 cerr << c[i][j]->powers[k] << " ";
210 cerr << ": " << c[i][j]->coeff << "/" << denom << endl;
212 cerr << endl;