32 static gmm::dense_matrix<size_type> alpha_M_(STORED, STORED);
33 static void alpha_init_() {
34 static bool init =
false;
37 alpha_M_(i, 0) = alpha_M_(0, i) = 1;
39 alpha_M_(i,j) = alpha_M_(j,i) = (alpha_M_(i, j-1) * (i+j)) / j;
45 {
return alpha_M_(d,n); }
49 GMM_ASSERT1(n < STORED && d < STORED,
50 "alpha called with n = " << n <<
" and d = " << d);
58 reverse_iterator it = rbegin() + 1;
65 if (g_idx+1) global_index_ = g_idx+1;
75 reverse_iterator it = rbegin();
81 (*this)[l] = 0; (*this)[n-1] =
short_type(a - 1);
82 if (l > 0) ((*this)[l-1])++;
85 if (g_idx+1) global_index_ = g_idx-1;
92 degree_ =
short_type(std::accumulate(begin(), end(), 0));
97 if (global_index_ !=
size_type(-1))
return global_index_;
100 const_iterator it = begin(), ite = end();
101 for ( ; it != ite && d > 0; ++it)
103 return global_index_;
107 { std::fill(begin(), end(),
short_type(0)); alpha_init_(); }
112 static void parse_error(
int i)
113 { GMM_ASSERT1(
false,
"Syntax error reading a polynomial " << i); }
115 static std::string stored_s;
118 static void unget_token(
int i, std::string s)
119 { std::swap(s, stored_s); stored_tokent = i; }
121 static int get_next_token(std::string &s, std::istream &f) {
122 if (stored_s.size() == 0) {
123 int r =
get_token(f, s,
true,
false,
false);
126 else { s.clear(); std::swap(s, stored_s);
return stored_tokent; }
129 static base_poly read_expression(
short_type n, std::istream &f) {
130 gmm::stream_standard_locale sl(f);
132 base_poly result(n,0);
134 int i = get_next_token(s, f), j;
136 case 2 : result.one();
137 result *= opt_long_scalar_type(::strtod(s.c_str(), 0));
140 if (s ==
"x") result = base_poly(n, 1, 0);
141 else if (s ==
"y" && n > 1) result = base_poly(n, 1, 1);
142 else if (s ==
"z" && n > 2) result = base_poly(n, 1, 2);
143 else if (s ==
"w" && n > 3) result = base_poly(n, 1, 3);
144 else if (s ==
"v" && n > 4) result = base_poly(n, 1, 4);
145 else if (s ==
"u" && n > 5) result = base_poly(n, 1, 5);
146 else if (s ==
"t" && n > 6) result = base_poly(n, 1, 6);
147 else if (s ==
"sqrt") {
148 base_poly p = read_expression(n, f);
149 if (p.degree() > 0) parse_error(1);
150 result.one(); result *= sqrt(p[0]);
152 else { parse_error(2); }
158 j = get_next_token(s, f);
159 if (j != 5 || s[0] !=
')') parse_error(3);
161 default : parse_error(4);
164 default : parse_error(5);
169 static void operator_priority_(
int i,
char c,
int &prior,
int &op) {
172 case '*' : prior = 2; op = 1;
return;
173 case '/' : prior = 2; op = 2;
return;
174 case '+' : prior = 3; op = 3;
return;
175 case '-' : prior = 3; op = 4;
return;
176 case '^' : prior = 1; op = 5;
return;
181 void do_bin_op(std::vector<base_poly> &value_list,
182 std::vector<int> &op_list,
183 std::vector<int> &prior_list) {
184 base_poly &p2 = *(value_list.rbegin());
185 if (op_list.back() != 6) {
186 assert(value_list.size()>1);
187 base_poly &p1 = *(value_list.rbegin()+1);
188 switch (op_list.back()) {
189 case 1 : p1 *= p2;
break;
190 case 2 :
if (p2.degree() > 0) parse_error(6); p1 /= p2[0];
break;
191 case 3 : p1 += p2;
break;
192 case 4 : p1 -= p2;
break;
195 if (p2.degree() > 0) parse_error(7);
196 int pow = int(to_scalar(p2[0]));
197 if (p2[0] != opt_long_scalar_type(pow) || pow < 0) parse_error(8);
198 base_poly p = p1; p1.one();
199 for (
int i = 0; i < pow; ++i) p1 *= p;
204 value_list.pop_back();
206 p2 *= opt_long_scalar_type(-1);
208 op_list.pop_back(); prior_list.pop_back();
212 std::vector<base_poly> value_list;
214 std::vector<int> op_list, prior_list;
216 int i = get_next_token(s, f), prior, op;
217 if (i == 5 && s[0] ==
'-')
218 { op_list.push_back(6); prior_list.push_back(2); }
219 else if (i == 5 && s[0] ==
'+') ;
220 else unget_token(i, s);
222 value_list.push_back(read_expression(n, f));
223 i = get_next_token(s, f);
224 operator_priority_(i, i ? s[0] :
'0', prior, op);
226 while (!prior_list.empty() && prior_list.back() <= prior)
227 do_bin_op(value_list, op_list, prior_list);
229 value_list.push_back(read_expression(n, f));
230 op_list.push_back(op);
231 prior_list.push_back(prior);
233 i = get_next_token(s, f);
234 operator_priority_(i, i ? s[0] :
'0', prior, op);
237 if (i == 5 && s[0] ==
')') { f.putback(
')'); }
238 else if (i != 0 && (i != 5 || s[0] !=
';')) {
239 cout <<
"s = " << s << endl;
243 while (!prior_list.empty()) do_bin_op(value_list, op_list, prior_list);
245 return value_list[0];
249 std::stringstream f(s);