Macaulay2 Engine
Loading...
Searching...
No Matches
res-a1-poly.cpp
Go to the documentation of this file.
1// Copyright 1996 Michael E. Stillman
2
3#include "res-a1-poly.hpp"
4#include "text-io.hpp"
5#include "polyring.hpp"
6#include "freemod.hpp"
7#include "geovec.hpp"
8
10 : R(RR), M(R->getMonoid()), K(R->getCoefficientRing())
11{
12 element_size = sizeof(resterm *) + sizeof(res_pair *) + sizeof(ring_elem) +
13 sizeof(int) * M->monomial_size();
14 resterm_stash = new stash("resterm", element_size);
15}
16
18inline int res_poly::compare(const resterm *a, const resterm *b) const
19{
20 int cmp = M->compare(a->monom, b->monom);
21 if (cmp != 0) return cmp;
22 cmp = a->comp->compare_num - b->comp->compare_num;
23 if (cmp > 0) return 1;
24 if (cmp < 0) return -1;
25 return 0;
26}
27
29{
30 resterm *result = reinterpret_cast<resterm *>(resterm_stash->new_elem());
31 result->next = nullptr;
32 return result;
33}
35// Note: this does NOT copy 'c'
36{
38 result->coeff = c;
39 M->copy(m, result->monom);
40 result->comp = x;
41 return result;
42}
43
44resterm *res_poly::mult_by_monomial(const resterm *f, const int *m) const
45{
46 resterm head;
47 resterm *result = &head;
48 for (const resterm *tm = f; tm != nullptr; tm = tm->next)
49 {
50 result->next = new_term();
51 result = result->next;
52 result->comp = tm->comp;
53 result->coeff = K->copy(tm->coeff);
54 M->mult(tm->monom, m, result->monom);
55 }
56 result->next = nullptr;
57 return head.next;
58}
59
61{
62 resterm head;
63 resterm *result = &head;
64 for (const resterm *tm = f; tm != nullptr; tm = tm->next)
65 {
66 result->next = new_term();
67 result = result->next;
68 result->comp = tm->comp;
69 result->coeff = K->copy(tm->coeff);
70 M->copy(tm->monom, result->monom);
71 }
72 result->next = nullptr;
73 return head.next;
74}
76{
77 while (f != nullptr)
78 {
79 resterm *tmp = f;
80 f = f->next;
81 K->remove(tmp->coeff);
82 resterm_stash->delete_elem(tmp);
83 }
84}
85
87 ring_elem c,
88 const int *m) const
89{
90 resterm head;
91 resterm *result = &head;
92 for (const resterm *tm = f; tm != nullptr; tm = tm->next)
93 {
94 result->next = new_term();
95 result = result->next;
96 result->comp = tm->comp;
97 result->coeff = K->mult(c, tm->coeff);
98 M->mult(tm->monom, m, result->monom);
99 }
100 result->next = nullptr;
101 return head.next;
102}
104 ring_elem c,
105 const int *m,
106 res_pair *x) const
107{
108 resterm head;
109 resterm *result = &head;
110 for (Nterm& tm : f)
111 {
112 result->next = new_term();
113 result = result->next;
114 result->comp = x;
115 result->coeff = K->mult(c, tm.coeff);
116 M->mult(tm.monom, m, result->monom);
117 }
118 result->next = nullptr;
119 return head.next;
120}
121
123{
124 if (f == nullptr) return;
125 ring_elem c_inv = K->invert(f->coeff);
126
127 for (resterm *tm = f; tm != nullptr; tm = tm->next) K->mult_to(tm->coeff, c_inv);
128
129 K->remove(c_inv);
130}
131
132void res_poly::add_to(resterm *&f, resterm *&g) const
133{
134 if (g == nullptr) return;
135 if (f == nullptr)
136 {
137 f = g;
138 g = nullptr;
139 return;
140 }
141 resterm head;
142 resterm *result = &head;
143 while (1) switch (compare(f, g))
144 {
145 case -1:
146 result->next = g;
147 result = result->next;
148 g = g->next;
149 if (g == nullptr)
150 {
151 result->next = f;
152 f = head.next;
153 return;
154 }
155 break;
156 case 1:
157 result->next = f;
158 result = result->next;
159 f = f->next;
160 if (f == nullptr)
161 {
162 result->next = g;
163 f = head.next;
164 g = nullptr;
165 return;
166 }
167 break;
168 case 0:
169 resterm *tmf = f;
170 resterm *tmg = g;
171 f = f->next;
172 g = g->next;
173 K->add_to(tmf->coeff, tmg->coeff);
174 if (K->is_zero(tmf->coeff))
175 resterm_stash->delete_elem(tmf);
176 else
177 {
178 result->next = tmf;
179 result = result->next;
180 }
181 resterm_stash->delete_elem(tmg);
182 if (g == nullptr)
183 {
184 result->next = f;
185 f = head.next;
186 return;
187 }
188 if (f == nullptr)
189 {
190 result->next = g;
191 f = head.next;
192 g = nullptr;
193 return;
194 }
195 break;
196 }
197}
198
200 ring_elem c,
201 const int *m,
202 const resterm *g) const
203// f := f - c * m * g
204{
205 ring_elem minus_c = K->negate(c);
206 resterm *h = mult_by_term(g, minus_c, m);
207 add_to(f, h);
208 K->remove(minus_c);
209}
211 ring_elem c,
212 const int *m,
213 res_pair *x,
214 const ring_elem g) const
215// f := f - c * m * g * x, where g is a ring element
216{
217 ring_elem minus_c = K->negate(c);
218 resterm *h = ring_mult_by_term(g, minus_c, m, x);
219 add_to(f, h);
220 K->remove(minus_c);
221}
222
223int res_poly::n_terms(const resterm *f) const
224{
225 int result = 0;
226 for (; f != nullptr; f = f->next) result++;
227 return result;
228}
229
231{
232 buffer o;
233 elem_text_out(o, f);
234 emit(o.str());
235}
236void res_poly::elem_text_out(buffer &o, const resterm *f) const
237{
238 if (f == nullptr)
239 {
240 o << "0";
241 return;
242 }
243
244 bool p_one = false;
245 bool p_parens = true;
246 bool p_plus = false;
247 for (const resterm *t = f; t != nullptr; t = t->next)
248 {
249 int isone = M->is_one(t->monom);
250 K->elem_text_out(o, t->coeff, p_one, p_parens, p_plus);
251 if (!isone) M->elem_text_out(o, t->monom, p_one);
252 o << "<" << t->comp->me << ">";
253 p_plus = true;
254 }
255}
256
258 const FreeModule *F,
259 int /*to_minimal*/) const
260{
261 vecHeap H(F);
262 monomial mon = M->make_one();
263 for (const resterm *tm = f; tm != nullptr; tm = tm->next)
264 {
265 // int x = (to_minimal ? tm->comp->minimal_me : tm->comp->me);
266 int x =
267 tm->comp
268 ->minimal_me; // MES: Currently used for non-minimal as well...
269 M->divide(tm->monom, tm->comp->base_monom, mon);
270
271 ring_elem a = R->make_flat_term(tm->coeff, mon);
272 vec tmp = R->make_vec(x, a);
273 H.add(tmp);
274 }
275 M->remove(mon);
276 return H.value();
277}
278
279resterm *res_poly::from_vector(const VECTOR(res_pair *)& base, const vec v) const
280{
281 resterm head;
282 resterm *result = &head;
283 for (vecterm *w = v; w != nullptr; w = w->next)
284 for (Nterm& t : w->coeff)
285 {
286 result->next = new_term();
287 result = result->next;
288 result->comp = base[w->comp];
289 result->coeff = t.coeff;
290 M->copy(t.monom, result->monom);
291 M->mult(result->monom, result->comp->base_monom, result->monom);
292 }
293 result->next = nullptr;
294 // Now we must sort these
295 sort(head.next);
296 return head.next;
297}
298
300{
301 resterm head;
302 resterm *result = &head;
303 for (const resterm *tm = f; tm != nullptr; tm = tm->next)
304 if (tm->comp->syz_type != SYZ_NOT_MINIMAL)
305 {
306 result->next = new_term();
307 result = result->next;
308 result->comp = tm->comp;
309 result->coeff = K->copy(tm->coeff);
310 M->copy(tm->monom, result->monom);
311 }
312 result->next = nullptr;
313 return head.next;
314}
315
317 const resterm *f) const
318{
319 for (const resterm *tm = f; tm != nullptr; tm = tm->next)
320 if (tm->comp == x) return tm;
321 return nullptr;
322}
323
324void res_poly::sort(resterm *&f) const
325{
326 // Divide f into two lists of equal length, sort each,
327 // then add them together. This allows the same monomial
328 // to appear more than once in 'f'.
329
330 if (f == nullptr || f->next == nullptr) return;
331 resterm *f1 = nullptr;
332 resterm *f2 = nullptr;
333 while (f != nullptr)
334 {
335 resterm *t = f;
336 f = f->next;
337 t->next = f1;
338 f1 = t;
339
340 if (f == nullptr) break;
341 t = f;
342 f = f->next;
343 t->next = f2;
344 f2 = t;
345 }
346
347 sort(f1);
348 sort(f2);
349 add_to(f1, f2);
350 f = f1;
351}
352
353// Local Variables:
354// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
355// indent-tabs-mode: nil
356// End:
Engine-side free module R^n over a Ring.
Definition freemod.hpp:66
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
char * str()
Definition buffer.hpp:72
int compare_num
void elem_text_out(buffer &o, const resterm *f) const
const PolynomialRing * R
resterm * mult_by_term(const resterm *f, ring_elem c, const int *m) const
resterm * copy(const resterm *f) const
size_t element_size
resterm * mult_by_monomial(const resterm *f, const int *m) const
int n_terms(const resterm *f) const
int compare(const resterm *a, const resterm *b) const
stash * resterm_stash
resterm * from_vector(const VECTOR(res_pair *)&base, const vec v) const
void remove(resterm *&f) const
void sort(resterm *&f) const
res_poly(PolynomialRing *R)
void ring_subtract_multiple_to(resterm *&f, ring_elem c, const int *m, res_pair *x, const ring_elem g) const
vec to_vector(const resterm *f, const FreeModule *F, int to_minimal=0) const
resterm * strip(const resterm *f) const
resterm * ring_mult_by_term(const ring_elem f, ring_elem c, const int *m, res_pair *x) const
const resterm * component_occurs_in(const res_pair *x, const resterm *f) const
void make_monic(resterm *&f) const
const Ring * K
void add_to(resterm *&f, resterm *&g) const
void subtract_multiple_to(resterm *&f, ring_elem c, const int *m, const resterm *g) const
resterm * new_term() const
const Monoid * M
Definition mem.hpp:78
vecterm * value()
Definition geovec.hpp:172
void add(vecterm *p)
Definition geovec.hpp:93
static CanonicalForm base
Definition factory.cpp:289
FreeModule — finite-rank free module R^n, the type-level anchor for every Matrix.
#define monomial
Definition gb-toric.cpp:11
vecHeap — geometric heap specialised for accumulating vec values.
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define VECTOR(T)
Definition newdelete.hpp:78
volatile int x
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
@ SYZ_NOT_MINIMAL
ring_elem coeff
Definition ringelem.hpp:158
int monom[1]
Definition ringelem.hpp:160
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156
res_pair * comp
ring_elem coeff
int monom[1]
resterm * next
void emit(const char *s)
Definition text-io.cpp:41
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.