Macaulay2 Engine
Loading...
Searching...
No Matches
matrix-ncbasis.cpp
Go to the documentation of this file.
1// Copyright 2018 Michael E. Stillman
2
3#include "matrix-ncbasis.hpp"
4
5#include <memory>
6
9#include "NCAlgebras/Word.hpp"
11
12#include "interrupted.hpp"
13#include "monoid.hpp"
14
15std::unique_ptr<WordTable> constructWordTable(const FreeAlgebra& A, const ConstPolyList& gb)
16{
17 std::unique_ptr<WordTable> W { new WordTable };
18
19 // Build the word table for the reduction
20 for (auto& f : gb)
21 {
22 auto i = f->cbegin();
23 Word tmp;
24 A.monoid().wordFromMonom(tmp,i.monom());
25 W->insert(tmp);
26 }
27 return W;
28}
29
44class NCBasis : public our_new_delete
45{
46private:
49
50 std::vector<int> mVariables; // the variable indices being used.
51 std::vector<int> mVariableHefts; // matches mVariables array.
52
53 // Word table of all lead terms from the input GB
54 std::unique_ptr<WordTable> mWordTable;
55
56 // Construction of monomials: these are used in the recursion.
57 std::vector<int> mMonomial; // word being constructed.
58 int mCurrentIndex; // into mMonomial... this is where we place next variable.
59 int mCurrentHeftValue; // heft value so far, of monomial being constructed.
60
61 // Result
63
64 // Input degree bounds, and input options
65 int mLimit; // if >= 0, then number of monomials to collect. <0 means no limit.
66 int mLoHeft; // 0 if -infinity was given
67 int mHiHeft; // -1 if infinity was given
68
69 // do we need these? Keep for now.
70 // // const int* mLoDegree; // either nullptr (if -infinity), or an array of length = degreeRank
71 // // const int* mHiDegree; // an array of length = degreeRank
72 // // enum { KB_SINGLE, KB_MULTI } mComputationType;
73 // // const int* mCurrentMultiDegree; // only used in multi-grading case?
74 // // const int* mMultiDegree; // target multi-degree in the multi-graded case.
75
76 // // std::vector<int> mHeftVector; // length: degreeRank := degreeMonoid().numVars()
77 // // std::vector<int> mLoDegree; // either nullptr (if -infinity), or an array of length = degreeRank
78 // // std::vector<int> mHiDegree; // an array of length = degreeRank
79
80public:
81 // TODO: add in a list of variable indices.
82 // add in heft vectors, multi-degree.
84 const ConstPolyList& gb,
85 const std::vector<int>& lo_degree,
86 const std::vector<int>& hi_degree,
87 int limit
88 )
89 :
90 mFreeAlgebra(A),
91 mMonoid(A.monoid()),
92 mVariableHefts(A.monoid().flattenedDegrees()),
94 mCurrentIndex(-1),
96 mLimit(limit),
97 mLoHeft(0),
98 mHiHeft(-1)
99 {
100 // TODO: set mVariables and their hefts from mMonoid info.
101 for (auto i = 0; i < mMonoid.numVars(); ++i)
102 mVariables.push_back(i);
103
104 if (lo_degree.size() > 0) mLoHeft = lo_degree[0];
105 if (hi_degree.size() > 0) mHiHeft = hi_degree[0];
106 }
107
109 {
110 if (mLimit != 0) basis0();
111 return mBasis;
112 }
113
114private:
115 void insert(); // takes mMonomial, and makes a polynomial from it (but with new memory), appending to mBasis.
116 void basis0(); // the main recursion step
117};
118
120{
121 Poly* result = new Poly;
122 mFreeAlgebra.from_word(*result, Word(mMonomial.data(), mMonomial.data() + mCurrentIndex + 1));
123 mBasis.push_back(result);
124 if (mLimit > 0) mLimit--;
125}
126
128{
129 if (system_interrupted()) return;
130
131 // order of events:
132 // 1. check if the degree is greater than hi_degree. If so, exit.
133 // 2. check if a suffix of the current word is a pattern in the WordTable. If so, exit.
134 // 3. if the degree is >= lo_degree, then call insert.
135 // 4. if the degree is equal to hi_degree, then exit (no recursion necessary)
136 // 5. for each variable, append the variable to the state monomial, and make recursive call.
137
138 Word tmpWord(mMonomial.data(),mMonomial.data() + mCurrentIndex + 1);
139 int notUsed;
140
141 if (mHiHeft != -1 and mCurrentHeftValue > mHiHeft) return;
142
143 if (mWordTable->isSuffix(tmpWord,notUsed)) return;
144
146
147 if (mHiHeft != -1 and mCurrentHeftValue == mHiHeft) return;
148
149 // this ensures that we do not move past allocated memory in the loop below
150 if (mMonomial.size() <= mCurrentIndex + 1) mMonomial.push_back(0);
151
153 for (int i = 0; i < mVariables.size(); ++i)
154 {
157
158 basis0();
159
161
162 if (mLimit == 0) return;
163 }
165}
166
168 const FreeAlgebra& A,
169 const ConstPolyList& gb, // actually, only the lead terms are ever considered
170 const std::vector<int>& lo_degree, // length 0: means -infinity, i.e. 0.
171 const std::vector<int>& hi_degree, // length 0: +infinity
172 int limit, // <0 means no limit
174 )
175{
176 if (A.monoid().degreeMonoid().n_vars() != 1)
177 {
178 ERROR("expected singly graded algebra");
179 return false;
180 }
181 if (lo_degree.size() > 1 or hi_degree.size() > 1)
182 {
183 ERROR("expected singly graded algebra");
184 return false;
185 }
186 NCBasis computation(A, gb, lo_degree, hi_degree, limit);
187 std::swap(result, computation.compute());
188 return true;
189}
190
191// Local Variables:
192// compile-command: "make -C $M2BUILDDIR/Macaulay2/e"
193// indent-tabs-mode: nil
194// End:
Free associative algebra k<x_1,...,x_n> over an arbitrary coefficient ring.
FreeMonoid — monoid of length-prefixed non-commutative words with weight-vector prefix.
gc_vector< const Poly * > ConstPolyList
Polynomial< CoefficientRingType > Poly
gc_vector< Poly * > PolyList
Word and WordWithData — non-owning views over the flat-int encoding of a non-commutative word.
WordTable / WordWithDataTable — leading-word indices for non-commutative Gröbner basis lookup.
const FreeMonoid & monoid() const
Free associative algebra over a coefficient ring: the non-commutative analogue of PolynomialRing.
const Monoid & degreeMonoid() const
void wordFromMonom(Word &result, const Monom &m) const
The free non-commutative monoid on a set of named variables, with monomial ordering and degree / weig...
int n_vars() const
Definition monoid.hpp:207
const FreeMonoid & mMonoid
PolyList mBasis
const FreeAlgebra & mFreeAlgebra
std::vector< int > mMonomial
std::vector< int > mVariables
std::vector< int > mVariableHefts
NCBasis(const FreeAlgebra &A, const ConstPolyList &gb, const std::vector< int > &lo_degree, const std::vector< int > &hi_degree, int limit)
int mCurrentHeftValue
std::unique_ptr< WordTable > mWordTable
PolyList & compute()
Non-commutative analogue of KBasis: enumerates basis monomials of a FreeAlgebra quotient up to a degr...
Non-owning view of a non-commutative word: [begin, end) of int variable indices.
Definition Word.hpp:56
Index of Words (non-commutative monomials) with subword, prefix/suffix, and overlap lookup used by th...
Definition WordTable.hpp:89
void gb(IntermediateBasis &F, int n)
bool ncBasis(const FreeAlgebra &A, const ConstPolyList &gb, const std::vector< int > &lo_degree, const std::vector< int > &hi_degree, int limit, PolyList &result)
bool system_interrupted()
system_interrupted() — thread-safe polling predicate for Ctrl+C handling.
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
std::unique_ptr< WordTable > constructWordTable(const FreeAlgebra &A, const ConstPolyList &gb)
ncBasis — non-commutative analogue of basis(d, M) over NCAlgebras/FreeAlgebra.
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
Definition mpreal.h:3244