31 static gmm::dense_matrix<size_type> alpha_M_(STORED, STORED);
32 static void alpha_init_() {
33 static bool init =
false;
36 alpha_M_(i, 0) = alpha_M_(0, i) = 1;
38 alpha_M_(i,j) = alpha_M_(j,i) = (alpha_M_(i, j-1) * (i+j)) / j;
44 {
return alpha_M_(d,n); }
48 GMM_ASSERT1(n < STORED && d < STORED,
49 "alpha called with n = " << n <<
" and d = " << d);
57 reverse_iterator it = rbegin() + 1;
64 if (g_idx+1) global_index_ = g_idx+1;
74 reverse_iterator it = rbegin();
80 (*this)[l] = 0; (*this)[n-1] =
short_type(a - 1);
81 if (l > 0) ((*this)[l-1])++;
84 if (g_idx+1) global_index_ = g_idx-1;
91 degree_ =
short_type(std::accumulate(begin(), end(), 0));
96 if (global_index_ !=
size_type(-1))
return global_index_;
99 const_iterator it = begin(), ite = end();
100 for ( ; it != ite && d > 0; ++it)
102 return global_index_;
106 { std::fill(begin(), end(),
short_type(0)); alpha_init_(); }
111 static void parse_error(
int i)
112 { GMM_ASSERT1(
false,
"Syntax error reading a polynomial " << i); }
114 static std::string stored_s;
117 static void unget_token(
int i, std::string s)
118 { std::swap(s, stored_s); stored_tokent = i; }
120 static int get_next_token(std::string &s, std::istream &f) {
121 if (stored_s.size() == 0) {
122 int r =
get_token(f, s,
true,
false,
false);
125 else { s.clear(); std::swap(s, stored_s);
return stored_tokent; }
129 gmm::stream_standard_locale sl(f);
133 int i = get_next_token(s, f), j;
135 case 2 : result.
one();
136 result *= opt_long_scalar_type(::strtod(s.c_str(), 0));
139 if (s ==
"x") result =
base_poly(n, 1, 0);
140 else if (s ==
"y" && n > 1) result =
base_poly(n, 1, 1);
141 else if (s ==
"z" && n > 2) result =
base_poly(n, 1, 2);
142 else if (s ==
"w" && n > 3) result =
base_poly(n, 1, 3);
143 else if (s ==
"v" && n > 4) result =
base_poly(n, 1, 4);
144 else if (s ==
"u" && n > 5) result =
base_poly(n, 1, 5);
145 else if (s ==
"t" && n > 6) result =
base_poly(n, 1, 6);
146 else if (s ==
"sqrt") {
148 if (p.
degree() > 0) parse_error(1);
149 result.
one(); result *= sqrt(p[0]);
151 else { parse_error(2); }
157 j = get_next_token(s, f);
158 if (j != 5 || s[0] !=
')') parse_error(3);
160 default : parse_error(4);
163 default : parse_error(5);
168 static void operator_priority_(
int i,
char c,
int &prior,
int &op) {
171 case '*' : prior = 2; op = 1;
return;
172 case '/' : prior = 2; op = 2;
return;
173 case '+' : prior = 3; op = 3;
return;
174 case '-' : prior = 3; op = 4;
return;
175 case '^' : prior = 1; op = 5;
return;
180 void do_bin_op(std::vector<base_poly> &value_list,
181 std::vector<int> &op_list,
182 std::vector<int> &prior_list) {
184 if (op_list.back() != 6) {
185 assert(value_list.size()>1);
186 base_poly &p1 = *(value_list.rbegin()+1);
187 switch (op_list.back()) {
188 case 1 : p1 *= p2;
break;
189 case 2 :
if (p2.
degree() > 0) parse_error(6); p1 /= p2[0];
break;
190 case 3 : p1 += p2;
break;
191 case 4 : p1 -= p2;
break;
194 if (p2.
degree() > 0) parse_error(7);
195 int pow = int(to_scalar(p2[0]));
196 if (p2[0] != opt_long_scalar_type(pow) || pow < 0) parse_error(8);
198 for (
int i = 0; i < pow; ++i) p1 *= p;
203 value_list.pop_back();
205 p2 *= opt_long_scalar_type(-1);
207 op_list.pop_back(); prior_list.pop_back();
211 std::vector<base_poly> value_list;
213 std::vector<int> op_list, prior_list;
215 int i = get_next_token(s, f), prior, op;
216 if (i == 5 && s[0] ==
'-')
217 { op_list.push_back(6); prior_list.push_back(2); }
218 else if (i == 5 && s[0] ==
'+') ;
219 else unget_token(i, s);
221 value_list.push_back(read_expression(n, f));
222 i = get_next_token(s, f);
223 operator_priority_(i, i ? s[0] :
'0', prior, op);
225 while (!prior_list.empty() && prior_list.back() <= prior)
226 do_bin_op(value_list, op_list, prior_list);
228 value_list.push_back(read_expression(n, f));
229 op_list.push_back(op);
230 prior_list.push_back(prior);
232 i = get_next_token(s, f);
233 operator_priority_(i, i ? s[0] :
'0', prior, op);
236 if (i == 5 && s[0] ==
')') { f.putback(
')'); }
237 else if (i != 0 && (i != 5 || s[0] !=
';')) {
238 cout <<
"s = " << s << endl;
242 while (!prior_list.empty()) do_bin_op(value_list, op_list, prior_list);
244 return value_list[0];
248 std::stringstream f(s);
base_poly read_base_poly(short_type n, std::istream &f)
read a base_poly on the stream ist.
const power_index & operator--()
Gives the next previous index.
Multivariate polynomials.
int get_token(std::istream &ist, std::string &st, bool ignore_cr, bool to_up, bool read_un_pm, int *linenb)
Very simple lexical analysis of general interest for reading small langages with a "MATLAB like" synt...
size_t size_type
used as the common size type in the library
Vector of integer (16 bits type) which represent the powers of a monomial.
const power_index & operator++()
Gives the next power index.
this is the above solutions for linux, but it still needs to be tested.
power_index()
Constructor.
gmm::uint16_type short_type
used as the common short type integer in the library
short_type degree() const
Gives the degree of the polynomial.
size_type alpha(short_type n, short_type d)
Return the value of which is the number of monomials of a polynomial of variables and degree ...
size_type global_index() const
Gives the global number of the index (i.e.
short_type degree() const
Gives the degree.