Macaulay2 Engine
Loading...
Searching...
No Matches
monideal-minprimes.cpp
Go to the documentation of this file.
1// (c) 1994-2005 Michael E. Stillman
2
4#include "text-io.hpp"
5
8 min_codim(I->get_ring()->n_vars() + 1),
9 nvars(I->get_ring()->n_vars()),
10 mi(I->radical())
11{
12 exps = newarray(int *, nvars + 2);
13 for (int i = 0; i <= nvars + 1; i++) exps[i] = nullptr;
14
15 primes = new MonomialIdeal(I->get_ring());
16 codim_limit = 0;
17}
18
20{
21 for (int i = 0; i <= nvars + 1; i++)
22 if (exps[i] != nullptr) freemem(exps[i]);
24 delete primes;
25 delete mi;
26}
27
29{
30 minprime_limit = -1;
31
34 ass_prime_generator(mi->first_node(), 0);
36 return codim_limit;
37}
38
39#if 0
40// MonomialIdeal * MinimalPrimes::min_primes(int codim_limit0, int minprime_limit0)
41// // Place the associated primes of minimal codimension
42// // into a monomial ideal where each monomial corresponds to the prime
43// // monomial ideal which is its support.
44// {
45// codim_limit = codim_limit0;
46// minprime_limit = minprime_limit0;
47// state = do_primes;
48// n_minprimes = 0;
49//
50// if (exps[0] == 0) exps[0] = newarray_atomic(int,nvars);
51// for (int i=0; i<nvars; i++) exps[0][i] = 0;
52// ass_prime_generator(mi->first_node(), 0);
53//
54// buffer o;
55// o << "number of tentative minprimes is " << Q.size();
56//
57// MonomialIdeal *result = new MonomialIdeal(mi->get_ring() , Q);
58//
59// o << " actual number is " << result->size() << newline;
60// emit(o.str());
61//
62// return result;
63// }
64#endif
65
66static void to_prime_ideal(int n, int *exp)
67{
68 for (int i = 0; i < n; i++)
69 if (exp[i] <= 0)
70 exp[i] = 0;
71 else
72 exp[i] = 1; // NOTE!! This is the OPPOSITE of the way it is
73 // done in assprimes!
74}
75
76static int alg1_reduce_exp(const int *m, const int *exp)
77// Determine whether the varpower monomial 'm'
78// can be in the monomial prime ideal 'exp'.
79// exp corresponds to the set:
80// exp[i]>0 means variable is in ideal
81// exp[i]<0 means variable is not in ideal
82// exp[i]=0 means variable may or may not be in the ideal.
83// Return: 0 if 'm' is in this ideal.
84// Return: 1 if 'm' could be in the ideal.
85// Return: -1 if 'm' cannot possibly be in this ideal.
86{
87 int is_one = 1;
88 while (*m != 0)
89 {
90 if (exp[*m] == 1) return 0;
91 if (exp[*m] == 0) is_one = 0;
92 m++;
93 }
94 if (is_one) return -1;
95 return 1;
96}
97
99{
100 Bag *b = new Bag(0);
101 (void) depth;
102 for (int i = 0; i < nvars; i++)
103 if (exp[i + 1] > 0)
104 exp2[i] = 1;
105 else
106 exp2[i] = 0;
108 Q.push_back(b);
109}
110
112// which: which monomial we are looking at right now
113// current depth: starts at -1, goes down from there
114// so the current codim is -depth-1
115// The following information is kept as well:
116// current_minprime: array 0..codim-1 of variables in the minprime
117// current_exp: array 0..nvars-1 of 0,1,-1's
118//
119//
120{
121 for (;;)
122 {
123 if (*which == 0)
124 {
125 alg1_grab_prime(depth);
126 return;
127 }
128 switch (alg1_reduce_exp(which + 1, exp))
129 {
130 case 0:
131 which = which + *which;
132 break;
133 case -1:
134 return;
135 case 1:
136 if (depth > depth_limit)
137 {
138 int *m = which + 1;
139 while (*m != 0)
140 {
141 int v = *m;
142 if (exp[v] == 0)
143 {
144 exp[v] = 1;
145 alg1_min_prime_generator(which + *which, depth - 1);
146 exp[v] = depth;
147 }
148 m++;
149 }
150 // This code sets the 'exp' array back to the way it was
151 m = which + 1;
152 while (*m != 0)
153 {
154 int v = *m;
155 if (exp[v] == depth) exp[v] = 0;
156 m++;
157 }
158 }
159 return;
160 }
161 }
162}
163
165{
166 // First, let's write out the (radical) monomial ideal in an array.
167 // We need to know how large to make it. So, we first add up all of the
168 // degrees of the gens
169
170 (void) count;
171 depth_limit = -maxcodim - 1;
172
173 long len = 1;
174 for (Bag& a : *mi)
175 {
176 long d = varpower::simple_degree(a.monom().data());
177 len += d;
178 }
179
180 len += mi->size();
181 len += mi->size();
182 monoms = newarray_atomic(int, len);
183
184 int next_monom = 0;
185
186 for (Bag& a : *mi)
187 {
188 int *m = a.monom().data();
189 int d = varpower::simple_degree(m);
190
191 monoms[next_monom++] = d + 2;
192
193 for (index_varpower j = m; j.valid(); ++j)
194 monoms[next_monom++] = j.var() + 1;
195 monoms[next_monom++] = 0;
196 }
197 monoms[next_monom] = 0;
198
199 exp = newarray_atomic_clear(int, nvars + 1);
201
203
205 freemem(exp);
206
207 buffer o;
208 o << "number of tentative minprimes is " << Q.size();
209
210 MonomialIdeal *result = new MonomialIdeal(mi->get_ring(), Q);
211
212 o << " actual number is " << result->size() << newline;
213 emit(o.str());
214
215 return result;
216}
217
218MonomialIdeal *MinimalPrimes::min_primes(int codim_limit0, int minprime_limit0)
219// Place the associated primes of minimal codimension
220// into a monomial ideal where each monomial corresponds to the prime
221// monomial ideal which is its support.
222
223// For this version: codim_limit0 says: all irred primes of codim smaller than
224// this
225// have been placed into 'primes'.
226{
227 minprime_limit = minprime_limit0;
229 n_minprimes = 0;
230
231 if (exps[0] == nullptr) exps[0] = newarray_atomic_clear(int, nvars);
232
233 while (codim_limit < codim_limit0)
234 {
235 codim_limit++;
236 ass_prime_generator(mi->first_node(), 0);
237 }
238
240 primes = nullptr;
241 return result;
242}
243
244static int reduce_exp(const int *m, const int *exp)
245// Determine whether the varpower monomial 'm'
246// can be in the monomial prime ideal 'exp'.
247// exp corresponds to the set:
248// exp[i]>0 means variable is in ideal
249// exp[i]<0 means variable is not in ideal
250// exp[i]=0 means variable may or may not be in the ideal.
251// Return: 0 if 'm' is in this ideal.
252// Return: 1 if 'm' could be in the ideal.
253// Return: -1 if 'm' cannot possibly be in this ideal.
254{
255 int is_one = 1;
256 for (index_varpower i = m; i.valid(); ++i)
257 {
258 if (exp[i.var()] == 1) return 0;
259 if (exp[i.var()] == 0) is_one = 0;
260 }
261 if (is_one) return -1;
262 return 1;
263}
264
266{
267 int i = codim + 1;
268 if (exps[i] == nullptr) exps[i] = newarray_atomic(int, nvars);
269 exponents_t exp0 = exps[i];
270 for (int j = 0; j < nvars; j++) exp0[j] = exps[codim][j];
271 for (;;)
272 {
273 if (p == nullptr)
274 {
275 if (state == do_codim)
276 {
277 if (codim < codim_limit) codim_limit = codim;
278 }
279 else
280 {
281 to_prime_ideal(nvars, exp0);
282 Bag *b = new Bag(0);
284 primes->insert(b);
285 n_minprimes++;
286 }
287 return;
288 }
289 const int *m = p->monom().data();
290 switch (reduce_exp(m, exp0))
291 {
292 case 0:
293 p = mi->next(p);
294 break;
295 case -1:
296 return;
297 case 1:
298 if (codim < codim_limit)
299 for (index_varpower i2 = m; i2.valid(); ++i2)
300 if (exp0[i2.var()] == 0)
301 {
302 exp0[i2.var()] = 1;
303 ass_prime_generator(mi->next(p), codim + 1);
304 exp0[i2.var()] = -1;
306 return;
307 }
308 return;
309 }
310 }
311}
312
313// Local Variables:
314// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
315// indent-tabs-mode: nil
316// End:
ExponentListIterator< int, true > index_varpower
exponents::Exponents exponents_t
static int reduce_exp(const int *m, const int *exp)
Definition assprime.cpp:59
static void to_prime_ideal(int n, int *exp)
Definition assprime.cpp:80
static void from_expvector(int n, exponents::ConstExponents a, Vector &result)
static Exponent simple_degree(ConstExponents m)
enum MinimalPrimes::@077213145220241077135133272357312173137144302304 state
void ass_prime_generator(Nmi_node *p, int codim)
MonomialIdeal * primes
MinimalPrimes(const MonomialIdeal *const &mi)
MonomialIdeal * mi
void alg1_grab_prime(int depth)
MonomialIdeal * alg1_min_primes(int maxcodim, int count)
void alg1_min_prime_generator(int *which, int depth)
MonomialIdeal * min_primes(int maxcodim, int count)
const PolynomialRing * get_ring() const
Definition monideal.hpp:190
Engine-side monomial ideal: a decision tree of Nmi_nodes storing the (typically minimal) generators b...
Definition monideal.hpp:136
Internal tree node of the MonomialIdeal decision tree.
Definition monideal.hpp:74
int size()
Definition buffer.hpp:70
char * str()
Definition buffer.hpp:72
gc_vector< int > & monom()
Definition int-bag.hpp:60
int p
int_bag Bag
Definition int-bag.hpp:70
void freemem(void *s)
Definition m2-mem.cpp:103
VALGRIND_MAKE_MEM_DEFINED & result(result)
char newline[]
Definition m2-types.cpp:49
static int reduce_exp(const int *m, const int *exp)
static void to_prime_ideal(int n, int *exp)
static int alg1_reduce_exp(const int *m, const int *exp)
MinimalPrimes — minimal primes of a MonomialIdeal via a two-phase state machine.
#define newarray_atomic_clear(T, len)
Definition newdelete.hpp:93
#define newarray(T, len)
Definition newdelete.hpp:82
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
void emit(const char *s)
Definition text-io.cpp:41
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.