Macaulay2 Engine
Loading...
Searching...
No Matches
monomial-ideal.cpp
Go to the documentation of this file.
1// Copyright 2002 Michael E. Stillman
2
4
5#include <frobby.h> // TODO: move Frobby routines elsewhere?
6
7#include "ExponentList.hpp"
8#include "assprime.hpp"
9#include "buffer.hpp"
10#include "error.h"
11#include "exceptions.hpp"
12#include "finalize.hpp"
13#include "hilb.hpp"
14#include "int-bag.hpp"
15#include "matrix.hpp"
17#include "monideal.hpp"
18#include "monomial.hpp"
19#include "newdelete.hpp"
20#include "text-io.hpp"
21
22class PolynomialRing;
23class RingElement;
24
25const MonomialIdeal* /* or null */ IM2_MonomialIdeal_make(const Matrix *m, int n)
26{
27 try
28 {
31 return result;
32 } catch (const exc::engine_error& e)
33 {
34 ERROR(e.what());
35 return nullptr;
36 }
37}
38
39unsigned int rawMonomialIdealHash(const MonomialIdeal *F) { return F->hash(); }
40const Matrix /* or null */ *IM2_MonomialIdeal_to_matrix(const MonomialIdeal *I)
41{
42 try
43 {
44 return Matrix::make(I);
45 } catch (const exc::engine_error& e)
46 {
47 ERROR(e.what());
48 return nullptr;
49 }
50}
51
53{
54 buffer o;
55 try
56 {
57 I->text_out(o);
58 return o.to_string();
59 } catch (const exc::engine_error& e)
60 {
61 o << "[unprintable monomial ideal]";
62 return o.to_string();
63 }
64}
65
66int IM2_MonomialIdeal_n_gens(const MonomialIdeal *I) { return I->size(); }
68// 1 = true, 0 = false, -1 = error
69{
70 try
71 {
72 if (I->get_ring() != J->get_ring()) return false;
73 return I->is_equal(*J);
74 } catch (const exc::engine_error& e)
75 {
76 ERROR(e.what());
77 return -1;
78 }
79}
80
82 const MonomialIdeal *I)
83{
84 try
85 {
88 return result;
89
90 } catch (const exc::engine_error& e)
91 {
92 ERROR(e.what());
93 return nullptr;
94 }
95}
96
98 const MonomialIdeal *I,
99 const MonomialIdeal *J)
100{
101 try
102 {
103 if (I->get_ring() != J->get_ring())
104 {
105 ERROR("expected ideals in the same ring");
106 return nullptr;
107 }
110 return result;
111 } catch (const exc::engine_error& e)
112 {
113 ERROR(e.what());
114 return nullptr;
115 }
116}
117
118#include "debug.hpp"
119
121 const MonomialIdeal *I,
122 const EngineMonomial *a)
123{
124 try
125 {
126 MonomialIdeal *result = I->quotient(a->ints());
128 return result;
129 } catch (const exc::engine_error& e)
130 {
131 ERROR(e.what());
132 return nullptr;
133 }
134}
135
137 const MonomialIdeal *I,
138 const MonomialIdeal *J)
139{
140 try
141 {
142 if (I->get_ring() != J->get_ring())
143 {
144 ERROR("expected ideals in the same ring");
145 return nullptr;
146 }
147 MonomialIdeal *result = I->quotient(*J);
149 if (M2_gbTrace >= 1) dstash();
150 return result;
151
152 } catch (const exc::engine_error& e)
153 {
154 ERROR(e.what());
155 return nullptr;
156 }
157}
158
160 const MonomialIdeal *I,
161 const EngineMonomial *a)
162{
163 try
164 {
165 MonomialIdeal *result = I->erase(a->ints());
167 return result;
168 } catch (const exc::engine_error& e)
169 {
170 ERROR(e.what());
171 return nullptr;
172 }
173}
174
176 const MonomialIdeal *I,
177 const MonomialIdeal *J)
178{
179 try
180 {
181 if (I->get_ring() != J->get_ring())
182 {
183 ERROR("expected ideals in the same ring");
184 return nullptr;
185 }
186 MonomialIdeal *result = I->sat(*J);
188 return result;
189 } catch (const exc::engine_error& e)
190 {
191 ERROR(e.what());
192 return nullptr;
193 }
194}
195
197 const MonomialIdeal *I)
198{
199 try
200 {
201 MonomialIdeal *result = I->borel();
203 return result;
204 } catch (const exc::engine_error& e)
205 {
206 ERROR(e.what());
207 return nullptr;
208 }
209}
210
212{
213 return I->is_borel();
214}
215
217{
218 try
219 {
220 MinimalPrimes ap(I);
221 return ap.codimension();
222 } catch (const exc::engine_error& e)
223 {
224 ERROR(e.what());
225 return -1; // -1 is not a valid codimension, and interface.d knows it
226 }
227}
228
229const MonomialIdeal /* or null */ *
230rawMonomialMinimalPrimes(const MonomialIdeal *I, int codim_limit, int count)
231{
232 try
233 {
234 MinimalPrimes ap(I);
235 MonomialIdeal *result = ap.alg1_min_primes(codim_limit, count);
237 return result;
238 } catch (const exc::engine_error& e)
239 {
240 ERROR(e.what());
241 return nullptr;
242 }
243}
244
246 const MonomialIdeal *I,
247 int count)
248{
249 try
250 {
251 AssociatedPrimes ap(I);
254 return result;
255 } catch (const exc::engine_error& e)
256 {
257 ERROR(e.what());
258 return nullptr;
259 }
260}
261
263 const MonomialIdeal *I)
264/* This routine computes the numerator of the Hilbert series
265 for coker I. NULL is returned if the ring is not appropriate for
266 computing Hilbert series, or the computation was interrupted. */
267{
268 try
269 {
271 } catch (const exc::engine_error& e)
272 {
273 ERROR(e.what());
274 return nullptr;
275 }
276}
277
279
280/***********************/
281/*** Frobby routines ***/
282/***********************/
283
297class MyIdealConsumer : public Frobby::IdealConsumer, our_new_delete
298{
299 int nv; // The size of exponentVector coming from frobby
302
303 public:
304 MyIdealConsumer(const PolynomialRing *R, int nv0) : nv(nv0)
305 {
306 J = new MonomialIdeal(R);
307 exp = newarray_atomic(int, nv);
308 }
310 {
311 freemem(exp);
312 J = nullptr;
313 }
314 virtual void consume(mpz_ptr *exponentVector)
315 {
316 // insert into J. This is a minimal generator of J
317 for (int i = 0; i < nv; i++)
318 exp[i] = static_cast<int>(mpz_get_si(
319 exponentVector[i])); // overflow should not occur, as input fit
320
321 if (M2_gbTrace >= 5)
322 {
323 fprintf(stderr, "got ");
324 for (int j = 0; j < nv; j++) fprintf(stderr, "%d ", exp[j]);
325 fprintf(stderr, "\n");
326 }
327
328 Bag *b = new Bag();
330 J->insert_minimal(b);
331 }
332 MonomialIdeal *result() { return J; }
333};
334
336 const mpz_t *topvec)
337{
338 int nv = I->topvar() + 1;
339 exponents_t exp = newarray_atomic(int, nv);
340 Frobby::Ideal F(nv);
341 for (Bag& b : *I)
342 {
343 varpower::to_expvector(nv, b.monom().data(), exp);
344
345 if (M2_gbTrace >= 4) fprintf(stderr, "adding ");
346 for (int j = 0; j < nv; j++)
347 {
348 if (M2_gbTrace >= 4) fprintf(stderr, "%d ", exp[j]);
349 F.addExponent(exp[j]);
350 }
351 if (M2_gbTrace >= 4) fprintf(stderr, "\n");
352 }
353
354 // Now create the consumer object, and call Frobby
355 MyIdealConsumer M(I->get_ring(), nv);
356 Frobby::alexanderDual(F, topvec, M);
357 freemem(exp);
358 // Extract the answer as a MonomialIdeal
359 return M.result();
360}
361
363 const M2_arrayint top)
364// Assumption: top is an array of at least the number of variables of I
365// whose v-th entry is at least as large as the v-th exp of any mingen of I
366{
367 // Create a Frobby Ideal containing I.
368 int nv = I->topvar() + 1;
369 if (nv == 0)
370 {
371 INTERNAL_ERROR("attempting to use frobby with zero variables");
372 return nullptr;
373 }
374
375 mpz_t *topvec = nullptr;
376 if (top->len > 0)
377 {
378 topvec = newarray(mpz_t, top->len);
379 for (int i = 0; i < top->len; i++)
380 mpz_init_set_si(topvec[i], top->array[i]);
381 }
382
384
385 // Clean up
386 if (topvec != nullptr)
387 {
388 for (int i = 0; i < top->len; i++) mpz_clear(topvec[i]);
389 freemem(topvec);
390 }
391
392 return result;
393}
394
395static MonomialIdeal /* or null */ *alexDual(const MonomialIdeal *I,
396 const M2_arrayint top,
397 int strategy)
398{
399 if (I->topvar() < 0)
400 strategy =
401 1; // i.e. don't use frobby if there are no generators and/or variables
402 switch (strategy)
403 {
404 case 0:
405 if (M2_gbTrace >= 1) emit_line(" -- [Alexander dual: frobby]");
406 return wrapperFrobbyAlexanderDual(I, top);
407 default:
408 if (M2_gbTrace >= 1) emit_line(" -- [Alexander dual: M2 monideal]");
409 return I->alexander_dual(top);
410 }
411}
412
413const MonomialIdeal /* or null */ *rawAlexanderDual(const MonomialIdeal *I,
414 const M2_arrayint top,
415 int strategy)
416{
417 try
418 {
419 MonomialIdeal *result = alexDual(I, top, strategy);
421 return result;
422 } catch (const exc::engine_error& e)
423 {
424 ERROR(e.what());
425 return nullptr;
426 }
427}
428
429// Local Variables:
430// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
431// indent-tabs-mode: nil
432// End:
Variable-length sparse (variable, exponent) encoding of monomials.
exponents::Exponents exponents_t
AssociatedPrimes — codimension and minimal-codimension associated primes of a monomial ideal.
Append-only GC-backed byte buffer used throughout the engine for text output.
MonomialIdeal * associated_primes(int count)
Definition assprime.cpp:42
Engine-side immutable monomial value type wrapping a varpower- encoded exponent vector.
Definition monomial.hpp:61
unsigned int hash() const
Definition hash.hpp:70
static void from_expvector(int n, exponents::ConstExponents a, Vector &result)
static void to_expvector(int n, ConstExponents a, exponents::Exponents result)
MonomialIdeal * make_monideal(int n, bool use_only_monomials_with_unit_coeffs=false) const
Definition matrix.cpp:1925
MonomialIdeal * alg1_min_primes(int maxcodim, int count)
MonomialIdeal * erase(const_varpower m) const
Definition monideal.cpp:853
M2_arrayint lcm() const
Definition monideal.cpp:819
bool is_equal(const MonomialIdeal &mi) const
Definition monideal.cpp:195
MonomialIdeal * quotient(const_varpower m) const
Definition monideal.cpp:759
bool is_borel() const
Definition monideal.cpp:955
MonomialIdeal * sat(const MonomialIdeal &J) const
Definition monideal.cpp:869
void text_out(buffer &o) const
Definition monideal.cpp:639
int size() const
Definition monideal.hpp:186
MonomialIdeal * intersect(const_varpower m) const
Definition monideal.cpp:696
int topvar() const
Definition monideal.hpp:187
MonomialIdeal * borel() const
Definition monideal.cpp:940
MonomialIdeal * alexander_dual(const M2_arrayint a) const
Definition monideal.cpp:834
const PolynomialRing * get_ring() const
Definition monideal.hpp:190
MonomialIdeal * radical() const
Definition monideal.cpp:899
Engine-side monomial ideal: a decision tree of Nmi_nodes storing the (typically minimal) generators b...
Definition monideal.hpp:136
MyIdealConsumer(const PolynomialRing *R, int nv0)
virtual void consume(mpz_ptr *exponentVector)
MonomialIdeal * result()
MonomialIdeal * J
Frobby::IdealConsumer adapter that collects Frobby's output monomials into an engine MonomialIdeal.
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Definition relem.hpp:67
M2_string to_string()
Definition buffer.cpp:20
static RingElement * hilbertNumerator(const Matrix *M)
Definition hilb.cpp:665
gc_vector< int > & monom()
Definition int-bag.hpp:60
void dstash()
Definition debug.cpp:138
Debugger-callable d* helpers that pretty-print engine values to stderr.
void INTERNAL_ERROR(const char *s,...)
Definition error.c:36
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
#define Matrix
Definition factory.cpp:14
void intern_monideal(MonomialIdeal *G)
Definition finalize.cpp:55
intern_* helpers that register long-lived engine objects with bdwgc finalisers.
Hilbert-series numerator via the Bigatti-Caboara-Robbiano recursion.
int_bag Bag
Definition int-bag.hpp:70
int_bag / Bag — minimal (payload, varpower monomial) carrier shared by monomial-ideal code.
void freemem(void *s)
Definition m2-mem.cpp:103
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
int M2_gbTrace
Definition m2-types.cpp:52
char M2_bool
Definition m2-types.h:82
Matrix — the engine's immutable homomorphism F -> G between free modules.
MinimalPrimes — minimal primes of a MonomialIdeal via a two-phase state machine.
MonomialIdeal — exponent-vector-only representation of an ideal generated by monomials.
M2_string IM2_MonomialIdeal_to_string(const MonomialIdeal *I)
static MonomialIdeal * wrapperFrobbyAlexanderDual(const MonomialIdeal *I, const M2_arrayint top)
const MonomialIdeal * rawSaturateMonomialIdeal2(const MonomialIdeal *I, const MonomialIdeal *J)
const MonomialIdeal * rawColonMonomialIdeal2(const MonomialIdeal *I, const MonomialIdeal *J)
int IM2_MonomialIdeal_codim(const MonomialIdeal *I)
M2_arrayint rawMonomialIdealLCM(const MonomialIdeal *I)
const MonomialIdeal * rawMonomialMinimalPrimes(const MonomialIdeal *I, int codim_limit, int count)
int IM2_MonomialIdeal_n_gens(const MonomialIdeal *I)
static MonomialIdeal * alexDual(const MonomialIdeal *I, const M2_arrayint top, int strategy)
M2_bool IM2_MonomialIdeal_is_borel(const MonomialIdeal *I)
static MonomialIdeal * FrobbyAlexanderDual(const MonomialIdeal *I, const mpz_t *topvec)
const MonomialIdeal * rawAlexanderDual(const MonomialIdeal *I, const M2_arrayint top, int strategy)
const MonomialIdeal * rawSaturateMonomialIdeal1(const MonomialIdeal *I, const EngineMonomial *a)
const MonomialIdeal * rawRadicalMonomialIdeal(const MonomialIdeal *I)
const MonomialIdeal * IM2_MonomialIdeal_borel(const MonomialIdeal *I)
const MonomialIdeal * IM2_MonomialIdeal_intersect(const MonomialIdeal *I, const MonomialIdeal *J)
const MonomialIdeal * rawMaximalIndependentSets(const MonomialIdeal *I, int count)
const MonomialIdeal * rawColonMonomialIdeal1(const MonomialIdeal *I, const EngineMonomial *a)
unsigned int rawMonomialIdealHash(const MonomialIdeal *F)
int IM2_MonomialIdeal_is_equal(const MonomialIdeal *I, const MonomialIdeal *J)
const MonomialIdeal * IM2_MonomialIdeal_make(const Matrix *m, int n)
const RingElement * IM2_MonomialIdeal_Hilbert(const MonomialIdeal *I)
const Matrix * IM2_MonomialIdeal_to_matrix(const MonomialIdeal *I)
Engine-boundary C API for constructing and operating on MonomialIdeals.
EngineMonomial — opaque single-monomial value type used at the engine boundary.
#define newarray(T, len)
Definition newdelete.hpp:82
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
our_new_delete — per-class opt-in routing of new / delete through bdwgc.
void emit_line(const char *s)
Definition text-io.cpp:47
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.