14#define FLAG_TRACE_MORPHISMS 1
15#define FLAG_TRIM_COMPLEX 2
16#define FLAG_PRUNE_PMONE 4
17#define FLAG_PRUNE_SCALARS 8
18#define FLAG_PRUNE_ORIGIN 16
19#define FLAG_PRUNE_MAXIMAL 32
20#define FLAG_PRUNE_PRIME 64
21#define FLAG_BEST_UNIT 1024
22#define FLAG_BEST_MATRIX 2048
23#define FLAG_REV_ORDER 65536
32 const size_t n = i.index();
33 const std::pair<size_t, size_t> u = *i;
34 mDifferential[n]->get_entry(u.first, u.second, e);
41 for (
size_t r = 0; r <
mBetti[n]; ++r)
43 if (r == u.first)
continue;
44 mDifferential[n]->get_entry(r, u.second, e);
45 if (
mRing->is_zero(e))
continue;
52 for (
size_t c = 0; c <
mBetti[n + 1]; ++c)
54 if (c == u.second)
continue;
55 mDifferential[n]->get_entry(u.first, c, e);
56 if (
mRing->is_zero(e))
continue;
65 return static_cast<size_t>(
s);
72 for (; i < i.
end(); ++i)
74 mDifferential[i.
index()]->get_entry((*i).first, (*i).second, e);
75 if (
mRing->is_unit(e))
return true;
104 const size_t flags)
const
107 std::vector<iterator> units;
120 const size_t n = i.
index();
121 const std::pair<size_t, size_t> u = *i;
128 mDifferential[n]->interchange_rows(u.first,
mBetti[n] - 1);
129 if (0 < n) mDifferential[n - 1]->interchange_columns(u.first,
mBetti[n] - 1);
130 if (trace) mMorphisms[n]->interchange_columns(u.first,
mBetti[n] - 1);
132 mDifferential[n]->interchange_columns(u.second,
mBetti[n + 1] - 1);
133 if (n < mDifferential.size() - 1)
134 mDifferential[n + 1]->interchange_rows(u.second,
mBetti[n + 1] - 1);
136 mMorphisms[n + 1]->interchange_columns(u.second,
mBetti[n + 1] - 1);
139 mDifferential[n]->get_entry(
mBetti[n] - 1,
mBetti[n + 1] - 1,
p);
143 for (
size_t r = 0; r <
mBetti[n] - 1; ++r)
145 mDifferential[n]->get_entry(r,
mBetti[n + 1] - 1, f);
146 mDifferential[n]->row_op(r,
mRing->mult(f, q),
mBetti[n] - 1);
148 mDifferential[n - 1]->column_op(
mBetti[n] - 1,
mRing->mult(f,
p), r);
149 if (trace) mMorphisms[n]->column_op(
mBetti[n] - 1,
mRing->mult(f,
p), r);
152 for (
size_t c = 0; c <
mBetti[n + 1] - 1; ++c)
154 mDifferential[n]->get_entry(
mBetti[n] - 1, c, f);
155 mDifferential[n]->column_op(c,
mRing->mult(f, q),
mBetti[n + 1] - 1);
156 if (n < mDifferential.size() - 1)
157 mDifferential[n + 1]->row_op(
mBetti[n + 1] - 1,
mRing->mult(f,
p), c);
159 mMorphisms[n + 1]->column_op(c,
mRing->mult(f, q),
mBetti[n + 1] - 1);
179 const bool dense = mDifferential[0]->is_dense();
181 for (
size_t n = 0; n < mDifferential.size() + 1; ++n)
183 for (
size_t n = 0; n < mDifferential.size() && n < nsteps; n++)
205MutableComplex::prune_morphisms(
size_t nsteps,
size_t flags)
208 for (
size_t n = 0; n < mMorphisms.size(); ++n)
210 if (
mBetti[n] < mMorphisms[n]->n_cols())
211 mMorphisms[n]->delete_columns(
mBetti[n], mMorphisms[n]->n_cols() - 1);
236 for (
size_t i = 0; i < mDifferential.size(); i++) o <<
mBetti[i] <<
" <-- ";
237 o <<
mBetti[mDifferential.size()];
250 size_t nsteps =
static_cast<size_t>(n), flags =
static_cast<size_t>(f);
254 int N =
static_cast<int>(M.size());
255 engine_RawMutableMatrixArray A =
258 for (
int i = 0; i < N; ++i) A->array[i] = M[i];
264 size_t nsteps =
static_cast<size_t>(n), flags =
static_cast<size_t>(f);
265 std::vector<size_t> betti = C->
prune_betti(nsteps, flags);
267 int N =
static_cast<int>(betti.size());
269 for (
int i = 0; i < N; ++i) B->array[i] =
static_cast<int>(betti[i]);
275 size_t nsteps =
static_cast<size_t>(n), flags =
static_cast<size_t>(f);
285 for (
int i = 0; i < M->len; ++i) D.push_back(M->array[i]);
Cursor pointing at one entry of one differential matrix in the complex: a (matrix index,...
std::vector< size_t > mBetti
bool next_unit(iterator &i, const size_t flags) const
void prune_unit(const iterator &i, const size_t flags)
void prune_complex(const size_t nsteps, const size_t flags)
std::vector< size_t > prune_betti(const size_t nsteps, const size_t flags)
size_t complexity(const iterator &i, const size_t flags) const
void text_out(buffer &o) const
const LocalRing * mLocalRing
bool find_unit(iterator &i, const size_t flags) const
std::vector< iterator > list_units(size_t n, const size_t flags) const
const PolynomialRing * mPolynomialRing
void prune_matrix(size_t n, const size_t flags)
Sequence of MutableMatrix differentials representing an in-progress chain complex,...
unsigned int hash() const
static MutableMatrix * identity(const Ring *R, size_t nrows, bool dense)
Abstract base class for mutable matrices over an arbitrary engine Ring, the in-place counterpart of t...
Debugger-callable d* helpers that pretty-print engine values to stderr.
Engine-wide include prelude — a single point of truth for portability shims.
#define getmemarraytype(S, len)
M2_arrayint M2_makearrayint(int n)
#define FLAG_TRACE_MORPHISMS
unsigned int rawMutableComplexHash(const MutableComplex *M)
MutableComplex * rawPruneComplex(MutableComplex *C, int n, int f)
engine_RawMutableMatrixArray rawPruningMorphism(MutableComplex *C, int n, int f)
M2_arrayint rawPruneBetti(MutableComplex *C, int n, int f)
MutableComplex * rawMutableComplex(const engine_RawMutableMatrixArray M)
M2_string rawMutableComplexToString(const MutableComplex *M)
MutableComplex — in-place chain complex of MutableMatrix differentials.
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
Ring — the legacy abstract base class for every coefficient and polynomial ring.