Macaulay2 Engine
Loading...
Searching...
No Matches
res-a0-poly.cpp
Go to the documentation of this file.
1// Copyright 1996 Michael E. Stillman
2
3#include "res-a0-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 respoly_size = sizeof(res2term *) + sizeof(res2_pair *) + sizeof(ring_elem) +
13 sizeof(int) * M->monomial_size();
14 resterm_stash = new stash("resterm2", respoly_size);
15}
16
18int res2_poly::compare(const res2term *a, const res2term *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 res2term *result = reinterpret_cast<res2term *>(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
44res2term *res2_poly::mult_by_monomial(const res2term *f, const int *m) const
45{
46 res2term head;
47 res2term *result = &head;
48 for (const res2term *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 const ring_elem c) const
62{
63 res2term head;
64 res2term *result = &head;
65 for (const res2term *tm = f; tm != nullptr; tm = tm->next)
66 {
67 result->next = new_term();
68 result = result->next;
69 result->comp = tm->comp;
70 result->coeff = K->mult(c, tm->coeff);
71 M->copy(tm->monom, result->monom);
72 }
73 result->next = nullptr;
74 return head.next;
75}
76
78{
79 res2term head;
80 res2term *result = &head;
81 for (const res2term *tm = f; tm != nullptr; tm = tm->next)
82 {
83 result->next = new_term();
84 result = result->next;
85 result->comp = tm->comp;
86 result->coeff = K->copy(tm->coeff);
87 M->copy(tm->monom, result->monom);
88 }
89 result->next = nullptr;
90 return head.next;
91}
93{
94 while (f != nullptr)
95 {
96 res2term *tmp = f;
97 f = f->next;
98 K->remove(tmp->coeff);
99 resterm_stash->delete_elem(tmp);
100 }
101}
102
104 ring_elem c,
105 const int *m) const
106{
107 res2term head;
108 res2term *result = &head;
109 for (const res2term *tm = f; tm != nullptr; tm = tm->next)
110 {
111 result->next = new_term();
112 result = result->next;
113 result->comp = tm->comp;
114 result->coeff = K->mult(c, tm->coeff);
115 M->mult(tm->monom, m, result->monom);
116 }
117 result->next = nullptr;
118 return head.next;
119}
121 ring_elem c,
122 const int *m,
123 res2_pair *x) const
124{
125 res2term head;
126 res2term *result = &head;
127 for (Nterm& tm : f)
128 {
129 result->next = new_term();
130 result = result->next;
131 result->comp = x;
132 result->coeff = K->mult(c, tm.coeff);
133 M->mult(tm.monom, m, result->monom);
134 }
135 result->next = nullptr;
136 return head.next;
137}
138
140{
141 if (f == nullptr) return;
142 ring_elem c_inv = K->invert(f->coeff);
143
144 for (res2term *tm = f; tm != nullptr; tm = tm->next)
145 K->mult_to(tm->coeff, c_inv);
146
147 K->remove(c_inv);
148}
149
151{
152 if (g == nullptr) return;
153 if (f == nullptr)
154 {
155 f = g;
156 g = nullptr;
157 return;
158 }
159 res2term head;
160 res2term *result = &head;
161 while (1) switch (compare(f, g))
162 {
163 case -1:
164 result->next = g;
165 result = result->next;
166 g = g->next;
167 if (g == nullptr)
168 {
169 result->next = f;
170 f = head.next;
171 return;
172 }
173 break;
174 case 1:
175 result->next = f;
176 result = result->next;
177 f = f->next;
178 if (f == nullptr)
179 {
180 result->next = g;
181 f = head.next;
182 g = nullptr;
183 return;
184 }
185 break;
186 case 0:
187 res2term *tmf = f;
188 res2term *tmg = g;
189 f = f->next;
190 g = g->next;
191 K->add_to(tmf->coeff, tmg->coeff);
192 if (K->is_zero(tmf->coeff))
193 resterm_stash->delete_elem(tmf);
194 else
195 {
196 result->next = tmf;
197 result = result->next;
198 }
199 resterm_stash->delete_elem(tmg);
200 if (g == nullptr)
201 {
202 result->next = f;
203 f = head.next;
204 return;
205 }
206 if (f == nullptr)
207 {
208 result->next = g;
209 f = head.next;
210 g = nullptr;
211 return;
212 }
213 break;
214 }
215}
216
218 ring_elem c,
219 const int *m,
220 const res2term *g) const
221// f := f - c * m * g
222{
223 ring_elem minus_c = K->negate(c);
224 res2term *h = mult_by_term(g, minus_c, m);
225 add_to(f, h);
226 K->remove(minus_c);
227}
229 ring_elem c,
230 const int *m,
231 res2_pair *x,
232 const ring_elem g) const
233// f := f - c * m * g * x, where g is a ring element
234{
235 ring_elem minus_c = K->negate(c);
236 res2term *h = ring_mult_by_term(g, minus_c, m, x);
237 add_to(f, h);
238 K->remove(minus_c);
239}
240
241int res2_poly::n_terms(const res2term *f) const
242{
243 int result = 0;
244 for (; f != nullptr; f = f->next) result++;
245 return result;
246}
247
249{
250 buffer o;
251 elem_text_out(o, f);
252 emit(o.str());
253}
255{
256 if (f == nullptr)
257 {
258 o << "0";
259 return;
260 }
261
262 bool p_one = false;
263 bool p_parens = true;
264 bool p_plus = false;
265 for (const res2term *t = f; t != nullptr; t = t->next)
266 {
267 int isone = M->is_one(t->monom);
268 K->elem_text_out(o, t->coeff, p_one, p_plus, p_parens);
269 if (!isone) M->elem_text_out(o, t->monom, p_one);
270 o << "<" << t->comp->me << ">";
271 p_plus = true;
272 }
273}
274
276 const FreeModule *F,
277 int /*to_minimal*/) const
278{
279 vecHeap H(F);
280 monomial mon = M->make_one();
281 for (const res2term *tm = f; tm != nullptr; tm = tm->next)
282 {
283 // int x = (to_minimal ? tm->comp->minimal_me : tm->comp->me);
284 int x = tm->comp->me; // MES: Currently used for non-minimal as well...
285 M->divide(tm->monom, tm->comp->syz->monom, mon);
286
287 ring_elem a = R->make_flat_term(tm->coeff, mon);
288 vec tmp = R->make_vec(x, a);
289 H.add(tmp);
290 }
291 M->remove(mon);
292 return H.value();
293}
294
296 const vec v) const
297{
298 res2term head;
299 res2term *result = &head;
300
301 for (vecterm *w = v; w != nullptr; w = w->next)
302 for (Nterm& t : w->coeff)
303 {
304 result->next = new_term();
305 result = result->next;
306 result->comp = base[w->comp];
307 result->coeff = t.coeff;
308 M->copy(t.monom, result->monom);
309 M->mult(result->monom, result->comp->syz->monom, result->monom);
310 }
311 result->next = nullptr;
312 // Now we must sort these
313 sort(head.next);
314 return head.next;
315}
316
318{
319 res2term head;
320 res2term *result = &head;
321 for (const res2term *tm = f; tm != nullptr; tm = tm->next)
322 if (tm->comp->syz_type != SYZ2_NOT_MINIMAL)
323 {
324 result->next = new_term();
325 result = result->next;
326 result->comp = tm->comp;
327 result->coeff = K->copy(tm->coeff);
328 M->copy(tm->monom, result->monom);
329 }
330 result->next = nullptr;
331 return head.next;
332}
333
335 const res2term *f) const
336{
337 for (const res2term *tm = f; tm != nullptr; tm = tm->next)
338 if (tm->comp == x) return tm;
339 return nullptr;
340}
341
343{
344 // Divide f into two lists of equal length, sort each,
345 // then add them together. This allows the same monomial
346 // to appear more than once in 'f'.
347
348 if (f == nullptr || f->next == nullptr) return;
349 res2term *f1 = nullptr;
350 res2term *f2 = nullptr;
351 while (f != nullptr)
352 {
353 res2term *t = f;
354 f = f->next;
355 t->next = f1;
356 f1 = t;
357
358 if (f == nullptr) break;
359 t = f;
360 f = f->next;
361 t->next = f2;
362 f2 = t;
363 }
364
365 sort(f1);
366 sort(f2);
367 add_to(f1, f2);
368 f = f1;
369}
370
371// Local Variables:
372// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
373// indent-tabs-mode: nil
374// 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
res2_poly(PolynomialRing *R)
size_t respoly_size
res2term * copy(const res2term *f) const
const Monoid * M
res2term * from_vector(const VECTOR(res2_pair *)&base, const vec v) const
const res2term * component_occurs_in(const res2_pair *x, const res2term *f) const
res2term * mult_by_monomial(const res2term *f, const int *m) const
void sort(res2term *&f) const
stash * resterm_stash
res2term * strip(const res2term *f) const
void add_to(res2term *&f, res2term *&g) const
const Ring * K
int n_terms(const res2term *f) const
res2term * ring_mult_by_term(const ring_elem f, ring_elem c, const int *m, res2_pair *x) const
void make_monic(res2term *&f) const
void ring_subtract_multiple_to(res2term *&f, ring_elem c, const int *m, res2_pair *x, const ring_elem g) const
void subtract_multiple_to(res2term *&f, ring_elem c, const int *m, const res2term *g) const
int compare(const res2term *a, const res2term *b) const
res2term * mult_by_coefficient(const res2term *f, const ring_elem c) const
void elem_text_out(buffer &o, const res2term *f) const
res2term * mult_by_term(const res2term *f, ring_elem c, const int *m) const
const PolynomialRing * R
vec to_vector(const res2term *f, const FreeModule *F, int to_minimal=0) const
res2term * new_term() const
void remove(res2term *&f) const
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.
@ SYZ2_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
unsigned int compare_num
res2term * next
res2_pair * comp
ring_elem coeff
int monom[1]
void emit(const char *s)
Definition text-io.cpp:41
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.