Frobby 0.9.6
frobby.cpp
Go to the documentation of this file.
1/* Frobby: Software for monomial ideal computations.
2 Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see http://www.gnu.org/licenses/.
16*/
17#include "stdinc.h"
18#include "frobby.h"
19
20#include "BigIdeal.h"
21#include "SliceFacade.h"
22#include "BigTermConsumer.h"
23#include "TermTranslator.h"
24#include "Term.h"
25#include "error.h"
26#include "CoefBigTermConsumer.h"
27#include "IdealFacade.h"
28#include "SliceParams.h"
29
30/* also increment the version number in:
31 - CMakeLists.txt
32 - doc/doxygen.conf
33 - doc/manual.tex
34 - test/messages/help-noparam.err
35 and update the library version as outlined in Makefile */
36const char* const frobby_version = "0.9.6";
37
39protected:
44
45 virtual ~ConsumerWrapper() {
46 delete[] _term;
47 }
48
49 void setTerm(const Term& term, const TermTranslator& translator) {
50 ASSERT(term.getVarCount() == _varCount);
51 ASSERT(translator.getVarCount() == _varCount);
52
53 for (size_t var = 0; var < _varCount; ++var)
54 _term[var] = const_cast<mpz_ptr>
55 (translator.getExponent(var, term).get_mpz_t());
56 }
57
58 void setTerm(const vector<mpz_class>& term) {
59 ASSERT(term.size() == _varCount);
60
61 for (size_t var = 0; var < _varCount; ++var)
62 _term[var] = const_cast<mpz_ptr>(term[var].get_mpz_t());
63 }
64
65 size_t _varCount;
67};
68
70 public ConsumerWrapper {
71public:
78
79 virtual void consumeRing(const VarNames& names) {
80 ASSERT(names.getVarCount() == _varCount);
81 }
82
83 virtual void beginConsuming() {
85 }
86
87 virtual void consume(const Term& term, const TermTranslator& translator) {
88 ASSERT(term.getVarCount() == _varCount);
89 ASSERT(translator.getVarCount() == _varCount);
90
91 setTerm(term, translator);
93 }
94
95 virtual void consume(const vector<mpz_class>& term) {
96 ASSERT(term.size() == _varCount);
97
98 setTerm(term);
100 }
101
102 virtual void doneConsuming() {
104 }
105
106private:
108};
109
111 public ConsumerWrapper {
112public:
120
121 virtual void consumeRing(const VarNames& names) {
122 ASSERT(names.getVarCount() == _varCount);
123 }
124
125 virtual void beginConsuming() {
127 }
128
129 virtual void consume(const mpz_class& coef,
130 const Term& term,
131 const TermTranslator& translator) {
132 ASSERT(term.getVarCount() == _varCount);
133 ASSERT(translator.getVarCount() == _varCount);
134
135 setTerm(term, translator);
136 _consumer->consume(coef.get_mpz_t(), _term);
137 }
138
139 virtual void consume(const mpz_class& coef,
140 const vector<mpz_class>& term) {
141 ASSERT(term.size() == _varCount);
142
143 for (size_t var = 0; var < _varCount; ++var)
144 _term[var] = const_cast<mpz_ptr>(term[var].get_mpz_t());
145 _consumer->consume(coef.get_mpz_t(), _term);
146 }
147
148 // TODO: make a note somewhere that in case of an exception,
149 // polynomialEnd might not get called, this being because it is too
150 // much of a burden to require it not to throw any
151 // exceptions. Hmm... maybe there is an alternative solution.
152 virtual void doneConsuming() {
154 }
155
156private:
158 size_t _varCount;
159};
160
163
166
169
172
175
178
179namespace FrobbyImpl {
180 using ::BigIdeal;
181
183 public:
185 _ideal(VarNames(variableCount)),
186 _atVariable(variableCount) {
187 }
188
189 static const BigIdeal& getIdeal(const Frobby::Ideal& ideal) {
190 return ideal._data->_ideal;
191 }
192
193 private:
194 friend class Frobby::Ideal;
195
198 };
199}
200
204
206 _data = new FrobbyImpl::FrobbyIdealHelper(*ideal._data);
207}
208
210 delete _data;
211}
212
214 // Allocate new object before deleting old object to leave *this
215 // in a valid state in case of new throwing an exception.
218
219 delete _data;
220 _data = newValue;
221
222 return *this;
223}
224
226 ASSERT(_data->_atVariable <= _data->_ideal.getVarCount());
227
228 if (_data->_atVariable == _data->_ideal.getVarCount()) {
229 _data->_ideal.newLastTerm();
230 _data->_atVariable = 0;
231 if (_data->_ideal.getVarCount() == 0)
232 return;
233 }
234
235 mpz_class& ref = _data->_ideal.getLastTermExponentRef(_data->_atVariable);
236 mpz_set(ref.get_mpz_t(), exponent);
237 ++_data->_atVariable;
238}
239
242 addExponent(tmp.get_mpz_t());
243}
244
247 addExponent(tmp.get_mpz_t());
248}
249
250bool Frobby::alexanderDual(const Ideal& ideal,
254
256 (&consumer, bigIdeal.getVarCount());
257
260
261 if (reflectionMonomial == 0)
262 facade.computeAlexanderDual();
263 else {
264 vector<mpz_class> point;
265 point.resize(bigIdeal.getVarCount());
266 for (size_t var = 0; var < bigIdeal.getVarCount(); ++var)
268
269 // We guarantee not to retain a reference to reflectionMonomial
270 // when providing terms to the consumer.
272
273 try {
274 facade.computeAlexanderDual(point);
275 } catch (const FrobbyException&) {
276 return false;
277 }
278 }
279
280 return true;
281}
282
283bool Frobby::alexanderDual(const Ideal& ideal,
289
290 if (reflectionIdeal.getGeneratorCount() != 1)
291 return false;
292 if (reflectionIdeal.getVarCount() != bigIdeal.getVarCount())
293 return false;
294
295 const vector<mpz_class>& monomial = reflectionIdeal.getTerm(0);
296 const mpz_t* monomialPtr = 0;
297 if (reflectionIdeal.getVarCount() > 0)
298 monomialPtr = (const mpz_t*)&(monomial[0]);
299
300 return alexanderDual(ideal, monomialPtr, consumer);
301}
302
314
325
330public:
332 _varCount(0),
333 _consumer(consumer),
334 _term(0) {
335 ASSERT(_consumer != 0);
336 }
337
340
341 virtual void idealBegin(size_t varCount) {
342 _varCount = varCount;
343 _term.resize(varCount);
344 for (size_t var = 0; var < _varCount; ++var)
345 _term[var] = _zero.get_mpz_t();
346 }
347
348 virtual void idealEnd() {
349 _term.clear();
350 }
351
353 _consumer->idealBegin(_varCount);
354
355 bool isIdentity = true;
356 for (size_t var = 0; var < _varCount; ++var) {
357 if (mpz_cmp_ui(exponentVector[var], 0) != 0) {
358 isIdentity = false;
359 _term[var] = exponentVector[var];
360 _consumer->consume(&*(_term.begin()));
361 _term[var] = _zero.get_mpz_t();
362 }
363 }
364
365 _consumer->idealEnd();
366 }
367
368private:
369 size_t _varCount;
370 IdealConsumer* _consumer;
371 vector<mpz_ptr> _term;
373};
374
384
388 if (bigIdeal.getGeneratorCount() == 0)
389 return false;
390
392 (&consumer, bigIdeal.getVarCount());
395
396 facade.computeIrreducibleDecomposition(true);
397 return true;
398}
399
411
423
425 const mpz_t* l,
427 ASSERT(l != 0);
428
430
431 vector<mpz_class> grading;
432 for (size_t var = 0; var < bigIdeal.getVarCount(); ++var)
433 grading.push_back(mpz_class(l[var]));
434
436 (&consumer, bigIdeal.getVarCount());
438 params.useIndependenceSplits(false); // not supported
440
442 return facade.solveStandardProgram(grading, dummy, false);
443}
444
447 dimension(ideal, codim);
448 mpz_ui_sub(codim, bigIdeal.getVarCount(), codim);
449}
450
451void Frobby::dimension(const Ideal& ideal, mpz_t dim) {
453
454 IdealFacade facade(false);
455 mpz_class dimen = facade.computeDimension(bigIdeal, false);
456 mpz_set(dim, dimen.get_mpz_t());
457}
458
void nameFactoryRegister(NameFactory< AbstractProduct > &factory)
Registers the string returned by ConcreteProduct::getStaticName() to a function that default-construc...
ConsumerWrapper(size_t varCount)
Definition frobby.cpp:40
void setTerm(const vector< mpz_class > &term)
Definition frobby.cpp:58
size_t _varCount
Definition frobby.cpp:65
void setTerm(const Term &term, const TermTranslator &translator)
Definition frobby.cpp:49
virtual ~ConsumerWrapper()
Definition frobby.cpp:45
mpz_ptr * _term
Definition frobby.cpp:66
virtual void doneConsuming()
Must be called once after each time beginConsuming has been called.
Definition frobby.cpp:102
ExternalIdealConsumerWrapper(Frobby::IdealConsumer *consumer, size_t varCount)
Definition frobby.cpp:72
Frobby::IdealConsumer * _consumer
Definition frobby.cpp:107
virtual void consumeRing(const VarNames &names)
Tell the consumer which ring is being used.
Definition frobby.cpp:79
virtual void consume(const Term &term, const TermTranslator &translator)
Definition frobby.cpp:87
virtual void consume(const vector< mpz_class > &term)
Definition frobby.cpp:95
virtual void beginConsuming()
Tell the consumer to begin consuming an ideal.
Definition frobby.cpp:83
virtual void consume(const mpz_class &coef, const Term &term, const TermTranslator &translator)
Definition frobby.cpp:129
virtual void consumeRing(const VarNames &names)
Definition frobby.cpp:121
ExternalPolynomialConsumerWrapper(Frobby::PolynomialConsumer *consumer, size_t varCount)
Definition frobby.cpp:113
Frobby::PolynomialConsumer * _consumer
Definition frobby.cpp:157
virtual void consume(const mpz_class &coef, const vector< mpz_class > &term)
Definition frobby.cpp:139
This is the base of the Frobby exception hierarchy for exceptions that can occur due to expected erro...
Definition error.h:27
FrobbyIdealHelper(size_t variableCount)
Definition frobby.cpp:184
static const BigIdeal & getIdeal(const Frobby::Ideal &ideal)
Definition frobby.cpp:189
This class provides a way to get monomial ideals as output from Frobby one generator at a time.
Definition frobby.h:75
virtual void idealBegin(size_t varCount)
Called before output of a monomial ideal.
Definition frobby.cpp:164
virtual ~IdealConsumer()
The provided implementation does nothing.
Definition frobby.cpp:161
virtual void idealEnd()
Called after output of a monomial ideal.
Definition frobby.cpp:167
virtual void consume(mpz_ptr *exponentVector)=0
For output of a generator of the ideal.
Ideal & operator=(const Ideal &ideal)
Definition frobby.cpp:213
Ideal(size_t variableCount)
Definition frobby.cpp:201
FrobbyImpl::FrobbyIdealHelper * _data
Definition frobby.h:62
void addExponent(const mpz_t exponent)
Call addExponent once for each variable to add a term one exponent at a time.
Definition frobby.cpp:225
This class provides a way to get polynomials as output from Frobby one term at a time.
Definition frobby.h:112
virtual void polynomialBegin(size_t varCount)
Called before output of a polynomial.
Definition frobby.cpp:173
virtual ~PolynomialConsumer()
The provided implementation does nothing.
Definition frobby.cpp:170
virtual void polynomialEnd()
Called after output of a polynomial.
Definition frobby.cpp:176
virtual void consume(const mpz_t coefficient, mpz_ptr *exponentVector)=0
For output of a term of the polynomial.
A facade for performing operations on BigIdeal.
Definition IdealFacade.h:34
IdealConsumer * _consumer
Definition frobby.cpp:370
virtual void idealBegin(size_t varCount)
Called before output of a monomial ideal.
Definition frobby.cpp:341
virtual void idealEnd()
Called after output of a monomial ideal.
Definition frobby.cpp:348
vector< mpz_ptr > _term
Definition frobby.cpp:371
IrreducibleIdealDecoder(IdealConsumer *consumer)
Definition frobby.cpp:331
virtual void consume(mpz_ptr *exponentVector)
For output of a generator of the ideal.
Definition frobby.cpp:352
A facade for operations on monomial ideals using the Slice Algorithm.
Definition SliceFacade.h:44
void useIndependenceSplits(bool value)
Definition SliceParams.h:34
TermTranslator handles translation between terms whose exponents are infinite precision integers and ...
Term represents a product of variables which does not include a coefficient.
Definition Term.h:49
size_t getVarCount() const
Definition Term.h:85
Defines the variables of a polynomial ring and facilities IO involving them.
Definition VarNames.h:40
const char *const frobby_version
Definition frobby.cpp:36
The namespace FrobbyImpl is for internal use inside Frobby only.
Definition frobby.cpp:179
void dimension(const Ideal &ideal, mpz_t dim)
Compute the Krull dimension of a monomial ideal.
Definition frobby.cpp:451
bool alexanderDual(const Ideal &ideal, const mpz_t *reflectionMonomial, IdealConsumer &consumer)
Compute the Alexander dual of ideal using the point reflectionMonomial.
Definition frobby.cpp:250
void irreducibleDecompositionAsIdeals(const Ideal &ideal, IdealConsumer &consumer)
Compute the irreducible decomposition of ideal.
Definition frobby.cpp:375
void codimension(const Ideal &ideal, mpz_t codim)
Compute the codimension of a monomial ideal.
Definition frobby.cpp:445
void associatedPrimes(const Ideal &ideal, IdealConsumer &consumer)
Compute the associated primes of the ideal.
Definition frobby.cpp:459
void univariateHilbertPoincareSeries(const Ideal &ideal, PolynomialConsumer &consumer)
Compute the univariate Hilbert-Poincare series of ideal.
Definition frobby.cpp:315
bool solveStandardMonomialProgram(const Ideal &ideal, const mpz_t *l, IdealConsumer &consumer)
Solve the optimization program.
Definition frobby.cpp:424
bool irreducibleDecompositionAsMonomials(const Ideal &ideal, IdealConsumer &consumer)
Compute the irreducible decomposition of ideal, and encode each irreducible component as a monomial.
Definition frobby.cpp:385
void maximalStandardMonomials(const Ideal &ideal, IdealConsumer &consumer)
Compute the maximal standard monomials of ideal.
Definition frobby.cpp:412
void primaryDecomposition(const Ideal &ideal, IdealConsumer &consumer)
Compute the canonical primary decomposition of a monomial ideal.
Definition frobby.cpp:400
void multigradedHilbertPoincareSeries(const Ideal &ideal, PolynomialConsumer &consumer)
Compute the multigraded Hilbert-Poincare series of ideal.
Definition frobby.cpp:303
#define ASSERT(X)
Definition stdinc.h:86