1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
#ifndef __montable_h
#define __montable_h
#include "mem.hpp"
#include <vector>
#include <memory>
#include <algorithm>
#include <stdio.h>
#include <stddef.h>
#include "newdelete.hpp"
#include "style.hpp"
/* "Tricks" used in this implementation */
/*
1. exponent vectors: these look like: [e1, ..., en],
where n is the number of variables. HOWEVER, these
exponents are never created or freed by these routines,
so if they have more entries (e.g. a "sugar" homogenization)
then that (those) value(s) are ignored.
2. comparison routine: elements are kept in (increasing?) lex order.
Is this really an OK idea?
*/
typedef int *exponents;
class MonomialTable : public our_new_delete
{
static MonomialTable *make_minimal(int nvars,
const VECTOR(exponents) & exps,
const VECTOR(int) & comps,
const VECTOR(int) & vals,
VECTOR(int) & rejects);
static void minimalize(int nvars,
const VECTOR(exponents) & exps,
const VECTOR(int) & comps,
bool keep_duplicates,
VECTOR(int) & result_positions);
MonomialTable(); // the public must use "make" below
public:
struct mon_term
{
mon_term *_next;
mon_term *_prev;
exponents _lead; /* Who owns this? */
unsigned long _mask;
int _val;
};
static MonomialTable *make(
int nvars); // this function serves as the constructor
/* Create a zero element table */
~MonomialTable();
void insert(exponents exp, int comp, int id);
/* Insert [exp,comp,id] into the table. If there is already
an element which is <= [exp,comp], this triple is still
inserted. If that is not desired, use find_divisors.
*/
int find_divisor(exponents exp, int comp);
/* returns the integer 'val' of the first divisor of exp*comp found,
or, returns -1 if none is found. */
int find_divisors(int max,
exponents exp,
int comp,
VECTOR(mon_term *) *result = 0);
/* max: the max number of divisors to find.
exp: the monomial whose divisors we seek.
result: an array of mon_term's.
return value: length of this array, i.e. the number of matches found */
mon_term *find_exact(exponents exp, int comp) const;
/* If this returns non-NULL, it is valid to grab the 'val' field, and/or to
assign to it.
All other fields should be considered read only */
/* Need a way of looping through the elements? */
void show(FILE *fil); /* Only for debugging */
private:
stash *mon_term_stash;
int _nvars;
int _count;
VECTOR(mon_term *) _head; /* One per component */
mon_term *_last_match; // optimization cache for find_divisors
int _last_match_comp; // optimization cache for find_divisors
mon_term *make_list_head();
static void move_up(mon_term *const y, mon_term *const head);
static void insert_before(mon_term *const y, mon_term *const z);
static void remove(mon_term *const y);
};
#endif
// Local Variables:
// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
// indent-tabs-mode: nil
// End:
|