HilbertStrategy.cpp
Go to the documentation of this file.
/* Frobby: Software for monomial ideal computations.
Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
*/
#include "stdinc.h"
#include "HilbertStrategy.h"
#include "Term.h"
#include "HilbertSlice.h"
#include "Ideal.h"
#include "CoefTermConsumer.h"
#include "Projection.h"
#include "IndependenceSplitter.h"
#include "HilbertIndependenceConsumer.h"
#include "ElementDeleter.h"
HilbertStrategy::HilbertStrategy(CoefTermConsumer* consumer,
const SplitStrategy* splitStrategy):
SliceStrategyCommon(splitStrategy),
_consumerCache(),
_consumerCacheDeleter(_consumerCache),
_consumer(consumer) {
}
void HilbertStrategy::run(const Ideal& ideal) {
ASSERT(_consumer != 0);
size_t varCount = ideal.getVarCount();
Ideal sliceIdeal(varCount);
if (!ideal.contains(Term(varCount))) {
_consumer->consume(1, Term(varCount));
if (ideal.getGeneratorCount() > 0) {
Term allOnes(varCount);
for (size_t var = 0; var < varCount; ++var)
allOnes[var] = 1;
sliceIdeal = ideal;
sliceIdeal.product(allOnes);
}
}
unique_ptr<Slice> slice
(new HilbertSlice(*this, sliceIdeal, Ideal(varCount),
Term(varCount), _consumer));
simplify(*slice);
_tasks.addTask(slice.release());
_tasks.runTasks();
_consumerCacheDeleter.deleteElements();
}
bool HilbertStrategy::processSlice
(TaskEngine& tasks, unique_ptr<Slice> slice) {
ASSERT(slice.get() != 0);
ASSERT(debugIsValidSlice(slice.get()));
if (slice->baseCase(getUseSimplification())) {
freeSlice(std::move(slice));
return true;
}
if (getUseIndependence() && _indepSplitter.analyze(*slice)) {
independenceSplit(std::move(slice));
} else {
ASSERT(_split->isPivotSplit());
pivotSplit(std::move(slice));
}
return false;
}
unique_ptr<HilbertSlice> HilbertStrategy::newHilbertSlice() {
unique_ptr<Slice> slice(newSlice());
ASSERT(debugIsValidSlice(slice.get()));
return unique_ptr<HilbertSlice>(static_cast<HilbertSlice*>(slice.release()));
}
unique_ptr<Slice> HilbertStrategy::allocateSlice() {
return unique_ptr<Slice>(new HilbertSlice(*this));
}
bool HilbertStrategy::debugIsValidSlice(Slice* slice) {
ASSERT(slice != 0);
ASSERT(dynamic_cast<HilbertSlice*>(slice) != 0);
return true;
}
void HilbertStrategy::getPivot(Term& term, Slice& slice) {
ASSERT(term.getVarCount() == slice.getVarCount());
_split->getPivot(term, slice);
}
void HilbertStrategy::freeConsumer(unique_ptr<HilbertIndependenceConsumer>
consumer) {
ASSERT(consumer.get() != 0);
ASSERT(std::find(_consumerCache.begin(),
_consumerCache.end(), consumer.get()) ==
_consumerCache.end());
consumer->clear();
noThrowPushBack(_consumerCache, std::move(consumer));
}
void HilbertStrategy::independenceSplit(unique_ptr<Slice> sliceParam) {
ASSERT(sliceParam.get() != 0);
ASSERT(debugIsValidSlice(sliceParam.get()));
unique_ptr<HilbertSlice> slice
(static_cast<HilbertSlice*>(sliceParam.release()));
// Construct split object.
unique_ptr<HilbertIndependenceConsumer> autoSplit = newConsumer();
autoSplit->reset(slice->getConsumer(), _indepSplitter, slice->getVarCount());
HilbertIndependenceConsumer* split = autoSplit.release();
_tasks.addTask(split); // Runs when we are done with all of this split.
// Construct left slice.
unique_ptr<HilbertSlice> leftSlice(newHilbertSlice());
leftSlice->setToProjOf(*slice, split->getLeftProjection(),
split->getLeftConsumer());
_tasks.addTask(leftSlice.release());
// Construct right slice.
unique_ptr<HilbertSlice> rightSlice(newHilbertSlice());
rightSlice->setToProjOf(*slice, split->getRightProjection(),
split->getRightConsumer());
_tasks.addTask(rightSlice.release());
// Deal with slice.
freeSlice(std::move(slice));
}
unique_ptr<HilbertIndependenceConsumer> HilbertStrategy::newConsumer() {
if (_consumerCache.empty())
return unique_ptr<HilbertIndependenceConsumer>
(new HilbertIndependenceConsumer(this));
unique_ptr<HilbertIndependenceConsumer> consumer(_consumerCache.back());
_consumerCache.pop_back();
return consumer;
}
CoefTermConsumer.h
ElementDeleter.h
noThrowPushBack
void noThrowPushBack(Container &container, unique_ptr< Element > pointer)
Definition ElementDeleter.h:141
HilbertIndependenceConsumer.h
HilbertSlice.h
HilbertStrategy.h
Ideal.h
IndependenceSplitter.h
Projection.h
Term.h
CoefTermConsumer
Definition CoefTermConsumer.h:24
HilbertIndependenceConsumer
Definition HilbertIndependenceConsumer.h:31
HilbertIndependenceConsumer::getRightConsumer
CoefTermConsumer * getRightConsumer()
Definition HilbertIndependenceConsumer.cpp:81
HilbertIndependenceConsumer::getRightProjection
const Projection & getRightProjection() const
Definition HilbertIndependenceConsumer.cpp:91
HilbertIndependenceConsumer::getLeftProjection
const Projection & getLeftProjection() const
Definition HilbertIndependenceConsumer.cpp:86
HilbertIndependenceConsumer::getLeftConsumer
CoefTermConsumer * getLeftConsumer()
Definition HilbertIndependenceConsumer.cpp:60
HilbertSlice
Definition HilbertSlice.h:27
HilbertStrategy::processSlice
virtual bool processSlice(TaskEngine &tasks, unique_ptr< Slice > slice)
Process the parameter slice.
Definition HilbertStrategy.cpp:67
HilbertStrategy::newConsumer
unique_ptr< HilbertIndependenceConsumer > newConsumer()
Definition HilbertStrategy.cpp:147
HilbertStrategy::getPivot
virtual void getPivot(Term &term, Slice &slice)
Used by pivotSplit to obtain a pivot.
Definition HilbertStrategy.cpp:102
HilbertStrategy::_consumerCacheDeleter
ElementDeleter< vector< HilbertIndependenceConsumer * > > _consumerCacheDeleter
Definition HilbertStrategy.h:57
HilbertStrategy::HilbertStrategy
HilbertStrategy(CoefTermConsumer *consumer, const SplitStrategy *splitStrategy)
Definition HilbertStrategy.cpp:29
HilbertStrategy::debugIsValidSlice
virtual bool debugIsValidSlice(Slice *slice)
Check that this slice is valid for use with this strategy.
Definition HilbertStrategy.cpp:96
HilbertStrategy::_indepSplitter
IndependenceSplitter _indepSplitter
Definition HilbertStrategy.h:53
HilbertStrategy::_consumerCache
vector< HilbertIndependenceConsumer * > _consumerCache
Definition HilbertStrategy.h:56
HilbertStrategy::_consumer
CoefTermConsumer * _consumer
Definition HilbertStrategy.h:59
HilbertStrategy::run
virtual void run(const Ideal &ideal)
Run the Slice algorithm.
Definition HilbertStrategy.cpp:37
HilbertStrategy::freeConsumer
void freeConsumer(unique_ptr< HilbertIndependenceConsumer > consumer)
Definition HilbertStrategy.cpp:108
HilbertStrategy::allocateSlice
virtual unique_ptr< Slice > allocateSlice()
Directly allocate a slice of the correct type using new.
Definition HilbertStrategy.cpp:92
HilbertStrategy::newHilbertSlice
unique_ptr< HilbertSlice > newHilbertSlice()
Definition HilbertStrategy.cpp:86
HilbertStrategy::independenceSplit
void independenceSplit(unique_ptr< Slice > slice)
Definition HilbertStrategy.cpp:119
Ideal
Represents a monomial ideal with int exponents.
Definition Ideal.h:27
Ideal::product
void product(const Exponent *term)
Definition Ideal.cpp:525
Ideal::getGeneratorCount
size_t getGeneratorCount() const
Definition Ideal.h:57
Ideal::contains
bool contains(const Exponent *term) const
Definition Ideal.cpp:57
Ideal::getVarCount
size_t getVarCount() const
Definition Ideal.h:56
SliceStrategyCommon::getUseIndependence
bool getUseIndependence() const
Returns true if independence splits should be performed when possible.
Definition SliceStrategyCommon.cpp:113
SliceStrategyCommon::getUseSimplification
bool getUseSimplification() const
Returns true if slices should be simplified.
Definition SliceStrategyCommon.cpp:117
SliceStrategyCommon::_split
const SplitStrategy * _split
Definition SliceStrategyCommon.h:80
SliceStrategyCommon::freeSlice
virtual void freeSlice(unique_ptr< Slice > slice)
It is allowed to delete returned slices directly, but it is better to use freeSlice.
Definition SliceStrategyCommon.cpp:39
SliceStrategyCommon::simplify
virtual bool simplify(Slice &slice)
Simplifies slice and returns true if it changed.
Definition SliceStrategyCommon.cpp:55
SliceStrategyCommon::pivotSplit
virtual void pivotSplit(unique_ptr< Slice > slice)
Takes over ownership of slice.
Definition SliceStrategyCommon.cpp:77
SliceStrategyCommon::SliceStrategyCommon
SliceStrategyCommon(const SplitStrategy *splitStrategy)
Definition SliceStrategyCommon.cpp:24
SliceStrategyCommon::newSlice
unique_ptr< Slice > newSlice()
Returns a slice from the cache that freeSlice adds to, or allocate a new one using allocateSlice.
Definition SliceStrategyCommon.cpp:65
SliceStrategyCommon::_tasks
TaskEngine _tasks
This keeps track of pending tasks to process.
Definition SliceStrategyCommon.h:84
Slice
This class represents a slice, which is the central data structure of the Slice Algorithm.
Definition Slice.h:77
Slice::getVarCount
size_t getVarCount() const
Returns the number of variables in the ambient ring.
Definition Slice.h:96
SplitStrategy
A SplitStrategy is an implementation of a split selection strategy for the Slice Algorithm.
Definition SplitStrategy.h:30
TaskEngine
TaskEngine handles a list of tasks that are to be carried out.
Definition TaskEngine.h:40
Term
Term represents a product of variables which does not include a coefficient.
Definition Term.h:49
Term::getVarCount
size_t getVarCount() const
Definition Term.h:85
stdinc.h
This header file includes common definitions and is included as the first line of code in every imple...
ASSERT
#define ASSERT(X)
Definition stdinc.h:86