57 void printIndentedMatrix(
const Matrix& matrix) {
67 void printNullSpace(
const Matrix& matrix) {
70 transpose(nullSpaceBasis, nullSpaceBasis);
72 fputs(
"The right null space is spanned by the rows of\n",
74 printIndentedMatrix(nullSpaceBasis);
77 class NeighborPrinter {
79 NeighborPrinter(
const GrobLat& lat):
83 _labelIndex = _pr.getColumnCount();
84 _pr.addColumn(
false,
" ");
87 _hHeader = _pr.getColumnCount();
88 _pr.addColumn(
false,
" ",
"");
89 _hIndex = _pr.getColumnCount();
90 for (
size_t i = 0; i < _lat.getHDim(); ++i)
91 _pr.addColumn(
false, i == 0 ?
" " :
" ");
93 _comma = _pr.getColumnCount();
94 _pr.addColumn(
false,
"",
" ");
97 _yHeader = _pr.getColumnCount();
98 _pr.addColumn(
false,
" ",
"");
99 _yIndex = _pr.getColumnCount();
100 for (
size_t i = 0; i < _lat.getYDim(); ++i)
101 _pr.addColumn(
false, i == 0 ?
" " :
" ");
104 _hitsHeader = _pr.getColumnCount();
105 _pr.addColumn(
false,
" ",
"");
106 _hits = _pr.getColumnCount();
107 _pr.addColumn(
false,
" ",
"");
110 _edgeHeader = _pr.getColumnCount();
111 _pr.addColumn(
false,
" ",
"");
112 _edge = _pr.getColumnCount();
113 _pr.addColumn(
false,
" ",
"");
116 void addNeighbor(
Neighbor neighbor) {
117 printNeighborOnly(neighbor);
118 _pr[_hitsHeader] <<
'\n';
120 _pr[_edgeHeader] <<
'\n';
124 void addMlfbPoint(
Neighbor neighbor,
128 printNeighborOnly(neighbor, plane.
getPlace(neighbor));
129 _pr[_hitsHeader] <<
"hits\n";
130 _pr[_hits] << hits.
getName() <<
'\n';
131 _pr[_edgeHeader] <<
"push to\n";
132 _pr[_edge] << edge.
getName(plane) <<
'\n';
135 void addEmptyLine() {
136 for (
size_t i = 0; i < _pr.getColumnCount(); ++i)
140 void print(FILE* out) {
144 void print(ostream& out) {
150 _pr[_labelIndex] << neighbor.
getName() <<
':';
153 _pr[_labelIndex] <<
'\n';
155 _pr[_yHeader] <<
"y=\n";
156 for (
size_t i = 0; i < neighbor.
getYDim(); ++i)
157 _pr[_yIndex + i] << neighbor.
getY(i) <<
'\n';
158 _pr[_comma] <<
",\n";
159 _pr[_hHeader] <<
"h=\n";
160 for (
size_t i = 0; i < neighbor.
getHDim(); ++i)
161 _pr[_hIndex + i] << neighbor.
getH(i) <<
'\n';
178 void printMinDotDegreeMlfb(vector<Mlfb>& mlfbs) {
179 Mlfb* min = &(mlfbs[0]);
180 for (
size_t i = 1; i < mlfbs.size(); ++i) {
181 Mlfb& mlfb = mlfbs[i];
185 cout <<
"The MLFB " << min->
getName() <<
" has minimal rhs dot product.\n";
188 void printNeighbors(
const GrobLat& lat) {
189 NeighborPrinter pr(lat);
194 fprintf(stdout,
"\nThe %u neighbors in y-space and h-space are\n",
202 MlfbPtrCmp(
const Plane& plane): _plane(plane) {}
203 bool operator()(
const Mlfb* a,
const Mlfb* b) {
204 size_t ta = _plane.getType(*a);
205 size_t tb = _plane.getType(*b);
218 void printMlfbs(vector<Mlfb>& mlfbs,
const Plane& plane,
const GrobLat& lat) {
220 for (
size_t i = 0; i < mlfbs.size(); ++i)
221 order.push_back(&(mlfbs[i]));
222 sort(order.begin(), order.end(), MlfbPtrCmp(plane));
225 for (
size_t i = 0; i < order.size(); ++i) {
226 Mlfb& mlfb = *(order[i]);
227 cout <<
"*** MLFB " << mlfb.
getName(plane) <<
" with rhs";
228 for (
size_t var = 0; var < lat.
getYDim(); ++var)
229 cout <<
' ' << mlfb.
getRhs()[var];
230 cout <<
" contains the neighbors\n";
232 NeighborPrinter pr(lat);
240 cout <<
"Its index is " << mlfb.
index <<
", its rhs dot product is " <<
242 << plane.
getType(mlfb) <<
" plane neighbors.\n\n";
246 void prSeq(
const vector<SeqPos>& seq,
const Plane& plane) {
248 for (
size_t i = 0; i < seq.size(); ++i)
249 cout << (i > 0 ?
"->" :
"") << seq[i].mlfb->getName(plane);
253 void printPlane(vector<Mlfb>& mlfbs,
const Plane& plane,
const GrobLat& lat) {
254 cout <<
"The plane's null space is spanned by the rows of\n";
258 const vector<SeqPos>& flatSeq = plane.
flatSeq;
263 for (
size_t i = plane.
getMaxType(); i > 0; --i)
265 <<
" MLFBs with " << i <<
" plane neighbors.\n";
268 const Tri& tri = plane.
tri;
269 cout <<
"The non-flat triangle of the plane is "
275 cout <<
"\nThe MLFBs containing {zero,"
280 cout <<
"\nThe MLFBs containing {zero,"
285 cout <<
"\nThe neighbors on the boundary of the body defined by {zero,"
290 NeighborPrinter pr(lat);
295 cout <<
"and those in the interior are\n";
297 NeighborPrinter pr(lat);
304 printMlfbs(mlfbs, plane, lat);
306 const vector<const Mlfb*>& pivots = plane.
pivots;
308 CHECK((pivots.size() % 2) == 0);
312 pivots.size() == 4 &&
313 flatSeq.size() > 0));
315 if (flatSeq.size() == 0 || pivots.size() != 4) {
316 cout <<
"(Falling back to general framework as no flats or more than 4 pivots)\n\n";
318 vector<vector<SeqPos> > left;
319 vector<vector<SeqPos> > right;
322 cout <<
"The left sequences are:\n";
323 for (
size_t j = 0; j < left.size(); ++j)
324 prSeq(left[j], plane);
326 cout <<
"The right sequences are:\n";
327 for (
size_t j = 0; j < right.size(); ++j)
328 prSeq(right[j], plane);
337 vector<vector<SeqPos> > leftSeqs;
338 vector<vector<SeqPos> > rightSeqs;
343 cout <<
"The left sequences are:\n";
344 for (
size_t j = 0; j < leftSeqs.size(); ++j)
345 prSeq(leftSeqs[j], plane);
346 cout <<
"The flat sequence is:\n";
347 prSeq(flatSeq, plane);
348 cout <<
"The right sequences are:\n";
349 for (
size_t j = 0; j < rightSeqs.size(); ++j)
350 prSeq(rightSeqs[j], plane);
359 void printInteriorNeighborGraph(
const GrobLat& lat,
360 const vector<Mlfb>& mlfbs,
361 const vector<Plane>& planes) {
362 ofstream out(
"interior.dot");
363 out <<
"digraph G {\n" << flush;
366 out <<
' ' << from.
getName() <<
";\n";
375 <<
" [label=\"" << to.
getName();
376 for (
size_t m = 0; m < mlfbs.size(); ++m) {
377 const Mlfb& mlfb = mlfbs[m];
383 for (
size_t p = 0; p < planes.size(); ++p) {
384 const Plane& plane = planes[p];
386 out <<
" p" << (p + 1);
388 out <<
"\",style=dotted,arrowhead=empty";
397 void printScarfGraph(
const vector<Mlfb>& mlfbs) {
398 ofstream out(
"graph.dot");
399 out <<
"graph G {\n";
400 for (
size_t m = 0; m < mlfbs.size(); ++m) {
401 const Mlfb& mlfb = mlfbs[m];
402 out <<
" " << mlfb.
getName() <<
"[label=\"";
404 out <<
"\", shape=box];\n";
406 for (
size_t e = 0; e < mlfb.
edges.size(); ++e) {
412 <<
" -- " << mlfb.
edges[e]->getName() <<
" [";
413 out <<
"headport=" <<
getEdgePos(hits) <<
", ";
414 out <<
"tailport=" <<
getEdgePos(e) <<
"];\n";
420 void printMathematica3D(vector<Mlfb>& mlfbs,
const GrobLat& lat) {
421 ofstream out(
"ma3d");
423 for (
size_t m = 0; m < mlfbs.size(); ++m) {
424 out <<
" Graphics3D[{RGBColor[";
425 for (
size_t i = 0; i < 3; ++i) {
428 out <<
"0." << (rand() % 10000);
430 out <<
"],Polygon[{";
432 Mlfb& mlfb = mlfbs[m];
437 for (
size_t i = 0; i < lat.
getHDim(); ++i) {
446 out <<
" Graphics3D[Point[{0,0,0}]]\n};\ng=Show[{a},Boxed->False];\n";
449 void printThinPlanes(
const vector<TriPlane>& thinPlanes) {
450 Matrix matrix(thinPlanes.size(), 3);
452 for (
size_t p = 0; p < thinPlanes.size(); ++p)
453 copyRow(matrix, p, thinPlanes[p].getNormal(), 0);
455 cout <<
"The " << thinPlanes.size() <<
" thin planes' normals are the rows of" << endl;
463 "Display information about the input ideal.",
464 "This action is not ready for general use.\n\n"
465 "Display information about input Grobner basis of lattice.",
481 cerr <<
"** Reading input " << endl;
498 cerr <<
"** Computing matrix and its nullspace" << endl;
499 cout <<
"Analysis of the "
502 printIndentedMatrix(matrix);
503 printNullSpace(matrix);
505 cerr <<
"** Computing h-space vectors" << endl;
509 cout <<
"matrix not generic." << endl;
513 cerr <<
"** Computing MLFBs" << endl;
517 cerr <<
"** Computing thin planes" << endl;
518 vector<TriPlane> thinPlanes;
521 cerr <<
"** Computing double triangle planes and associated structures" << endl;
522 vector<Plane> planes;
525 size_t paraMlfbCount = 0;
526 for (
size_t mlfb = 0; mlfb < mlfbs.size(); ++mlfb) {
527 if (mlfbs[mlfb].index == 0)
531 cerr <<
"** Producing output" << endl;
534 cout <<
"A neighbor has a zero entry.\n";
536 cout <<
"No neighbor has a zero entry.\n";
540 cout <<
"There are " << lat.
getNeighborCount() <<
" neighbors excluding zero.\n";
541 cout <<
"There are " << mlfbs.size() <<
" MLFBs.\n";
542 cout <<
"There are " << paraMlfbCount <<
" parallelogram MLFBs.\n";
543 cout <<
"There are " << planes.size()
544 <<
" distinct double triangle planes.\n";
545 cout <<
"The sum of MLFB indexes is " << indexSum <<
".\n";
547 CHECK(indexSum == 6 || indexSum == -6);
549 printMinDotDegreeMlfb(mlfbs);
553 const vector<Neighbor>& nonSums = lat.
getNonSums();
554 cout <<
"The " << nonSums.size() <<
" non-sum neighbors are:";
555 for (
size_t i = 0; i < nonSums.size(); ++i)
556 cout <<
' ' << nonSums[i].
getName();
559 printThinPlanes(thinPlanes);
561 for (
size_t plane = 0; plane < planes.size(); ++plane) {
562 cout <<
"\n\n*** Plane " << (plane + 1)
563 <<
" of " << planes.size() <<
"\n\n";
564 printPlane(mlfbs, planes[plane], lat);
572 printInteriorNeighborGraph(lat, mlfbs, planes);
573 printScarfGraph(mlfbs);
574 printMathematica3D(mlfbs, lat);
void print(FILE *out, const ColumnPrinter &pr)
void checkFlatSeq(const vector< SeqPos > &flatSeq, const GrobLat &lat, const Plane &plane)
void checkGraphOnPlane(const Plane &plane, const vector< Mlfb > &mlfbs)
void checkPlanes(const vector< TriPlane > &thinPlanes, const vector< Plane > &dtPlanes)
void checkMlfbs(const vector< Mlfb > &mlfbs, const GrobLat &lat)
const char * getEdgePos(size_t index)
void computePivotSeqs(vector< vector< SeqPos > > &seqs, const Mlfb &pivot, const Plane &plane)
Starting at pivot (which must be a pivot), follow the three non-flat sequences starting at pivot.
void checkSeqs(const vector< vector< SeqPos > > &left, const vector< vector< SeqPos > > &right, const Plane &plane, const vector< Mlfb > &mlfbs)
void computeSeqs(vector< vector< SeqPos > > &left, vector< vector< SeqPos > > &right, const vector< Mlfb > &mlfbs, const Plane &plane)
char getPlaceCode(NeighborPlace place)
void computeMlfbs(vector< Mlfb > &mlfbs, const GrobLat &lat)
void checkGraph(const vector< Mlfb > &mlfbs)
void checkMiddle(const Plane &plane, const vector< Mlfb > &mlfbs)
mpq_class getIndexSum(const vector< Mlfb > &mlfbs)
void checkDoubleTriangle(const Plane &plane, const vector< Mlfb > &mlfbs)
void computePlanes(vector< Plane > &planes, const GrobLat &lat, vector< Mlfb > &mlfbs)
void checkDoubleTrianglePlanes(const vector< Plane > &planes, const GrobLat &lat, const vector< Mlfb > &mlfbs)
void getThinPlanes(vector< TriPlane > &planes, const GrobLat &lat)
void checkNonSums(const GrobLat &lat)
void checkPlane(const Plane &plane, const vector< Mlfb > &mlfbs)
void checkPlaneTri(const GrobLat &lat, const vector< Mlfb > &mlfbs, const vector< const Mlfb * > &pivots, const Plane &plane)
void checkPivotSeqs(vector< vector< SeqPos > > &pivotSeqs, const Plane &plane, const vector< Mlfb > &mlfbs, const vector< SeqPos > &flatSeq)
Perform checks where pivotSeqs are the 3 non-flat sequences on one side.
void nullSpace(Matrix &basis, const Matrix &matParam)
Sets the columns of basis to a basis of the null space of mat.
void copyRow(Matrix &target, size_t targetRow, const Matrix &source, size_t sourceRow)
Copies row sourceRow from source to row targetRow of target.
void transpose(Matrix &trans, const Matrix &mat)
Sets trans to the transpose of mat.
const char * getName() const
BoolParameter _printActions
virtual void obtainParameters(vector< Parameter * > ¶meters)
void print(ostream &out) const
void setPrefix(const string &prefix)
The intention of this class is to describe the different kinds of mathematical structures that Frobby...
A lattice with associated Grobner basis/neighbors.
Neighbor getNeighbor(size_t row) const
const vector< Neighbor > & getNonSums() const
bool hasZeroEntryY() const
Neighbor getSum(Neighbor a, Neighbor b) const
size_t getNeighborCount() const
bool isInterior(Neighbor a, Neighbor b) const
bool isPointFreeBody(Neighbor a, Neighbor b) const
Returns true if the smallest body containing zero, a and b has no neighbor in its interior.
A facade for input and output of mathematical objects.
void readSatBinomIdeal(Scanner &in, SatBinomConsumer &consumer)
Read a saturated binomial ideal from in and feed it to consumer.
void autoDetectInputFormat(Scanner &in)
If using the input format, this must be called before validating the ideals, since the auto detect fo...
const string & getInputFormat() const
void validateFormats() const
static const char * staticGetName()
virtual void obtainParameters(vector< Parameter * > ¶meters)
virtual bool displayAction() const
This action isn't done yet, so it should not be displayed by the help action.
size_t getColCount() const
size_t getRowCount() const
const vector< mpz_class > & getRhs() const
Neighbor getPoint(size_t offset) const
vector< size_t > edgeHitsFacet
Neighbor getHitsNeighbor(size_t indexParam) const
const Mlfb * getEdge(size_t indexParam) const
bool hasPoint(Neighbor n) const
size_t getPointCount() const
const mpq_class & getH(size_t i) const
const mpq_class & getY(size_t i) const
void obtainParameters(vector< Parameter * > ¶meters)
NeighborPlace getPlace(Neighbor neighbor) const
vector< const Mlfb * > pivots
size_t getTypeCount(size_t type) const
size_t getMaxType() const
bool inPlane(Neighbor neighbor) const
size_t getType(const Mlfb &mlfb) const
Represents a saturated binomial ideal.
void getMatrix(Matrix &matrix) const
This class offers an input interface which is more convenient and for some purposes more efficient th...
const vector< const Mlfb * > & getBSideMlfbs() const
const vector< const Mlfb * > & getASideMlfbs() const
const vector< Neighbor > & getNeighborsOnBoundary() const
const vector< Neighbor > & getNeighborsInInterior() const