2 * File: GroebnerBase.tpp
5 * Created on 8. August 2016, 16:15
13 template<typename Number>
14 bool GroebnerBase<Number>::hasFiniteMon() const {
15 std::set<Variable> vars = this->gatherVariables();
16 std::vector<typename GroebnerBase<Number>::Monomial> lmons = this->cor();
17 for (const auto& v: vars) {
19 for (const auto& m : lmons) {
20 assert(is_one(m.coeff()));
21 if (m.has_no_other_variable(v)) {
26 if (found) return false;
32 template<typename Number>
33 std::vector<typename GroebnerBase<Number>::Monomial> GroebnerBase<Number>::cor() const {
34 std::vector<typename GroebnerBase<Number>::Monomial> res;
35 for(const auto& p : this->get()) {
36 res.push_back(GroebnerBase<Number>::Monomial(p.lmon()));
41 // general helper function
42 // returns true iff any of the monomials in list divides m
43 template<typename Number>
44 bool anyDivides(const std::vector<typename GroebnerBase<Number>::Monomial>& list, const typename GroebnerBase<Number>::Monomial& m) {
45 CARL_LOG_ASSERT("carl.thom.groebner", is_one(m.coeff()), "invalid monomial!");
46 for(const auto& m_prime : list) {
47 CARL_LOG_ASSERT("carl.thom.groebner", is_one(m_prime.coeff()), "invalid monomial!");
48 if(m.divisible(m_prime)) {
57 // this is a helper function for mon
58 template<typename Number> // i dont know why this has to be a template but i get a linker error if its not
59 bool nextTuple(std::vector<carl::uint>& tuple, const std::vector<carl::uint>& maxTuple) {
60 assert(tuple.size() == maxTuple.size());
61 if(tuple[0] < maxTuple[0]) {
66 assert(tuple[0] == maxTuple[0]);
68 for(carl::uint i = 1; i < tuple.size(); i++) {
69 if(tuple[i] < maxTuple[i]) {
70 for(carl::uint j = 0; j < i; j++) tuple[j] = 0;
82 template<typename Number>
83 std::vector<typename GroebnerBase<Number>::Monomial> GroebnerBase<Number>::mon() const {
84 CARL_LOG_FUNC("carl.thom.groebner", "groebner base: " << this->get());
85 CARL_LOG_ASSERT("carl.thom.groebner", this->hasFiniteMon(), "tried to compute mon of non-zerodimensional system");
86 std::set<Variable> varsset = this->gatherVariables();
87 std::vector<Variable> vars(varsset.begin(), varsset.end());
88 std::vector<typename GroebnerBase<Number>::Monomial> lmons = this->cor();
89 std::vector<uint> degrees;
90 for(const auto& v : vars) {
91 for(const auto& m : lmons) {
92 CARL_LOG_ASSERT("carl.thom.groebner", is_one(m.coeff()), "invalid monomial!");
93 if(m.has_no_other_variable(v)) {
94 degrees.push_back(m.monomial()->tdeg());
99 CARL_LOG_ASSERT("carl.thom.groebner", degrees.size() == vars.size(), "");
100 CARL_LOG_TRACE("carl.thom.groebner", "variables: " << vars);
101 CARL_LOG_TRACE("carl.thom.groebner", "vector of degrees: " << degrees);
103 std::vector<typename GroebnerBase<Number>::Monomial> res;
104 std::vector<uint> currTuple(degrees.size(), 0);
106 typename GroebnerBase<Number>::Monomial candidate(Number(1));
107 for(uint i = 0; i < currTuple.size(); i++) {
108 for(uint d = 0; d < currTuple[i]; d++) {
109 candidate = candidate * vars[i];
112 if(!anyDivides<Number>(lmons, candidate)) {
113 res.push_back(candidate);
116 while(::nextTuple<Number>(currTuple, degrees));
117 CARL_LOG_TRACE("carl.thom.groebner", "result: " << res);
121 template<typename Number>
122 std::vector<typename GroebnerBase<Number>::Monomial> GroebnerBase<Number>::bor() const {
123 std::vector<typename GroebnerBase<Number>::Monomial> res;
124 std::vector<typename GroebnerBase<Number>::Monomial> lmons = this->cor();
125 std::set<Variable> vars = this->gatherVariables();
126 std::vector<typename GroebnerBase<Number>::Monomial> _mon = this->mon();
127 for(const Variable& v : vars) {
128 for(const auto& m : _mon) {
129 assert(is_one(m.coeff()));
130 typename GroebnerBase<Number>::Monomial currMon = m * v;
131 if(std::find(res.begin(), res.end(), currMon) == res.end()) { // not already contained in res
132 if(std::find(_mon.begin(), _mon.end(), currMon) == _mon.end()) { // not contained in _mon
133 res.push_back(currMon);
141 template<typename Number>
142 std::set<Variable> GroebnerBase<Number>::gatherVariables() const {
144 for(const auto& p : this->get()) {
145 carl::variables(p, vars);
147 return vars.as_set();