source: git/kernel/gfan.cc @ 94aed9

spielwiese
Last change on this file since 94aed9 was 94aed9, checked in by Martin Monerjan, 15 years ago
Implemented codim2 check Workaround for problems with intPointMatrix in flip git-svn-id: file:///usr/local/Singular/svn/trunk@11979 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 65.4 KB
Line 
1/*
2Compute the Groebner fan of an ideal
3$Author: monerjan $
4$Date: 2009-07-15 09:49:09 $
5$Header: /exports/cvsroot-2/cvsroot/kernel/gfan.cc,v 1.77 2009-07-15 09:49:09 monerjan Exp $
6$Id: gfan.cc,v 1.77 2009-07-15 09:49:09 monerjan Exp $
7*/
8
9#include "mod2.h"
10
11#ifdef HAVE_GFAN
12
13#include "kstd1.h"
14#include "kutil.h"
15#include "intvec.h"
16#include "polys.h"
17#include "ideals.h"
18#include "kmatrix.h"
19#include "fast_maps.h"  //Mapping of ideals
20#include "maps.h"
21#include "ring.h"
22#include "prCopy.h"
23#include <iostream>
24#include <bitset>
25#include <fstream>      //read-write cones to files
26#include <gmp.h>
27#include <string>
28#include <sstream>
29//#include <gmpxx.h>
30
31/*DO NOT REMOVE THIS*/
32#ifndef GMPRATIONAL
33#define GMPRATIONAL
34#endif
35
36//Hacks for different working places
37#define ITWM
38
39#ifdef UNI
40#include "/users/urmel/alggeom/monerjan/cddlib/include/setoper.h" //Support for cddlib. Dirty hack
41#include "/users/urmel/alggeom/monerjan/cddlib/include/cdd.h"
42#endif
43
44#ifdef HOME
45#include "/home/momo/studium/diplomarbeit/cddlib/include/setoper.h"
46#include "/home/momo/studium/diplomarbeit/cddlib/include/cdd.h"
47#endif
48
49#ifdef ITWM
50#include "/u/slg/monerjan/cddlib/include/setoper.h"
51#include "/u/slg/monerjan/cddlib/include/cdd.h"
52#include "/u/slg/monerjan/cddlib/include/cddmp.h"
53#endif
54
55#ifndef gfan_DEBUG
56#define gfan_DEBUG
57#endif
58
59//#include gcone.h
60using namespace std;
61
62/**
63*\brief Class facet
64*       Implements the facet structure as a linked list
65*
66*/
67class facet
68{
69        private:
70                /** \brief Inner normal of the facet, describing it uniquely up to isomorphism */
71                intvec *fNormal;
72               
73                /** \brief An interior point of the facet*/
74                intvec *interiorPoint;
75               
76                /** \brief Universal Cone Number
77                * The number of the cone the facet belongs to, Set in getConeNormals()
78                */
79                int UCN;
80               
81                /** \brief The codim of the facet
82                */
83                int codim;
84               
85                /** \brief The Groebner basis on the other side of a shared facet
86                 *
87                 * In order not to have to compute the flipped GB twice we store the basis we already get
88                 * when identifying search facets. Thus in the next step of the reverse search we can
89                 * just copy the old cone and update the facet and the gcBasis.
90                 * facet::flibGB is set via facet::setFlipGB() and printed via facet::printFlipGB
91                 */
92                ideal flipGB;           //The Groebner Basis on the other side, computed via gcone::flip               
93                       
94        public: 
95                /**
96                */     
97                bool isFlippable;       //**flippable facet? */
98                bool isIncoming;        //Is the facet incoming or outgoing in the reverse search?
99                facet *next;            //Pointer to next facet
100                facet *prev;            //Pointer to predecessor. Needed for the SearchList in noRevS
101                facet *codim2Ptr;       //Pointer to (codim-2)-facet. Bit of recursion here ;-)
102                int numCodim2Facets;    //#of (codim-2)-facets of this facet. Set in getCodim2Normals()
103                ring flipRing;          //the ring on the other side of the facet
104                                               
105                /** The default constructor. Do I need a constructor of type facet(intvec)? */
106                facet()                 
107                {
108                        // Pointer to next facet.  */
109                        /* Defaults to NULL. This way there is no need to check explicitly */
110                        this->fNormal=NULL;
111                        this->interiorPoint=NULL;               
112                        this->UCN=0;
113                        this->codim2Ptr=NULL;
114                        this->codim=1;          //default for (codim-1)-facets
115                        this->numCodim2Facets=0;
116                        this->flipGB=NULL;
117                        this->isIncoming=FALSE;
118                        this->next=NULL;
119                        this->prev=NULL;               
120                        this->flipRing=NULL;
121                        this->isFlippable=FALSE;
122                }
123               
124                /** \brief Constructor for facets of codim >= 2
125                */
126                facet(int const &n)
127                {
128                        this->fNormal=NULL;
129                        this->interiorPoint=NULL;                       
130                        this->UCN=0;
131                        this->codim2Ptr=NULL;
132                        if(n>1)
133                        {
134                                this->codim=n;
135                        }//NOTE Handle exception here!                 
136                        this->numCodim2Facets=0;
137                        this->flipGB=NULL;
138                        this->isIncoming=FALSE;
139                        this->next=NULL;
140                        this->prev=NULL;
141                        this->flipRing=NULL;
142                        this->isFlippable=FALSE;
143                }
144               
145                /** The default destructor */
146                ~facet(){;}
147               
148                /** \brief Comparison of facets*/
149                bool areEqual(facet &f, facet &g)
150                {
151                        bool res = TRUE;
152                        intvec *fNormal = new intvec(pVariables);
153                        intvec *gNormal = new intvec(pVariables);
154                        fNormal = f.getFacetNormal();
155                        gNormal = g.getFacetNormal();
156                        if((fNormal == gNormal))//||(gcone::isParallel(fNormal,gNormal)))
157                        {
158                                if(f.numCodim2Facets==g.numCodim2Facets)
159                                {
160                                        facet *f2Act;
161                                        facet *g2Act;
162                                        f2Act = f.codim2Ptr;
163                                        g2Act = g.codim2Ptr;
164                                        intvec *f2N = new intvec(pVariables);
165                                        intvec *g2N = new intvec(pVariables);
166                                        while(f2Act->next!=NULL && g2Act->next!=NULL)
167                                        {
168                                                for(int ii=0;ii<f2N->length();ii++)
169                                                {
170                                                        if(f2Act->getFacetNormal() != g2Act->getFacetNormal())
171                                                        {
172                                                                res=FALSE;                                                             
173                                                        }
174                                                        if (res==FALSE)
175                                                                break;
176                                                }
177                                                if(res==FALSE)
178                                                        break;
179                                               
180                                                f2Act = f2Act->next;
181                                                g2Act = g2Act->next;
182                                        }//while
183                                }//if           
184                        }//if
185                        else
186                        {
187                                res = FALSE;
188                        }
189                        return res;
190                }
191               
192                /** Stores the facet normal \param intvec*/
193                void setFacetNormal(intvec *iv)
194                {
195                        this->fNormal = ivCopy(iv);                     
196                }
197               
198                /** Hopefully returns the facet normal */
199                intvec *getFacetNormal()
200                {                               
201                        return this->fNormal;
202                }
203               
204                /** Method to print the facet normal*/
205                void printNormal()
206                {
207                        fNormal->show();
208                }
209               
210                /** Store the flipped GB*/
211                void setFlipGB(ideal I)
212                {
213                        this->flipGB=idCopy(I);
214                }
215               
216                /** Return the flipped GB*/
217                ideal getFlipGB()
218                {
219                        return this->flipGB;
220                }
221               
222                /** Print the flipped GB*/
223                void printFlipGB()
224                {
225                        idShow(this->flipGB);
226                }
227               
228                /** Set the UCN */
229                void setUCN(int n)
230                {
231                        this->UCN=n;
232                }
233               
234                /** \brief Get the UCN
235                * Returns the UCN iff this != NULL, else -1
236                */
237                int getUCN()
238                {
239                        if(this!=NULL)
240                                return this->UCN;
241                        else
242                                return -1;
243                }
244               
245                /** Store an interior point of the facet */
246                void setInteriorPoint(intvec *iv)
247                {
248                        this->interiorPoint = ivCopy(iv);
249                }
250               
251                intvec *getInteriorPoint()
252                {
253                        return this->interiorPoint;
254                }       
255               
256                /** \brief Debugging function
257                * prints the facet normal an all (codim-2)-facets that belong to it
258                */
259                void fDebugPrint()
260                {                       
261                        facet *codim2Act;                       
262                        codim2Act = this->codim2Ptr;
263                        intvec *fNormal;
264                        fNormal = this->getFacetNormal();
265                        intvec *f2Normal;
266                        cout << "=======================" << endl;
267                        cout << "Facet normal = (";
268                        for(int ii=0;ii<pVariables;ii++)
269                        {
270                                cout << (*fNormal)[ii] << ",";
271                        }
272                        if(this->isFlippable==TRUE)
273                                cout << ")" << endl;
274                        else
275                                cout << ")*" << endl;   //This case should never happen in SLA!
276                        cout << "-----------------------" << endl;
277                        cout << "Codim2 facets:" << endl;
278                        while(codim2Act!=NULL)
279                        {
280                                f2Normal = codim2Act->getFacetNormal();
281                                cout << "(";
282                                for(int jj=0;jj<pVariables;jj++)
283                                {
284                                        cout << (*f2Normal)[jj] << ",";
285                                }
286                                cout << ")" << endl;
287                                codim2Act = codim2Act->next;
288                        }
289                        cout << "=======================" << endl;
290                }
291               
292                /*bool isFlippable(intvec &load)
293                {
294                        bool res=TRUE;                 
295                        int jj;
296                        for (int jj = 0; jj<load.length(); jj++)
297                        {
298                                intvec *ivCanonical = new intvec(load.length());
299                                (*ivCanonical)[jj]=1;                           
300                                if (ivMult(&load,ivCanonical)<0)
301                                {
302                                        res=FALSE;
303                                        break;
304                                }
305                        }
306                        return res;
307                       
308                        /*while (dotProduct(load,ivCanonical)>=0)
309                        {
310                                if (jj!=this->numVars)
311                                {
312                                        intvec *ivCanonical = new intvec(this->numVars);
313                                        (*ivCanonical)[jj]=1;                   
314                                        res=TRUE;
315                                        jj += 1;
316                                }
317                        }
318                        if (jj==this->numVars)
319                        {                       
320                                delete ivCanonical;
321                                return FALSE;
322                        }
323                        else
324                        {
325                                delete ivCanonical;
326                                return TRUE;
327                }*/                                             
328                //}//bool isFlippable(facet &f)
329               
330               
331                friend class gcone;     //Bad style
332};
333
334/**
335*\brief Implements the cone structure
336*
337* A cone is represented by a linked list of facet normals
338* @see facet
339*/
340/*class gcone
341finally this should become s.th. like gconelib.{h,cc} to provide an API
342*/
343class gcone
344{
345        private:               
346                ring rootRing;          //good to know this -> generic walk
347                ideal inputIdeal;       //the original
348                ring baseRing;          //the basering of the cone             
349                /* TODO in order to save memory use pointers to rootRing and inputIdeal instead */
350                intvec *ivIntPt;        //an interior point of the cone
351                int UCN;                //unique number of the cone
352                static int counter;
353               
354        public: 
355                /** \brief Pointer to the first facet */
356                facet *facetPtr;        //Will hold the adress of the first facet; set by gcone::getConeNormals
357               
358                /** # of variables in the ring */
359                int numVars;            //#of variables in the ring
360               
361                /** # of facets of the cone
362                * This value is set by gcone::getConeNormals
363                */
364                int numFacets;          //#of facets of the cone
365               
366                /**
367                * At least as a workaround we store the irredundant facets of a matrix here.
368                * Otherwise, since we throw away non-flippable facets, facets2Matrix will not
369                * yield all the necessary information
370                */
371                dd_MatrixPtr ddFacets;  //Matrix to store irredundant facets of the cone
372               
373                /** Contains the Groebner basis of the cone. Is set by gcone::getGB(ideal I)*/
374                ideal gcBasis;          //GB of the cone, set by gcone::getGB();
375                gcone *next;            //Pointer to *previous* cone in search tree     
376               
377                /** \brief Default constructor.
378                *
379                * Initialises this->next=NULL and this->facetPtr=NULL
380                */
381                gcone()
382                {
383                        this->next=NULL;
384                        this->facetPtr=NULL;    //maybe this->facetPtr = new facet();                   
385                        this->baseRing=currRing;
386                        this->counter++;
387                        this->UCN=this->counter;                       
388                        this->numFacets=0;
389                        this->ivIntPt=NULL;
390                }
391               
392                /** \brief Constructor with ring and ideal
393                *
394                * This constructor takes the root ring and the root ideal as parameters and stores
395                * them in the private members gcone::rootRing and gcone::inputIdeal
396                * Since knowledge of the root ring is only needed when using reverse search,
397                * this constructor is not needed when using the "second" method
398                */
399                gcone(ring r, ideal I)
400                {
401                        this->next=NULL;
402                        this->facetPtr=NULL;                   
403                        this->rootRing=r;
404                        this->inputIdeal=I;
405                        this->baseRing=currRing;
406                        this->counter++;
407                        this->UCN=this->counter;                       
408                        this->numFacets=0;
409                        this->ivIntPt=NULL;
410                }
411               
412                /** \brief Copy constructor
413                *
414                * Copies a cone, sets this->gcBasis to the flipped GB
415                * Call this only after a successful call to gcone::flip which sets facet::flipGB
416                */             
417                gcone(const gcone& gc, const facet &f)
418                {
419                        this->next=NULL;
420                        this->numVars=gc.numVars;                                               
421                        this->counter++;
422                        this->UCN=this->counter;                       
423                        this->facetPtr=NULL;
424                        this->gcBasis=idCopy(f.flipGB);
425                        this->inputIdeal=idCopy(this->gcBasis);
426                        this->baseRing=rCopy(f.flipRing);
427                        this->numFacets=0;
428                        this->ivIntPt=NULL;
429                        //rComplete(this->baseRing);
430                        //rChangeCurrRing(this->baseRing);
431                }
432               
433                /** \brief Default destructor
434                */
435                ~gcone()
436                {
437                        //NOTE SAVE THE FACET STRUCTURE!!!
438                }                       
439               
440                /** \brief Set the interior point of a cone */
441                void setIntPoint(intvec *iv)
442                {
443                        this->ivIntPt=ivCopy(iv);
444                }
445               
446                /** \brief Return the interior point */
447                intvec *getIntPoint()
448                {
449                        return this->ivIntPt;
450                }
451               
452                /** \brief Print the interior point */
453                void showIntPoint()
454                {
455                        ivIntPt->show();
456                }
457               
458                /** \brief Print facets
459                * This is mainly for debugging purposes. Usually called from within gdb
460                */
461                void showFacets(short codim=1)
462                {
463                        facet *f;
464                        switch(codim)
465                        {
466                                case 1:
467                                        f = this->facetPtr;
468                                        break;
469                                case 2:
470                                        f = this->facetPtr->codim2Ptr;
471                                        break;
472                        }                       
473                       
474                        intvec *iv;                     
475                        while(f!=NULL)
476                        {
477                                iv = f->getFacetNormal();
478                                cout << "(";
479                                iv->show(1,0);                         
480                                if(f->isFlippable==FALSE)
481                                        cout << ")* ";
482                                else
483                                        cout << ") ";
484                                f=f->next;
485                        }
486                        cout << endl;
487                }
488               
489                /** For debugging purposes only */
490                void showSLA(facet &f)
491                {
492                        facet *fAct;
493                        fAct = &f;
494                        facet *codim2Act;
495                        codim2Act = fAct->codim2Ptr;
496                        intvec *fNormal;// = new intvec(this->numVars);
497                        intvec *f2Normal;
498                        cout << endl;
499                        while(fAct!=NULL)
500                        {
501                                fNormal=fAct->getFacetNormal();
502                                cout << "(";
503                                fNormal->show(1,0);
504                                cout << ") ";
505                                codim2Act = fAct->codim2Ptr;
506                                cout << " Codim2: ";
507                                while(codim2Act!=NULL)
508                                {
509                                        f2Normal = codim2Act->getFacetNormal();
510                                        cout << "(";
511                                        f2Normal->show(1,0);
512                                        cout << ") ";
513                                        codim2Act = codim2Act->next;
514                                }
515                                cout << "UCN = " << fAct->getUCN() << endl;                             
516                                fAct = fAct->next;
517                        }
518                }
519               
520                /** \brief Set gcone::numFacets */
521                void setNumFacets()
522                {
523                }
524               
525                /** \brief Get gcone::numFacets */
526                int getNumFacets()
527                {
528                        return this->numFacets;
529                }
530               
531                int getUCN()
532                {
533                        return this->UCN;
534                }
535               
536                /** \brief Compute the normals of the cone
537                *
538                * This method computes a representation of the cone in terms of facet normals. It takes an ideal
539                * as its input. Redundancies are automatically removed using cddlib's dd_MatrixCanonicalize.
540                * Other methods for redundancy checkings might be implemented later. See Anders' diss p.44.
541                * Note that in order to use cddlib a 0-th column has to be added to the matrix since cddlib expects
542                * each row to represent an inequality of type const+x1+...+xn <= 0. While computing the normals we come across
543                * the set \f$ \partial\mathcal{G} \f$ which we might store for later use. C.f p71 of journal
544                * As a result of this procedure the pointer facetPtr points to the first facet of the cone.
545                *
546                * Optionally, if the parameter bool compIntPoint is set to TRUE the method will also compute
547                * an interior point of the cone.
548                */
549                void getConeNormals(ideal const &I, bool compIntPoint=FALSE)
550                {
551#ifdef gfan_DEBUG
552                        std::cout << "*** Computing Inequalities... ***" << std::endl;
553#endif         
554                        //All variables go here - except ineq matrix and *v, see below
555                        int lengthGB=IDELEMS(I);        // # of polys in the groebner basis
556                        int pCompCount;                 // # of terms in a poly
557                        poly aktpoly;
558                        int numvar = pVariables;        // # of variables in a polynomial (or ring?)
559                        int leadexp[numvar];            // dirty hack of exp.vects
560                        int aktexp[numvar];
561                        int cols,rows;                  // will contain the dimensions of the ineq matrix - deprecated by
562                        dd_rowrange ddrows;
563                        dd_colrange ddcols;
564                        dd_rowset ddredrows;            // # of redundant rows in ddineq
565                        dd_rowset ddlinset;             // the opposite
566                        dd_rowindex ddnewpos;             // all to make dd_Canonicalize happy
567                        dd_NumberType ddnumb=dd_Integer; //Number type
568                        dd_ErrorType dderr=dd_NoError;  //
569                        // End of var declaration
570#ifdef gfan_DEBUG
571//                      cout << "The Groebner basis has " << lengthGB << " elements" << endl;
572//                      cout << "The current ring has " << numvar << " variables" << endl;
573#endif
574                        cols = numvar;
575               
576                        //Compute the # inequalities i.e. rows of the matrix
577                        rows=0; //Initialization
578                        for (int ii=0;ii<IDELEMS(I);ii++)
579                        {
580                                aktpoly=(poly)I->m[ii];
581                                rows=rows+pLength(aktpoly)-1;
582                        }
583#ifdef gfan_DEBUG
584//                      cout << "rows=" << rows << endl;
585//                      cout << "Will create a " << rows << " x " << cols << " matrix to store inequalities" << endl;
586#endif
587                        dd_rowrange aktmatrixrow=0;     // needed to store the diffs of the expvects in the rows of ddineq
588                        dd_set_global_constants();
589                        ddrows=rows;
590                        ddcols=cols;
591                        dd_MatrixPtr ddineq;            //Matrix to store the inequalities                     
592                        ddineq=dd_CreateMatrix(ddrows,ddcols+1); //The first col has to be 0 since cddlib checks for additive consts there
593               
594                        // We loop through each g\in GB and compute the resulting inequalities
595                        for (int i=0; i<IDELEMS(I); i++)
596                        {
597                                aktpoly=(poly)I->m[i];          //get aktpoly as i-th component of I
598                                pCompCount=pLength(aktpoly);    //How many terms does aktpoly consist of?
599#ifdef gfan_DEBUG
600//                              cout << "Poly No. " << i << " has " << pCompCount << " components" << endl;
601#endif
602               
603                                int *v=(int *)omAlloc((numvar+1)*sizeof(int));
604                                pGetExpV(aktpoly,v);    //find the exp.vect in v[1],...,v[n], use pNext(p)
605                               
606                                //Store leadexp for aktpoly
607                                for (int kk=0;kk<numvar;kk++)
608                                {
609                                        leadexp[kk]=v[kk+1];
610                                        //Since we need to know the difference of leadexp with the other expvects we do nothing here
611                                        //but compute the diff below
612                                }
613               
614                               
615                                while (pNext(aktpoly)!=NULL) //move to next term until NULL
616                                {
617                                        aktpoly=pNext(aktpoly);
618                                        pSetm(aktpoly);         //doesn't seem to help anything
619                                        pGetExpV(aktpoly,v);
620                                        for (int kk=0;kk<numvar;kk++)
621                                        {
622                                                aktexp[kk]=v[kk+1];
623                                                //ineq[aktmatrixrow][kk]=leadexp[kk]-aktexp[kk];        //dito
624                                                dd_set_si(ddineq->matrix[(dd_rowrange)aktmatrixrow][kk+1],leadexp[kk]-aktexp[kk]); //because of the 1st col being const 0
625                                        }
626                                        aktmatrixrow=aktmatrixrow+1;
627                                }//while
628               
629                        } //for
630               
631                        //Maybe add another row to contain the constraints of the standard simplex?
632
633#ifdef gfan_DEBUG
634                        cout << "The inequality matrix is" << endl;
635                        dd_WriteMatrix(stdout, ddineq);
636#endif
637
638                        // The inequalities are now stored in ddineq
639                        // Next we check for superflous rows
640                        ddredrows = dd_RedundantRows(ddineq, &dderr);
641                        if (dderr!=dd_NoError)                  // did an error occur?
642                        {
643                                dd_WriteErrorMessages(stderr,dderr);    //if so tell us
644                        } else
645                        {
646                                cout << "Redundant rows: ";
647                                set_fwrite(stdout, ddredrows);          //otherwise print the redundant rows
648                        }//if dd_Error
649               
650                        //Remove reduntant rows here!
651                        dd_MatrixCanonicalize(&ddineq, &ddlinset, &ddredrows, &ddnewpos, &dderr);
652                        ddrows = ddineq->rowsize;       //Size of the matrix with redundancies removed
653                        ddcols = ddineq->colsize;
654                       
655                        //ddCreateMatrix(ddrows,ddcols+1);
656                        ddFacets = dd_CopyMatrix(ddineq);
657#ifdef gfan_DEBUG
658//                      cout << "Having removed redundancies, the normals now read:" << endl;
659//                      dd_WriteMatrix(stdout,ddineq);
660//                      cout << "Rows = " << ddrows << endl;
661//                      cout << "Cols = " << ddcols << endl;
662#endif
663                       
664                        /*Write the normals into class facet*/
665#ifdef gfan_DEBUG
666//                      cout << "Creating list of normals" << endl;
667#endif
668                        /*The pointer *fRoot should be the return value of this function*/
669                        //facet *fRoot = new facet();   //instantiate new facet
670                        //fRoot->setUCN(this->getUCN());
671                        //this->facetPtr = fRoot;               //set variable facetPtr of class gcone to first facet
672                        facet *fAct;                    //pointer to active facet
673                        //fAct = fRoot;                 //Seems to do the trick. fRoot and fAct have to point to the same adress!
674                        //std::cout << "fRoot = " << fRoot << ", fAct = " << fAct << endl;
675                        int numNonFlip=0;
676                        for (int kk = 0; kk<ddrows; kk++)
677                        {
678                                intvec *load = new intvec(this->numVars);       //intvec to store a single facet normal that will then be stored via setFacetNormal
679                                for (int jj = 1; jj <ddcols; jj++)
680                                {
681                                        double foo;
682                                        foo = mpq_get_d(ddineq->matrix[kk][jj]);
683#ifdef gfan_DEBUG
684//                                      std::cout << "fAct is " << foo << " at " << fAct << std::endl;
685#endif
686                                        (*load)[jj-1] = (int)foo;               //store typecasted entry at pos jj-1 of load           
687                                }//for (int jj = 1; jj <ddcols; jj++)
688                               
689                                /*Quick'n'dirty hack for flippability*/ 
690                                bool isFlip=FALSE;
691                                                               
692                                for (int jj = 0; jj<load->length(); jj++)
693                                {
694                                        intvec *ivCanonical = new intvec(load->length());
695                                        (*ivCanonical)[jj]=1;
696//                                      cout << "dotProd=" << dotProduct(*load,*ivCanonical) << endl;
697                                        if (dotProduct(*load,*ivCanonical)<0)   
698                                        //if (ivMult(load,ivCanonical)<0)
699                                        {
700                                                isFlip=TRUE;
701                                                break;  //URGHS
702                                        }
703                                }       
704                                if (isFlip==FALSE)
705                                {
706                                        this->numFacets++;
707                                        numNonFlip++;
708                                        if(this->numFacets==1)
709                                        {
710                                                facet *fRoot = new facet();
711                                                this->facetPtr = fRoot;
712                                                fAct = fRoot;
713                                               
714                                        }
715                                        else
716                                        {
717                                                fAct->next = new facet();
718                                                fAct = fAct->next;
719                                        }
720                                        fAct->isFlippable=FALSE;
721                                        fAct->setFacetNormal(load);
722                                        fAct->setUCN(this->getUCN());
723#ifdef gfan_DEBUG
724                                        cout << "Marking facet (";
725                                        load->show(1,0);
726                                        cout << ") as non flippable" << endl;                           
727#endif
728                                }
729                                else
730                                {       /*Now load should be full and we can call setFacetNormal*/                                     
731                                        this->numFacets++;
732                                        if(this->numFacets==1)
733                                        {
734                                                facet *fRoot = new facet();
735                                                this->facetPtr = fRoot;
736                                                fAct = fRoot;
737                                        }
738                                        else
739                                        {
740                                                fAct->next = new facet();
741                                                fAct = fAct->next;
742                                        }
743                                        fAct->isFlippable=TRUE;
744                                        fAct->setFacetNormal(load);
745                                        fAct->setUCN(this->getUCN());                                   
746                                }//if (isFlippable==FALSE)
747                                //delete load;                         
748                        }//for (int kk = 0; kk<ddrows; kk++)
749                       
750                        //In cases like I=<x-1,y-1> there are only non-flippable facets...
751                        if(numNonFlip==this->numFacets)
752                        {                                       
753                                cerr << "Only non-flippable facets. Terminating..." << endl;
754                        }
755                       
756                        /*
757                        Now we should have a linked list containing the facet normals of those facets that are
758                        -irredundant
759                        -flipable
760                        Adressing is done via *facetPtr
761                        */
762                       
763                        if (compIntPoint==TRUE)
764                        {
765                                intvec *iv = new intvec(this->numVars);
766                                interiorPoint(ddineq, *iv);     //NOTE ddineq contains non-flippable facets
767                                this->setIntPoint(iv);  //stores the interior point in gcone::ivIntPt
768                                //delete iv;
769                        }
770                       
771                        //Compute the number of facets
772                        // wrong because ddineq->rowsize contains only irredundant facets. There can still be
773                        // non-flippable ones!
774                        //this->numFacets=ddineq->rowsize;
775                       
776                        //Clean up but don't delete the return value! (Whatever it will turn out to be)                 
777                        //dd_FreeMatrix(ddineq);
778                        //set_free(ddredrows);
779                        //free(ddnewpos);
780                        //set_free(ddlinset);
781                        //NOTE Commented out. Solved the bug that after facet2Matrix there were facets lost
782                        //THIS SUCKS
783                        //dd_free_global_constants();
784
785                }//method getConeNormals(ideal I)       
786               
787                /** \brief Compute the (codim-2)-facets of a given cone
788                * This method is used during noRevS
789                */
790                void getCodim2Normals(gcone const &gc)
791                {
792                        //this->facetPtr->codim2Ptr = new facet(2);     //instantiate a (codim-2)-facet
793                        facet *fAct;
794                        fAct = this->facetPtr;         
795                        facet *codim2Act;
796                        //codim2Act = this->facetPtr->codim2Ptr;
797                       
798                        dd_set_global_constants();
799                       
800                        dd_MatrixPtr ddineq,P,ddakt;
801                        dd_rowset impl_linset, redset;
802                        dd_ErrorType err;
803                        dd_rowindex newpos;             
804
805                        //ddineq = facets2Matrix(gc);   //get a matrix representation of the cone
806                        ddineq = dd_CopyMatrix(gc.ddFacets);
807                               
808                        /*Now set appropriate linearity*/
809                        dd_PolyhedraPtr ddpolyh;
810                        for (int ii=0; ii<this->numFacets; ii++)                       
811                        {                               
812                                ddakt = dd_CopyMatrix(ddineq);
813                                ddakt->representation=dd_Inequality;
814                                set_addelem(ddakt->linset,ii+1);                               
815                                dd_MatrixCanonicalize(&ddakt, &impl_linset, &redset, &newpos, &err);                   
816                                       
817#ifdef gfan_DEBUG
818//                              cout << "Codim2 matrix"<<endl;
819//                              dd_WriteMatrix(stdout,ddakt);
820#endif
821                                ddpolyh=dd_DDMatrix2Poly(ddakt, &err);
822                                P=dd_CopyGenerators(ddpolyh);                           
823#ifdef gfan_DEBUG
824//                              cout << "Codim2 facet:" << endl;
825//                                      dd_WriteMatrix(stdout,P);
826//                              cout << endl;
827#endif
828                                       
829                                /* We loop through each row of P
830                                * normalize it by making all entries integer ones
831                                * and add the resulting vector to the int matrix facet::codim2Facets
832                                */
833                                for (int jj=1;jj<=P->rowsize;jj++)
834                                {                                       
835                                        fAct->numCodim2Facets++;
836                                        if(fAct->numCodim2Facets==1)                                   
837                                        {                                               
838                                                fAct->codim2Ptr = new facet(2);                                         
839                                                codim2Act = fAct->codim2Ptr;
840                                        }
841                                        else
842                                        {
843                                                codim2Act->next = new facet(2);
844                                                codim2Act = codim2Act->next;
845                                        }
846                                        intvec *n = new intvec(this->numVars);
847                                        makeInt(P,jj,*n);
848                                        codim2Act->setFacetNormal(n);
849                                        delete n;                                       
850                                }               
851                                /*We check whether the facet spanned by the codim-2 facets
852                                * intersects with the positive orthant. Otherwise we define this
853                                * facet to be non-flippable
854                                */
855                                intvec *iv_intPoint = new intvec(this->numVars);
856                                dd_MatrixPtr shiftMatrix;
857                                dd_MatrixPtr intPointMatrix;
858                                shiftMatrix = dd_CreateMatrix(this->numVars,this->numVars+1);
859                                for(int kk=0;kk<this->numVars;kk++)
860                                {
861                                        dd_set_si(shiftMatrix->matrix[kk][0],1);
862                                        dd_set_si(shiftMatrix->matrix[kk][kk+1],1);
863                                }
864                                intPointMatrix=dd_MatrixAppend(ddakt,shiftMatrix);
865                                //dd_WriteMatrix(stdout,intPointMatrix);
866                                interiorPoint(intPointMatrix,*iv_intPoint);
867                                for(int ll=0;ll<this->numVars;ll++)
868                                {
869                                        if( (*iv_intPoint)[ll] < 0 )
870                                        {
871                                                fAct->isFlippable=FALSE;
872                                                break;
873                                        }
874                                }
875                                /*End of check*/                                       
876                                fAct = fAct->next;     
877                                dd_FreeMatrix(ddakt);
878                                dd_FreePolyhedra(ddpolyh);
879                        }//while
880                }
881               
882                /** \brief Compute the Groebner Basis on the other side of a shared facet
883                *
884                * Implements algorithm 4.3.2 from Anders' thesis.
885                * As shown there it is not necessary to compute an interior point. The knowledge of the facet normal
886                * suffices. A term \f$ x^\gamma \f$ of \f$ g \f$ is in \f$  in_\omega(g) \f$ iff \f$ \gamma - leadexp(g)\f$
887                * is parallel to \f$ leadexp(g) \f$
888                * Parallelity is checked using basic linear algebra. See gcone::isParallel.
889                * Other possibilities include computing the rank of the matrix consisting of the vectors in question and
890                * computing an interior point of the facet and taking all terms having the same weight with respect
891                * to this interior point.
892                *\param ideal, facet
893                * Input: a marked,reduced Groebner basis and a facet
894                */
895                void flip(ideal gb, facet *f)           //Compute "the other side"
896                {                       
897                        intvec *fNormal = new intvec(this->numVars);    //facet normal, check for parallelity                   
898                        fNormal = f->getFacetNormal();  //read this->fNormal;
899#ifdef gfan_DEBUG
900                        //std::cout << "===" << std::endl;
901                        std::cout << "running gcone::flip" << std::endl;
902                        std::cout << "flipping" << endl;
903                        for(int ii=0;ii<IDELEMS(gb);ii++)
904                        {
905                                pWrite((poly)gb->m[ii]);
906                        }
907                        cout << "over facet ";
908                        fNormal->show(1,0);
909                        std::cout << std::endl;
910#endif                         
911                        /*1st step: Compute the initial ideal*/
912                        poly initialFormElement[IDELEMS(gb)];   //array of #polys in GB to store initial form
913                        ideal initialForm=idInit(IDELEMS(gb),this->gcBasis->rank);
914                        poly aktpoly;
915                        intvec *check = new intvec(this->numVars);      //array to store the difference of LE and v
916                       
917                        for (int ii=0;ii<IDELEMS(gb);ii++)
918                        {
919                                aktpoly = (poly)gb->m[ii];                                                             
920                                int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
921                                int *leadExpV=(int *)omAlloc((this->numVars+1)*sizeof(int));
922                                pGetExpV(aktpoly,leadExpV);     //find the leading exponent in leadExpV[1],...,leadExpV[n], use pNext(p)
923                                initialFormElement[ii]=pHead(aktpoly);
924                               
925                                while(pNext(aktpoly)!=NULL)     /*loop trough terms and check for parallelity*/
926                                {
927                                        aktpoly=pNext(aktpoly); //next term
928                                        pSetm(aktpoly);
929                                        pGetExpV(aktpoly,v);           
930                                        /* Convert (int)v into (intvec)check */                 
931                                        for (int jj=0;jj<this->numVars;jj++)
932                                        {
933                                                //cout << "v["<<jj+1<<"]="<<v[jj+1]<<endl;
934                                                //cout << "leadExpV["<<jj+1<<"]="<<leadExpV[jj+1]<<endl;
935                                                (*check)[jj]=v[jj+1]-leadExpV[jj+1];
936                                        }
937#ifdef gfan_DEBUG
938//                                      cout << "check=";                       
939//                                      check->show();
940//                                      cout << endl;
941#endif
942                                        //TODO why not *check, *fNormal????
943                                        if (isParallel(*check,*fNormal)) //pass *check when
944                                        {
945//                                              cout << "Parallel vector found, adding to initialFormElement" << endl;                 
946                                                initialFormElement[ii] = pAdd(pCopy(initialFormElement[ii]),(poly)pHead(aktpoly));
947                                        }                                               
948                                }//while
949#ifdef gfan_DEBUG
950//                              cout << "Initial Form=";                               
951//                              pWrite(initialFormElement[ii]);
952//                              cout << "---" << endl;
953#endif
954                                /*Now initialFormElement must be added to (ideal)initialForm */
955                                initialForm->m[ii]=initialFormElement[ii];
956                        }//for                 
957#ifdef gfan_DEBUG
958/*                      cout << "Initial ideal is: " << endl;
959                        idShow(initialForm);
960                        //f->printFlipGB();*/
961//                      cout << "===" << endl;
962#endif
963                        //delete check;
964                       
965                        /*2nd step: lift initial ideal to a GB of the neighbouring cone using minus alpha as weight*/
966                        /*Substep 2.1
967                        compute $G_{-\alpha}(in_v(I))
968                        see journal p. 66
969                        NOTE Check for different rings. Prolly it will not always be necessary to add a weight, if the
970                        srcRing already has a weighted ordering
971                        */
972                        ring srcRing=currRing;
973                        ring tmpRing;
974                       
975                        if( (srcRing->order[0]!=ringorder_a))
976                        {
977                                tmpRing=rCopyAndAddWeight(srcRing,ivNeg(fNormal));
978                        }
979                        else
980                        {
981                                tmpRing=rCopy0(srcRing);
982                                int length=fNormal->length();
983                                int *A=(int *)omAlloc0(length*sizeof(int));
984                                for(int jj=0;jj<length;jj++)
985                                {
986                                        A[jj]=-(*fNormal)[jj];
987                                }
988                                omFree(tmpRing->wvhdl[0]);
989                                tmpRing->wvhdl[0]=(int*)A;
990                                tmpRing->block1[0]=length;
991                                rComplete(tmpRing);     
992                        }
993                        rChangeCurrRing(tmpRing);
994                       
995                        //rWrite(currRing); cout << endl;
996                       
997                        ideal ina;                     
998                        ina=idrCopyR(initialForm,srcRing);                     
999#ifdef gfan_DEBUG
1000//                      cout << "ina=";
1001//                      idShow(ina); cout << endl;
1002#endif
1003                        ideal H;
1004                        //H=kStd(ina,NULL,isHomog,NULL);        //we know it is homogeneous
1005                        H=kStd(ina,NULL,testHomog,NULL);
1006                        idSkipZeroes(H);
1007#ifdef gfan_DEBUG
1008//                      cout << "H="; idShow(H); cout << endl;
1009#endif
1010                        /*Substep 2.2
1011                        do the lifting and mark according to H
1012                        */
1013                        rChangeCurrRing(srcRing);
1014                        ideal srcRing_H;
1015                        ideal srcRing_HH;                       
1016                        srcRing_H=idrCopyR(H,tmpRing);
1017#ifdef gfan_DEBUG
1018//                      cout << "srcRing_H = ";
1019//                      idShow(srcRing_H); cout << endl;
1020#endif
1021                        srcRing_HH=ffG(srcRing_H,this->gcBasis);               
1022#ifdef gfan_DEBUG
1023//                      cout << "srcRing_HH = ";
1024//                      idShow(srcRing_HH); cout << endl;
1025#endif
1026                        /*Substep 2.2.1
1027                        Mark according to G_-\alpha
1028                        Here we have a minimal basis srcRing_HH. In order to turn this basis into a reduced basis
1029                        we have to compute an interior point of C(srcRing_HH). For this we need to know the cone
1030                        represented by srcRing_HH MARKED ACCORDING TO G_{-\alpha}
1031                        Thus we check whether the leading monomials of srcRing_HH and srcRing_H coincide. If not we
1032                        compute the difference accordingly
1033                        */
1034                        dd_set_global_constants();
1035                        bool markingsAreCorrect=FALSE;
1036                        dd_MatrixPtr intPointMatrix;
1037                        int iPMatrixRows=0;
1038                        dd_rowrange aktrow=0;                   
1039                        for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
1040                        {
1041                                poly aktpoly=(poly)srcRing_HH->m[ii];
1042                                iPMatrixRows = iPMatrixRows+pLength(aktpoly)-1;
1043                        }
1044                        /* additionally one row for the standard-simplex and another for a row that becomes 0 during
1045                        construction of the differences
1046                        */
1047                        intPointMatrix = dd_CreateMatrix(iPMatrixRows+10,this->numVars+1);
1048                        intPointMatrix->numbtype=dd_Integer;    //NOTE: DO NOT REMOVE OR CHANGE TO dd_Rational
1049                       
1050                        for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
1051                        {
1052                                markingsAreCorrect=FALSE;       //crucial to initialise here
1053                                poly aktpoly=srcRing_HH->m[ii];
1054                                /*Comparison of leading monomials is done via exponent vectors*/
1055                                for (int jj=0;jj<IDELEMS(H);jj++)
1056                                {
1057                                        int *src_ExpV = (int *)omAlloc((this->numVars+1)*sizeof(int));
1058                                        int *dst_ExpV = (int *)omAlloc((this->numVars+1)*sizeof(int));
1059                                        pGetExpV(aktpoly,src_ExpV);
1060                                        rChangeCurrRing(tmpRing);       //this ring change is crucial!
1061                                        pGetExpV(pCopy(H->m[ii]),dst_ExpV);
1062                                        rChangeCurrRing(srcRing);
1063                                        bool expVAreEqual=TRUE;
1064                                        for (int kk=1;kk<=this->numVars;kk++)
1065                                        {
1066#ifdef gfan_DEBUG
1067                                                //cout << src_ExpV[kk] << "," << dst_ExpV[kk] << endl;
1068#endif
1069                                                if (src_ExpV[kk]!=dst_ExpV[kk])
1070                                                {
1071                                                        expVAreEqual=FALSE;
1072                                                }
1073                                        }                                       
1074                                        //if (*src_ExpV == *dst_ExpV)
1075                                        if (expVAreEqual==TRUE)
1076                                        {
1077                                                markingsAreCorrect=TRUE; //everything is fine
1078#ifdef gfan_DEBUG
1079//                                              cout << "correct markings" << endl;
1080#endif
1081                                        }//if (pHead(aktpoly)==pHead(H->m[jj])
1082                                        delete src_ExpV;
1083                                        delete dst_ExpV;
1084                                }//for (int jj=0;jj<IDELEMS(H);jj++)
1085                               
1086                                int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
1087                                int *leadExpV=(int *)omAlloc((this->numVars+1)*sizeof(int));
1088                                if (markingsAreCorrect==TRUE)
1089                                {
1090                                        pGetExpV(aktpoly,leadExpV);
1091                                }
1092                                else
1093                                {
1094                                        rChangeCurrRing(tmpRing);
1095                                        pGetExpV(pHead(H->m[ii]),leadExpV); //We use H->m[ii] as leading monomial
1096                                        rChangeCurrRing(srcRing);
1097                                }
1098                                /*compute differences of the expvects*/                         
1099                                while (pNext(aktpoly)!=NULL)
1100                                {
1101                                        /*The following if-else-block makes sure the first term (i.e. the wrongly marked term)
1102                                        is not omitted when computing the differences*/
1103                                        if(markingsAreCorrect==TRUE)
1104                                        {
1105                                                aktpoly=pNext(aktpoly);
1106                                                pGetExpV(aktpoly,v);
1107                                        }
1108                                        else
1109                                        {
1110                                                pGetExpV(pHead(aktpoly),v);
1111                                                markingsAreCorrect=TRUE;
1112                                        }
1113
1114                                        for (int jj=0;jj<this->numVars;jj++)
1115                                        {                               
1116                                                /*Store into ddMatrix*/                                                         
1117                                                dd_set_si(intPointMatrix->matrix[aktrow][jj+1],leadExpV[jj+1]-v[jj+1]);
1118                                        }
1119                                        aktrow +=1;
1120                                }
1121                                delete v;
1122                                delete leadExpV;
1123                        }//for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
1124                        /*Now we add the constraint for the standard simplex*/
1125                        /*NOTE:Might actually work without the standard simplex*/
1126                        dd_set_si(intPointMatrix->matrix[aktrow][0],-1);
1127                        for (int jj=1;jj<=this->numVars;jj++)
1128                        {
1129                                dd_set_si(intPointMatrix->matrix[aktrow][jj],1);
1130                        }
1131#ifdef gfan_DEBUG
1132//                      dd_WriteMatrix(stdout,intPointMatrix);
1133#endif
1134                        intvec *iv_weight = new intvec(this->numVars);
1135                        interiorPoint(intPointMatrix, *iv_weight);      //iv_weight now contains the interior point
1136                        dd_FreeMatrix(intPointMatrix);
1137                        dd_free_global_constants();
1138                       
1139                        /*Step 3
1140                        turn the minimal basis into a reduced one
1141                        */
1142                        //ring dstRing=rCopyAndAddWeight(tmpRing,iv_weight);   
1143                       
1144                        // NOTE May assume that at this point srcRing already has 3 blocks of orderins, starting with a
1145                        // Thus:
1146                        //ring dstRing=rCopyAndChangeWeight(srcRing,iv_weight);
1147                        //cout << "PLING" << endl;
1148                        /*ring dstRing=rCopy0(srcRing);
1149                        for (int ii=0;ii<this->numVars;ii++)
1150                        {                               
1151                                dstRing->wvhdl[0][ii]=(*iv_weight)[ii];                         
1152                        }*/
1153                        ring dstRing=rCopy0(tmpRing);
1154                        int length=iv_weight->length();
1155                        int *A=(int *)omAlloc0(length*sizeof(int));
1156                        for(int jj=0;jj<length;jj++)
1157                        {
1158                                A[jj]=(*iv_weight)[jj];
1159                        }
1160                        dstRing->wvhdl[0]=(int*)A;
1161                        rComplete(dstRing);                                     
1162                        rChangeCurrRing(dstRing);
1163                       
1164#ifdef gfan_DEBUG
1165                        rWrite(dstRing); cout << endl;
1166#endif
1167                        ideal dstRing_I;                       
1168                        dstRing_I=idrCopyR(srcRing_HH,srcRing);                 
1169                        //validOpts<1>=TRUE;
1170#ifdef gfan_DEBUG
1171                        //idShow(dstRing_I);
1172#endif                 
1173                        BITSET save=test;
1174                        test|=Sy_bit(OPT_REDSB);
1175                        test|=Sy_bit(6);        //OPT_DEBUG
1176                        ideal tmpI;
1177                        tmpI = idrCopyR(this->inputIdeal,this->baseRing);                               
1178                        dstRing_I=kStd(tmpI,NULL,testHomog,NULL);                                       
1179                        kInterRed(dstRing_I);
1180                        idSkipZeroes(dstRing_I);
1181                        test=save;
1182                        /*End of step 3 - reduction*/
1183                       
1184                        f->setFlipGB(dstRing_I);//store the flipped GB
1185                        f->flipRing=rCopy(dstRing);     //store the ring on the other side
1186#ifdef gfan_DEBUG
1187                        cout << "Flipped GB is: " << endl;
1188                        f->printFlipGB();
1189#endif                 
1190                        rChangeCurrRing(srcRing);       //return to the ring we started the computation of flipGB in
1191                }//void flip(ideal gb, facet *f)
1192                               
1193                /** \brief Compute the remainder of a polynomial by a given ideal
1194                *
1195                * Compute \f$ f^{\mathcal{G}} \f$
1196                * Algorithm is taken from Cox, Little, O'Shea, IVA 2nd Ed. p 62
1197                * However, since we are only interested in the remainder, there is no need to
1198                * compute the factors \f$ a_i \f$
1199                */
1200                //NOTE: Should be replaced by kNF or kNF2
1201                poly restOfDiv(poly const &f, ideal const &I)
1202                {
1203//                      cout << "Entering restOfDiv" << endl;
1204                        poly p=f;
1205                        //pWrite(p);                   
1206                        poly r=NULL;    //The zero polynomial
1207                        int ii;
1208                        bool divOccured;
1209                       
1210                        while (p!=NULL)
1211                        {
1212                                ii=1;
1213                                divOccured=FALSE;
1214                               
1215                                while( (ii<=IDELEMS(I) && (divOccured==FALSE) ))
1216                                {                                       
1217                                        if (pDivisibleBy(I->m[ii-1],p)) //does LM(I->m[ii]) divide LM(p) ?
1218                                        {                                               
1219                                                poly step1,step2,step3;
1220                                                //cout << "dividing "; pWrite(pHead(p));cout << "by ";pWrite(pHead(I->m[ii-1])); cout << endl;
1221                                                step1 = pDivideM(pHead(p),pHead(I->m[ii-1]));
1222                                                //cout << "LT(p)/LT(f_i)="; pWrite(step1); cout << endl;                               
1223                                                step2 = ppMult_qq(step1, I->m[ii-1]);                                           
1224                                                step3 = pSub(pCopy(p), step2);
1225                                                //p=pSub(p,pMult( pDivide(pHead(p),pHead(I->m[ii])), I->m[ii]));                       
1226                                                //pSetm(p);
1227                                                pSort(step3); //must be here, otherwise strange behaviour with many +o+o+o+o+ terms
1228                                                p=step3;
1229                                                //pWrite(p);                                           
1230                                                divOccured=TRUE;
1231                                        }
1232                                        else
1233                                        {
1234                                                ii += 1;
1235                                        }//if (pLmDivisibleBy(I->m[ii],p,currRing))
1236                                }//while( (ii<IDELEMS(I) && (divOccured==FALSE) ))
1237                                if (divOccured==FALSE)
1238                                {
1239                                        //cout << "TICK 5" << endl;
1240                                        r=pAdd(pCopy(r),pHead(p));
1241                                        pSetm(r);
1242                                        pSort(r);
1243                                        //cout << "r="; pWrite(r); cout << endl;
1244                                       
1245                                        if (pLength(p)!=1)
1246                                        {
1247                                                p=pSub(pCopy(p),pHead(p));      //Here it may occur that p=0 instead of p=NULL
1248                                        }
1249                                        else
1250                                        {
1251                                                p=NULL; //Hack to correct this situation                                               
1252                                        }                                       
1253                                        //cout << "p="; pWrite(p);
1254                                }//if (divOccured==FALSE)
1255                        }//while (p!=0)
1256                        return r;
1257                }//poly restOfDiv(poly const &f, ideal const &I)
1258               
1259                /** \brief Compute \f$ f-f^{\mathcal{G}} \f$
1260                */
1261                //NOTE: use kNF or kNF2 instead of restOfDivision
1262                ideal ffG(ideal const &H, ideal const &G)
1263                {
1264//                      cout << "Entering ffG" << endl;
1265                        int size=IDELEMS(H);
1266                        ideal res=idInit(size,1);
1267                        poly temp1, temp2, temp3;       //polys to temporarily store values for pSub
1268                        for (int ii=0;ii<size;ii++)
1269                        {
1270                                res->m[ii]=restOfDiv(H->m[ii],G);
1271                                //res->m[ii]=kNF(H->m[ii],G);
1272                                temp1=H->m[ii];
1273                                temp2=res->m[ii];                               
1274                                temp3=pSub(temp1, temp2);
1275                                res->m[ii]=temp3;
1276                                //res->m[ii]=pSub(temp1,temp2); //buggy
1277                                //pSort(res->m[ii]);
1278                                //pSetm(res->m[ii]);
1279                                //cout << "res->m["<<ii<<"]=";pWrite(res->m[ii]);                                               
1280                        }                       
1281                        return res;
1282                }
1283               
1284                /** \brief Compute a Groebner Basis
1285                *
1286                * Computes the Groebner basis and stores the result in gcone::gcBasis
1287                *\param ideal
1288                *\return void
1289                */
1290                void getGB(ideal const &inputIdeal)
1291                {
1292                        ideal gb;
1293                        gb=kStd(inputIdeal,NULL,testHomog,NULL);
1294                        idSkipZeroes(gb);
1295                        this->gcBasis=gb;       //write the GB into gcBasis
1296                }//void getGB
1297               
1298                /** \brief The Generic Groebner Walk due to FJLT
1299                * Needed for computing the search facet
1300                */
1301                ideal GenGrbWlk(ideal, ideal)
1302                {
1303                }//GGW
1304               
1305                /** \brief Compute the negative of a given intvec
1306                */             
1307                intvec *ivNeg(const intvec *iv)
1308                {
1309                        intvec *res = new intvec(iv->length());
1310                        res=ivCopy(iv);
1311                        *res *= (int)-1;
1312                        //for(int ii=0;ii<this->numVars;ii++)
1313                        //{                     
1314                                //(res)[ii] = (*res[ii])*(int)(-1);
1315                        //}
1316                        res->show(1,0);                 
1317                        return res;
1318                }
1319
1320
1321                /** \brief Compute the dot product of two intvecs
1322                *
1323                */
1324                int dotProduct(intvec const &iva, intvec const &ivb)                           
1325                {
1326                        //intvec iva=a;
1327                        //intvec ivb=b;
1328                        int res=0;
1329                        for (int i=0;i<this->numVars;i++)
1330                        {
1331                                res = res+(iva[i]*ivb[i]);
1332                        }
1333                        return res;
1334                }//int dotProduct
1335
1336                /** \brief Check whether two intvecs are parallel
1337                *
1338                * \f$ \alpha\parallel\beta\Leftrightarrow\langle\alpha,\beta\rangle^2=\langle\alpha,\alpha\rangle\langle\beta,\beta\rangle \f$
1339                */
1340                bool isParallel(intvec const &a, intvec const &b)
1341                {                       
1342                        int lhs,rhs;
1343                        lhs=dotProduct(a,b)*dotProduct(a,b);
1344                        rhs=dotProduct(a,a)*dotProduct(b,b);
1345                        //cout << "LHS="<<lhs<<", RHS="<<rhs<<endl;
1346                        if (lhs==rhs)
1347                        {
1348                                return TRUE;
1349                        }
1350                        else
1351                        {
1352                                return FALSE;
1353                        }
1354                }//bool isParallel
1355               
1356                /** \brief Compute an interior point of a given cone
1357                * Result will be written into intvec iv.
1358                * Any rational point is automatically converted into an integer.
1359                */
1360                void interiorPoint(dd_MatrixPtr const &M, intvec &iv) //no const &M here since we want to remove redundant rows
1361                {
1362                        dd_LPPtr lp,lpInt;
1363                        dd_ErrorType err=dd_NoError;
1364                        dd_LPSolverType solver=dd_DualSimplex;
1365                        dd_LPSolutionPtr lpSol=NULL;
1366                        dd_rowset ddlinset,ddredrows;   //needed for dd_FindRelativeInterior
1367                        dd_rowindex ddnewpos;
1368                        dd_NumberType numb;     
1369                        //M->representation=dd_Inequality;
1370                        //M->objective-dd_LPMin;  //Not sure whether this is needed
1371                       
1372                        //NOTE: Make this n-dimensional!
1373                        //dd_set_si(M->rowvec[0],1);dd_set_si(M->rowvec[1],1);dd_set_si(M->rowvec[2],1);
1374                                                                       
1375                        //dd_MatrixCanonicalize(&M, &ddlinset, &ddredrows, &ddnewpos, &err);
1376                        //if (err!=dd_NoError){cout << "Error during dd_MatrixCanonicalize" << endl;}
1377                        //cout << "Tick 2" << endl;
1378                        //dd_WriteMatrix(stdout,M);
1379                       
1380                        lp=dd_Matrix2LP(M, &err);
1381                        if (err!=dd_NoError){cout << "Error during dd_Matrix2LP in gcone::interiorPoint" << endl;}                     
1382                        if (lp==NULL){cout << "LP is NULL" << endl;}
1383#ifdef gfan_DEBUG
1384//                      dd_WriteLP(stdout,lp);
1385#endif 
1386                                       
1387                        lpInt=dd_MakeLPforInteriorFinding(lp);
1388                        if (err!=dd_NoError){cout << "Error during dd_MakeLPForInteriorFinding in gcone::interiorPoint" << endl;}
1389#ifdef gfan_DEBUG
1390//                      dd_WriteLP(stdout,lpInt);
1391#endif                 
1392
1393                        dd_FindRelativeInterior(M,&ddlinset,&ddredrows,&lpSol,&err);
1394                        if (err!=dd_NoError)
1395                        {
1396                                cout << "Error during dd_FindRelativeInterior in gcone::interiorPoint" << endl;
1397                                dd_WriteErrorMessages(stdout, err);
1398                        }
1399                       
1400                        //dd_LPSolve(lpInt,solver,&err);        //This will not result in a point from the relative interior
1401                        if (err!=dd_NoError){cout << "Error during dd_LPSolve" << endl;}
1402                                                                       
1403                        //lpSol=dd_CopyLPSolution(lpInt);
1404                        if (err!=dd_NoError){cout << "Error during dd_CopyLPSolution" << endl;}                 
1405#ifdef gfan_DEBUG
1406                        cout << "Interior point: ";
1407                        for (int ii=1; ii<(lpSol->d)-1;ii++)
1408                        {
1409                                dd_WriteNumber(stdout,lpSol->sol[ii]);
1410                        }
1411                        cout << endl;
1412#endif
1413                       
1414                        //NOTE The following strongly resembles parts of makeInt.
1415                        //Maybe merge sometimes
1416                        mpz_t kgV; mpz_init(kgV);
1417                        mpz_set_str(kgV,"1",10);
1418                        mpz_t den; mpz_init(den);
1419                        mpz_t tmp; mpz_init(tmp);
1420                        mpq_get_den(tmp,lpSol->sol[1]);
1421                        for (int ii=1;ii<(lpSol->d)-1;ii++)
1422                        {
1423                                mpq_get_den(den,lpSol->sol[ii+1]);
1424                                mpz_lcm(kgV,tmp,den);
1425                                mpz_set(tmp, kgV);
1426                        }
1427                        mpq_t qkgV;
1428                        mpq_init(qkgV);
1429                        mpq_set_z(qkgV,kgV);
1430                        for (int ii=1;ii<(lpSol->d)-1;ii++)
1431                        {
1432                                mpq_t product;
1433                                mpq_init(product);
1434                                mpq_mul(product,qkgV,lpSol->sol[ii]);
1435                                iv[ii-1]=(int)mpz_get_d(mpq_numref(product));
1436                                mpq_clear(product);
1437                        }
1438#ifdef gfan_DEBUG
1439//                      iv.show();
1440//                      cout << endl;
1441#endif
1442                        mpq_clear(qkgV);
1443                        mpz_clear(tmp);
1444                        mpz_clear(den);
1445                        mpz_clear(kgV);                 
1446                       
1447                        dd_FreeLPSolution(lpSol);
1448                        dd_FreeLPData(lpInt);
1449                        dd_FreeLPData(lp);
1450                        set_free(ddlinset);
1451                        set_free(ddredrows);                   
1452                       
1453                }//void interiorPoint(dd_MatrixPtr const &M)
1454               
1455                /** \brief Copy a ring and add a weighted ordering in first place
1456                *
1457                */
1458                ring rCopyAndAddWeight(ring const &r, intvec const *ivw)                               
1459                {
1460                        ring res=rCopy0(r);
1461                        int jj;
1462                       
1463                        omFree(res->order);
1464                        res->order =(int *)omAlloc0(4*sizeof(int));
1465                        omFree(res->block0);
1466                        res->block0=(int *)omAlloc0(4*sizeof(int));
1467                        omFree(res->block1);
1468                        res->block1=(int *)omAlloc0(4*sizeof(int));
1469                        omfree(res->wvhdl);
1470                        res->wvhdl =(int **)omAlloc0(4*sizeof(int**));
1471                       
1472                        res->order[0]=ringorder_a;
1473                        res->block0[0]=1;
1474                        res->block1[0]=res->N;;
1475                        res->order[1]=ringorder_dp;     //basically useless, since that should never be used                   
1476                        res->block0[1]=1;
1477                        res->block1[1]=res->N;;
1478                        res->order[2]=ringorder_C;
1479
1480                        int length=ivw->length();
1481                        int *A=(int *)omAlloc0(length*sizeof(int));
1482                        for (jj=0;jj<length;jj++)
1483                        {                               
1484                                A[jj]=(*ivw)[jj];                               
1485                        }                       
1486                        res->wvhdl[0]=(int *)A;
1487                        res->block1[0]=length;
1488                       
1489                        rComplete(res);
1490                        return res;
1491                }//rCopyAndAdd
1492               
1493                ring rCopyAndChangeWeight(ring const &r, intvec *ivw)
1494                {
1495                        ring res=rCopy0(currRing);
1496                        rComplete(res);
1497                        rSetWeightVec(res,(int64*)ivw);
1498                        //rChangeCurrRing(rnew);
1499                        return res;
1500                }
1501               
1502                /** \brief Checks whether a given facet is a search facet
1503                * Determines whether a given facet of a cone is the search facet of a neighbouring cone
1504                * This is done in the following way:
1505                * We loop through all facets of the cone and find the "smallest" facet, i.e. the unique facet
1506                * that is first crossed during the generic walk.
1507                * We then check whether the fNormal of this facet is parallel to the fNormal of our testfacet.
1508                * If this is the case, then our facet is indeed a search facet and TRUE is retuned.
1509                */
1510                bool isSearchFacet(gcone &gcTmp, facet *testfacet)
1511                {                               
1512                        ring actRing=currRing;
1513                        facet *facetPtr=(facet*)gcTmp.facetPtr;                 
1514                        facet *fMin=new facet(*facetPtr);       //Pointer to the "minimal" facet
1515                        //facet *fMin = new facet(tmpcone.facetPtr);
1516                        //fMin=tmpcone.facetPtr;                //Initialise to first facet of tmpcone
1517                        facet *fAct;    //Ptr to alpha_i
1518                        facet *fCmp;    //Ptr to alpha_j
1519                        fAct = fMin;
1520                        fCmp = fMin->next;                             
1521                       
1522                        rChangeCurrRing(this->rootRing);        //because we compare the monomials in the rootring                     
1523                        poly p=pInit();
1524                        poly q=pInit();
1525                        intvec *alpha_i = new intvec(this->numVars);                   
1526                        intvec *alpha_j = new intvec(this->numVars);
1527                        intvec *sigma = new intvec(this->numVars);
1528                        sigma=gcTmp.getIntPoint();
1529                       
1530                        int *u=(int *)omAlloc((this->numVars+1)*sizeof(int));
1531                        int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
1532                        u[0]=0; v[0]=0;
1533                        int weight1,weight2;
1534                        while(fAct->next->next!=NULL)   //NOTE this is ugly. Can it be done without fCmp?
1535                        {
1536                                /* Get alpha_i and alpha_{i+1} */
1537                                alpha_i=fAct->getFacetNormal();
1538                                alpha_j=fCmp->getFacetNormal();
1539#ifdef gfan_DEBUG
1540                                alpha_i->show(); 
1541                                alpha_j->show();
1542#endif
1543                                /*Compute the dot product of sigma and alpha_{i,j}*/
1544                                weight1=dotProduct(sigma,alpha_i);
1545                                weight2=dotProduct(sigma,alpha_j);
1546#ifdef gfan_DEBUG
1547                                cout << "weight1=" << weight1 << " " << "weight2=" << weight2 << endl;
1548#endif
1549                                /*Adjust alpha_i and alpha_i+1 accordingly*/
1550                                for(int ii=1;ii<=this->numVars;ii++)
1551                                {                                       
1552                                        u[ii]=weight1*(*alpha_i)[ii-1];
1553                                        v[ii]=weight2*(*alpha_j)[ii-1];
1554                                }                               
1555                               
1556                                /*Now p_weight and q_weight need to be compared as exponent vectors*/
1557                                pSetCoeff0(p,nInit(1));
1558                                pSetCoeff0(q,nInit(1));
1559                                pSetExpV(p,u); 
1560                                pSetm(p);                       
1561                                pSetExpV(q,v); 
1562                                pSetm(q);
1563#ifdef gfan_DEBUG                               
1564                                pWrite(p);pWrite(q);
1565#endif 
1566                                /*We want to check whether x^p < x^q
1567                                => want to check for return value 1 */
1568                                if (pLmCmp(p,q)==1)     //i.e. x^q is smaller
1569                                {
1570                                        fMin=fCmp;
1571                                        fAct=fMin;
1572                                        fCmp=fCmp->next;
1573                                }
1574                                else
1575                                {
1576                                        //fAct=fAct->next;
1577                                        if(fCmp->next!=NULL)
1578                                        {
1579                                                fCmp=fCmp->next;
1580                                        }
1581                                        else
1582                                        {
1583                                                fAct=fAct->next;
1584                                        }
1585                                }
1586                                //fAct=fAct->next;
1587                        }//while(fAct.facetPtr->next!=NULL)
1588                        delete alpha_i,alpha_j,sigma;
1589                       
1590                        /*If testfacet was minimal then fMin should still point there */
1591                       
1592                        //if(fMin->getFacetNormal()==ivNeg(testfacet.getFacetNormal()))                 
1593#ifdef gfan_DEBUG
1594                        cout << "Checking for parallelity" << endl <<" fMin is";
1595                        fMin->printNormal();
1596                        cout << "testfacet is ";
1597                        testfacet->printNormal();
1598                        cout << endl;
1599#endif
1600                        if (fMin==gcTmp.facetPtr)                       
1601                        //if(areEqual(fMin->getFacetNormal(),ivNeg(testfacet.getFacetNormal())))
1602                        //if (isParallel(fMin->getFacetNormal(),testfacet->getFacetNormal()))
1603                        {                               
1604                                cout << "Parallel" << endl;
1605                                rChangeCurrRing(actRing);
1606                                //delete alpha_min, test;
1607                                return TRUE;
1608                        }
1609                        else 
1610                        {
1611                                cout << "Not parallel" << endl;
1612                                rChangeCurrRing(actRing);
1613                                //delete alpha_min, test;
1614                                return FALSE;
1615                        }
1616                }//bool isSearchFacet
1617               
1618                /** \brief Check for equality of two intvecs
1619                */
1620                bool areEqual(intvec const &a, intvec const &b)
1621                {
1622                        bool res=TRUE;
1623                        for(int ii=0;ii<this->numVars;ii++)
1624                        {
1625                                if(a[ii]!=b[ii])
1626                                {
1627                                        res=FALSE;
1628                                        break;
1629                                }
1630                        }
1631                        return res;
1632                }
1633               
1634                /** \brief The reverse search algorithm
1635                */
1636                void reverseSearch(gcone *gcAct) //no const possible here since we call gcAct->flip
1637                {
1638                        facet *fAct=new facet();
1639                        fAct = gcAct->facetPtr;                 
1640                       
1641                        while(fAct!=NULL) 
1642                        {
1643                                cout << "======================"<< endl;
1644                                gcAct->flip(gcAct->gcBasis,gcAct->facetPtr);
1645                                gcone *gcTmp = new gcone(*gcAct);
1646                                //idShow(gcTmp->gcBasis);
1647                                gcTmp->getConeNormals(gcTmp->gcBasis, TRUE);
1648#ifdef gfan_DEBUG
1649                                facet *f = new facet();
1650                                f=gcTmp->facetPtr;
1651                                while(f!=NULL)
1652                                {
1653                                        f->printNormal();
1654                                        f=f->next;                                     
1655                                }
1656#endif
1657                                gcTmp->showIntPoint();
1658                                /*recursive part goes gere*/
1659                                if (isSearchFacet(*gcTmp,(facet*)gcAct->facetPtr))
1660                                {
1661                                        gcAct->next=gcTmp;
1662                                        cout << "PING"<< endl;
1663                                        reverseSearch(gcTmp);
1664                                }
1665                                else
1666                                {
1667                                        delete gcTmp;
1668                                        /*NOTE remove fAct from linked list. It's no longer needed*/
1669                                }
1670                                /*recursion ends*/
1671                                fAct = fAct->next;             
1672                        }//while(fAct->next!=NULL)
1673                }//reverseSearch
1674               
1675                /** \brief The new method of Markwig and Jensen
1676                * Compute gcBasis and facets for the arbitrary starting cone. Store \f$(codim-1)\f$-facets as normals.
1677                * In order to represent a facet uniquely compute also the \f$(codim-2)\f$-facets and norm by the gcd of the components.
1678                * Keep a list of facets as a linked list containing an intvec and an integer matrix.
1679                * Since a \f$(codim-1)\f$-facet belongs to exactly two full dimensional cones, we remove a facet from the list as
1680                * soon as we compute this facet again. Comparison of facets is done by...
1681                */
1682                void noRevS(gcone &gcRoot, bool usingIntPoint=FALSE)
1683                {       
1684                        facet *SearchListRoot = new facet(); //The list containing ALL facets we come across
1685                        facet *SearchListAct;
1686                        //SearchListAct = SearchListRoot;
1687                       
1688                        gcone *gcAct;
1689                        gcAct = &gcRoot;
1690                        gcone *gcPtr;   //Pointer to end of linked list of cones
1691                        gcPtr = &gcRoot;
1692                        gcone *gcNext;  //Pointer to next cone to be visited
1693                        gcNext = &gcRoot;
1694                        gcone *gcHead;
1695                        gcHead = &gcRoot;
1696                       
1697                        facet *fAct;
1698                        fAct = gcAct->facetPtr;                 
1699                       
1700                        ring rAct;
1701                        rAct = currRing;
1702                                               
1703                        int UCNcounter=gcAct->getUCN();
1704#ifdef gfan_DEBUG
1705                        cout << "NoRevs" << endl;
1706                        cout << "Facets are:" << endl;
1707                        gcAct->showFacets();
1708#endif                 
1709                       
1710                        gcAct->getCodim2Normals(*gcAct);
1711                               
1712                        //Compute unique representation of codim-2-facets
1713                        gcAct->normalize();
1714                       
1715                        /*Make a copy of the facet list of first cone
1716                        Since the operations getCodim2Normals and normalize affect the facets
1717                        we must not memcpy them before these ops!
1718                        */
1719                        intvec *fNormal;// = new intvec(this->numVars);
1720                        intvec *f2Normal;// = new intvec(this->numVars);
1721                        facet *codim2Act; codim2Act = NULL;                     
1722                        facet *sl2Root; //sl2Root = new facet(2);
1723                        facet *sl2Act;  //sl2Act = sl2Root;
1724                       
1725                        for(int ii=0;ii<this->numFacets;ii++)
1726                        {
1727                                //only copy flippable facets!
1728                                if(fAct->isFlippable==TRUE)
1729                                {
1730                                        fNormal = fAct->getFacetNormal();
1731                                        if(ii==0)
1732                                        {                                               
1733                                                SearchListAct = SearchListRoot;
1734                                                //memcpy(SearchListAct,fAct,sizeof(facet));                                     
1735                                        }
1736                                        else
1737                                        {
1738                                                SearchListAct->next = new facet();
1739                                                SearchListAct = SearchListAct->next;
1740                                                //memcpy(SearchListAct,fAct,sizeof(facet));                             
1741                                        }
1742                                        SearchListAct->setFacetNormal(fNormal);
1743                                        SearchListAct->setUCN(this->getUCN());
1744                                        SearchListAct->numCodim2Facets=fAct->numCodim2Facets;
1745                                        SearchListAct->isFlippable=TRUE;
1746                                        //Copy codim2-facets                           
1747                                        codim2Act=fAct->codim2Ptr;
1748                                        SearchListAct->codim2Ptr = new facet(2);
1749                                        sl2Root = SearchListAct->codim2Ptr;
1750                                        sl2Act = sl2Root;
1751                                        //while(codim2Act!=NULL)
1752                                        for(int jj=0;jj<fAct->numCodim2Facets;jj++)
1753                                        {
1754                                                f2Normal = codim2Act->getFacetNormal();
1755                                                if(jj==0)
1756                                                {                                               
1757                                                        sl2Act = sl2Root;
1758                                                        sl2Act->setFacetNormal(f2Normal);
1759                                                }
1760                                                else
1761                                                {
1762                                                        sl2Act->next = new facet(2);
1763                                                        sl2Act = sl2Act->next;
1764                                                        sl2Act->setFacetNormal(f2Normal);
1765                                                }                                       
1766                                                codim2Act = codim2Act->next;
1767                                        }
1768                                        fAct = fAct->next;
1769                                }//if(fAct->isFlippable==TRUE)
1770                                else {fAct = fAct->next;}
1771                        }                               
1772                       
1773                        SearchListAct = SearchListRoot; //Set to beginning of list
1774                        /*Make SearchList doubly linked*/
1775                        while(SearchListAct!=NULL)
1776                        {
1777                                if(SearchListAct->next!=NULL)
1778                                {
1779                                        SearchListAct->next->prev = SearchListAct;
1780                                        //SearchListAct = SearchListAct->next;
1781                                }
1782                                SearchListAct = SearchListAct->next;
1783                        }
1784                        SearchListAct = SearchListRoot; //Set to beginning of List
1785                       
1786                        fAct = gcAct->facetPtr;                 
1787                        //gcAct->writeConeToFile(*gcAct);
1788                       
1789                        /*End of initialisation*/
1790                        fAct = SearchListAct;
1791                        /*2nd step
1792                        Choose a facet from fListPtr, flip it and forget the previous cone
1793                        We always choose the first facet from fListPtr as facet to be flipped
1794                        */
1795                        while(SearchListAct!=NULL)
1796                        {//NOTE See to it that the cone is only changed after ALL facets have been flipped!                             
1797                                fAct = SearchListAct;
1798                                //while( ( (fAct->next!=NULL) && (fAct->getUCN()==fAct->next->getUCN() ) ) )
1799                                //do
1800                                while(fAct!=NULL)
1801                                {       //Since SLA should only contain flippables there should be no need to check for that
1802                                        gcAct->flip(gcAct->gcBasis,fAct);
1803                                        ring rTmp=rCopy(fAct->flipRing);
1804                                        rComplete(rTmp);
1805                                        rChangeCurrRing(rTmp);
1806                                        gcone *gcTmp = new gcone::gcone(*gcAct,*fAct);
1807                                        gcTmp->getConeNormals(gcTmp->gcBasis, FALSE);
1808                                        gcTmp->getCodim2Normals(*gcTmp);
1809                                        gcTmp->normalize();
1810                                        //gcTmp->writeConeToFile(*gcTmp);
1811                                        /*add facets to SLA here*/
1812                                        SearchListRoot=gcTmp->enqueueNewFacets(*SearchListRoot);
1813                                        if(SearchListRoot!=NULL)
1814                                                gcTmp->showSLA(*SearchListRoot);
1815                                        rChangeCurrRing(gcAct->baseRing);
1816                                        gcPtr->next=gcTmp;
1817                                        gcPtr=gcPtr->next;
1818                                        if(fAct->getUCN() == fAct->next->getUCN())
1819                                        {
1820                                                fAct=fAct->next;
1821                                        }
1822                                        else
1823                                                break;
1824                                }//while( ( (fAct->next!=NULL) && (fAct->getUCN()==fAct->next->getUCN() ) ) );
1825                                //Search for cone with smallest UCN
1826                                gcNext = gcHead;
1827                                while(gcNext!=NULL)
1828                                {
1829                                        if( gcNext->getUCN() == UCNcounter+1 )
1830                                        {
1831                                                gcAct = gcNext;
1832                                                rAct=rCopy(gcAct->baseRing);
1833                                                rComplete(rAct);
1834                                                rChangeCurrRing(rAct);                                         
1835                                                break;                                         
1836                                        }
1837                                        gcNext = gcNext->next;
1838                                }
1839                                UCNcounter++;
1840                                //SearchListAct = SearchListAct->next;
1841                                //SearchListAct = fAct->next;
1842                                SearchListAct = SearchListRoot;
1843                        }
1844                        cout << endl << "Found " << counter << " cones - terminating" << endl;
1845               
1846                        //NOTE Hm, comment in and get a crash for free...
1847                        //dd_free_global_constants();                           
1848                        //gc.writeConeToFile(gc);
1849                       
1850                       
1851                        //fAct = fListPtr;
1852                        //gcone *gcTmp = new gcone(gc); //copy
1853                        //gcTmp->flip(gcTmp->gcBasis,fAct);
1854                        //NOTE: gcTmp may be deleted, gcRoot from main proc should probably not!
1855                       
1856                }//void noRevS(gcone &gc)       
1857               
1858               
1859                /** \brief Make a set of rational vectors into integers
1860                *
1861                * We compute the lcm of the denominators and multiply with this to get integer values.         
1862                * \param dd_MatrixPtr,intvec
1863                */
1864                void makeInt(dd_MatrixPtr const &M, int const line, intvec &n)
1865                {                       
1866                        mpz_t denom[this->numVars];
1867                        for(int ii=0;ii<this->numVars;ii++)
1868                        {
1869                                mpz_init_set_str(denom[ii],"0",10);
1870                        }
1871               
1872                        mpz_t kgV,tmp;
1873                        mpz_init(kgV);
1874                        mpz_init(tmp);
1875                       
1876                        for (int ii=0;ii<(M->colsize)-1;ii++)
1877                        {
1878                                mpz_t z;
1879                                mpz_init(z);
1880                                mpq_get_den(z,M->matrix[line-1][ii+1]);
1881                                mpz_set( denom[ii], z);
1882                                mpz_clear(z);                           
1883                        }
1884                       
1885                        //Check whether denom is all ones, in which case we will divide out the gcd of the nominators
1886//                      mpz_t checksum; mpz_t rop;
1887//                      mpz_init(checksum);
1888//                      mpz_init(rop);
1889//                      bool divideOutGcd=FALSE;
1890//                      for(int ii=0;ii<this->numVars;ii++)
1891//                      {
1892//                              mpz_add(rop, checksum, denom[ii]);
1893//                              mpz_set(checksum, rop);
1894//                      }
1895//                      if( (int)mpz_get_ui(checksum)==this->numVars)
1896//                      {
1897//                              divideOutGcd=TRUE;
1898//                      }
1899                       
1900                        /*Compute lcm of the denominators*/
1901                        mpz_set(tmp,denom[0]);
1902                        for (int ii=0;ii<(M->colsize)-1;ii++)
1903                        {
1904                                mpz_lcm(kgV,tmp,denom[ii]);                             
1905                        }
1906                       
1907                        /*Multiply the nominators by kgV*/
1908                        mpq_t qkgV,res;
1909                        mpq_init(qkgV);
1910                        mpq_set_str(qkgV,"1",10);
1911                        mpq_canonicalize(qkgV);
1912                       
1913                        mpq_init(res);
1914                        mpq_set_str(res,"1",10);
1915                        mpq_canonicalize(res);
1916                       
1917                        mpq_set_num(qkgV,kgV);
1918                       
1919//                      mpq_canonicalize(qkgV);
1920                        for (int ii=0;ii<(M->colsize)-1;ii++)
1921                        {
1922                                mpq_mul(res,qkgV,M->matrix[line-1][ii+1]);
1923                                n[ii]=(int)mpz_get_d(mpq_numref(res));
1924                        }
1925                        //mpz_clear(denom[this->numVars]);
1926                        mpz_clear(kgV);
1927                        mpq_clear(qkgV); mpq_clear(res);                       
1928                       
1929                }
1930                /**
1931                 * For all codim-2-facets we compute the gcd of the components of the facet normal and
1932                 * divide it out. Thus we get a normalized representation of each
1933                 * (codim-2)-facet normal, i.e. a primitive vector
1934                */
1935                void normalize()
1936                {
1937                        int ggT=1;
1938                        facet *fAct;
1939                        facet *codim2Act;
1940                        fAct = this->facetPtr;
1941                        codim2Act = fAct->codim2Ptr;
1942                        intvec *n = new intvec(this->numVars);
1943                       
1944                        //while(codim2Act->next!=NULL)
1945                        while(fAct!=NULL)
1946                        {
1947                                while(codim2Act!=NULL)
1948                                {                               
1949                                        n=codim2Act->getFacetNormal();
1950                                        for(int ii=0;ii<this->numVars;ii++)
1951                                        {
1952                                                ggT = intgcd(ggT,(*n)[ii]);
1953                                        }
1954                                        for(int ii=0;ii<this->numVars;ii++)
1955                                        {
1956                                                (*n)[ii] = ((*n)[ii])/ggT;
1957                                        }
1958                                        codim2Act->setFacetNormal(n);
1959                                        codim2Act = codim2Act->next;                           
1960                                }
1961                                fAct = fAct->next;
1962                        }
1963               
1964                        //delete n;
1965                        /*codim2Act = this->facetPtr->codim2Ptr;        //reset to start of linked list                 
1966                        while(codim2Act!=NULL)
1967                        {                               
1968                                n=codim2Act->getFacetNormal();
1969                                intvec *new_n = new intvec(this->numVars);
1970                                for(int ii=0;ii<this->numVars;ii++)
1971                                {
1972                                        (*new_n)[ii] = (*n)[ii]*ggT;
1973                                }
1974                                codim2Act->setFacetNormal(new_n);
1975                                codim2Act = codim2Act->next;
1976                                //delete n;
1977                                //delete new_n;
1978                        }       */             
1979                }
1980                /**
1981                * Takes ptr to search list root
1982                * Returns a pointer to new first element of Searchlist
1983                */
1984                //void enqueueNewFacets(facet &f)
1985                facet * enqueueNewFacets(facet &f)
1986                {
1987                        facet *slHead;
1988                        slHead = &f;
1989                        facet *slAct;   //called with f=SearchListRoot
1990                        slAct = &f;
1991                        facet *slEnd;   //Pointer to end of SLA
1992                        slEnd = &f;
1993                        facet *slEndStatic;     //marks the end before a new facet is added             
1994                        facet *fAct;
1995                        fAct = this->facetPtr;
1996                        facet *codim2Act;
1997                        codim2Act = this->facetPtr->codim2Ptr;
1998                        facet *sl2Act;
1999                        sl2Act = f.codim2Ptr;
2000                       
2001                        bool doNotAdd=FALSE;
2002                        int ctr=0;      //encountered qualities in SLA
2003                        int notParallelCtr=0;
2004                        int lengthOfSearchList=1;
2005                        while(slEnd->next!=NULL)
2006                        {
2007                                slEnd=slEnd->next;
2008                                lengthOfSearchList++;
2009                        }
2010                        slEndStatic = slEnd;
2011                        /*1st step: compare facetNormals*/
2012                        intvec *fNormal=NULL; //= new intvec(this->numVars);
2013                        intvec *f2Normal=NULL; //= new intvec(this->numVars);
2014                        intvec *slNormal=NULL; //= new intvec(this->numVars);
2015                        intvec *sl2Normal=NULL; //= new intvec(this->numVars);
2016                       
2017                        while(fAct!=NULL)
2018                        {
2019                                if(fAct->isFlippable==TRUE)
2020                                {
2021                                        doNotAdd=TRUE;
2022                                        fNormal=fAct->getFacetNormal();
2023                                        slAct = slHead;
2024                                        notParallelCtr=0;
2025                                        while(slAct!=NULL)
2026                                        {
2027                                                slNormal = slAct->getFacetNormal();
2028#ifdef gfan_DEBUG
2029                                                cout << "Checking facet (";
2030                                                fNormal->show(1,1);
2031                                                cout << ") against (";
2032                                                slNormal->show(1,1);
2033                                                cout << ")" << endl;
2034#endif
2035                                                if(!isParallel(fNormal, slNormal))
2036                                                {
2037                                                        notParallelCtr++;
2038                                                }
2039                                                else
2040                                                {
2041                                                        codim2Act = fAct->codim2Ptr;
2042                                                        ctr=0;
2043                                                        while(codim2Act!=NULL)
2044                                                        {
2045                                                                f2Normal = codim2Act->getFacetNormal();
2046                                                                //sl2Act = f.codim2Ptr;
2047                                                                sl2Act = slAct->codim2Ptr;
2048                                                                while(sl2Act!=NULL)
2049                                                                {
2050                                                                        sl2Normal = sl2Act->getFacetNormal();
2051                                                                        if(areEqual(f2Normal, sl2Normal))
2052                                                                                        ctr++;
2053                                                                        sl2Act = sl2Act->next;
2054                                                                }//while(sl2Act!=NULL)
2055                                                                codim2Act = codim2Act->next;
2056                                                        }//while(codim2Act!=NULL)
2057                                                        if(ctr==fAct->numCodim2Facets)  //facets ARE equal
2058                                                        {
2059#ifdef gfan_DEBUG
2060                                                                cout << "Removing facet (";
2061                                                                slNormal->show(1,0);
2062                                                                cout << ") from SLA:" << endl;
2063                                                                fAct->fDebugPrint();
2064                                                                slAct->fDebugPrint();
2065#endif
2066                                                                if(slAct==slHead)       //We want to delete the first element of SearchList
2067                                                                {
2068                                                                        slHead = slAct->next;
2069                                                                        if(slHead!=NULL)
2070                                                                                slHead->prev = NULL;
2071                                                                        //set a bool flag to mark slAct as to be deleted
2072                                                                }
2073                                                                else if(slAct==slEndStatic)
2074                                                                        {
2075                                                                                if(slEndStatic->next==NULL)
2076                                                                                {
2077                                                                                        slEndStatic = slEndStatic->prev;
2078                                                                                        slEndStatic->next = NULL;
2079                                                                                }
2080                                                                                else    //we already added a facet after slEndStatic
2081                                                                                {
2082                                                                                        slEndStatic->prev->next = slEndStatic->next;
2083                                                                                        slEndStatic = slEndStatic->prev;
2084                                                                                        slEnd = slEndStatic;
2085                                                                                }
2086                                                                        }
2087                                                                else
2088                                                                {
2089                                                                        slAct->prev->next = slAct->next;
2090                                                                }
2091                                                                //update lengthOfSearchList
2092                                                                lengthOfSearchList--;
2093                                                                break;
2094                                                        }//if(ctr==fAct->numCodim2Facets)
2095                                                        else    //facets are NOT equal
2096                                                        {
2097                                                                doNotAdd=FALSE;
2098                                                                break;
2099                                                        }
2100                                                }//if(!isParallel(fNormal, slNormal))
2101                                                slAct = slAct->next;
2102                                                //if slAct was marked as to be deleted, delete it here!
2103                                        }//while(slAct!=NULL)                           
2104                                if( (notParallelCtr==lengthOfSearchList) || (doNotAdd==FALSE) )
2105                                {
2106#ifdef gfan_DEBUG
2107                                        cout << "Adding facet (";
2108                                        fNormal->show(1,0);
2109                                        cout << ") to SLA " << endl;
2110#endif
2111                                        //Add fAct to SLA
2112                                        facet *marker;
2113                                        marker = slEnd;
2114                                        facet *f2Act;
2115                                        f2Act = fAct->codim2Ptr;
2116                                       
2117                                        slEnd->next = new facet();
2118                                        slEnd = slEnd->next;
2119                                        facet *slEndCodim2Root;
2120                                        facet *slEndCodim2Act;
2121                                        slEndCodim2Root = slEnd->codim2Ptr;
2122                                        slEndCodim2Act = slEndCodim2Root;
2123                                                       
2124                                        slEnd->setUCN(this->getUCN());
2125                                        slEnd->isFlippable = TRUE;
2126                                        slEnd->setFacetNormal(fNormal);
2127                                        slEnd->prev = marker;
2128                                        //Copy codim2-facets
2129                                        intvec *f2Normal;// = new intvec(this->numVars);
2130                                        while(f2Act!=NULL)
2131                                        {
2132                                                f2Normal=f2Act->getFacetNormal();
2133                                                if(slEndCodim2Root==NULL)
2134                                                {
2135                                                        slEndCodim2Root = new facet(2);
2136                                                        slEnd->codim2Ptr = slEndCodim2Root;                     
2137                                                        slEndCodim2Root->setFacetNormal(f2Normal);
2138                                                        slEndCodim2Act = slEndCodim2Root;
2139                                                }
2140                                                else                                   
2141                                                {
2142                                                        slEndCodim2Act->next = new facet(2);
2143                                                        slEndCodim2Act = slEndCodim2Act->next;
2144                                                        slEndCodim2Act->setFacetNormal(f2Normal);
2145                                                }
2146                                                f2Act = f2Act->next;
2147                                        }
2148                                        lengthOfSearchList++;
2149                                        //delete f2Normal;
2150                                       
2151                                }
2152                                fAct = fAct->next;
2153                                }
2154                                else
2155                                {
2156                                        fAct = fAct->next;
2157                                }
2158                        }//while(fAct!=NULL)
2159                        return slHead;
2160//                      delete sl2Normal;
2161//                      delete slNormal;
2162//                      delete f2Normal;
2163//                      delete fNormal;
2164                }//addC2N
2165               
2166                /** \brief Compute the gcd of two ints
2167                */
2168                int intgcd(int a, int b)
2169                {
2170                        int r, p=a, q=b;
2171                        if(p < 0)
2172                                p = -p;
2173                        if(q < 0)
2174                                q = -q;
2175                        while(q != 0)
2176                        {
2177                                r = p % q;
2178                                p = q;
2179                                q = r;
2180                        }
2181                        return p;
2182                }               
2183               
2184                /** \brief Construct a dd_MatrixPtr from a cone's list of facets
2185                *
2186                */
2187                dd_MatrixPtr facets2Matrix(gcone const &gc)
2188                {
2189                        facet *fAct;
2190                        fAct = gc.facetPtr;
2191       
2192                        dd_MatrixPtr M;
2193                        dd_rowrange ddrows;
2194                        dd_colrange ddcols;
2195                        ddcols=(this->numVars)+1;
2196                        ddrows=this->numFacets;
2197                        dd_NumberType numb = dd_Integer;
2198                        M=dd_CreateMatrix(ddrows,ddcols);                       
2199                       
2200                        int jj=0;
2201                        //while(fAct->next!=NULL)
2202                        while(fAct!=NULL)
2203                        {
2204                                intvec *comp;
2205                                comp = fAct->getFacetNormal();
2206                                for(int ii=0;ii<this->numVars;ii++)
2207                                {
2208                                        dd_set_si(M->matrix[jj][ii+1],(*comp)[ii]);
2209                                }
2210                                jj++;
2211                                fAct=fAct->next;                               
2212                        }                       
2213                       
2214                        return M;
2215                }
2216               
2217                /** \brief Write information about a cone into a file on disk
2218                *
2219                * This methods writes the information needed for the "second" method into a file.
2220                * The file's is divided in sections containing information on
2221                * 1) the ring
2222                * 2) the cone's Groebner Basis
2223                * 3) the cone's facets
2224                * Each line contains exactly one date
2225                * Each section starts with its name in CAPITALS
2226                */
2227                void writeConeToFile(gcone const &gc, bool usingIntPoints=FALSE)
2228                {
2229                        int UCN=gc.UCN;
2230                        stringstream ss;
2231                        ss << UCN;
2232                        string UCNstr = ss.str();               
2233                       
2234                        char prefix[]="/tmp/cone";
2235                        char *UCNstring;
2236                        strcpy(UCNstring,UCNstr.c_str());
2237                        char suffix[]=".sg";
2238                        char *filename=strcat(prefix,UCNstring);
2239                        strcat(filename,suffix);
2240                                       
2241                        ofstream gcOutputFile(filename);
2242                        facet *fAct = new facet(); //NOTE Why new?
2243                        fAct = gc.facetPtr;                     
2244                       
2245                        char *ringString = rString(currRing);
2246                       
2247                        if (!gcOutputFile)
2248                        {
2249                                cout << "Error opening file for writing in writeConeToFile" << endl;
2250                        }
2251                        else
2252                        {       gcOutputFile << "UCN" << endl;
2253                                gcOutputFile << this->UCN << endl;
2254                                gcOutputFile << "RING" << endl; 
2255                                gcOutputFile << ringString << endl;                     
2256                                //Write this->gcBasis into file
2257                                gcOutputFile << "GCBASIS" << endl;                             
2258                                for (int ii=0;ii<IDELEMS(gc.gcBasis);ii++)
2259                                {                                       
2260                                        gcOutputFile << p_String((poly)gc.gcBasis->m[ii],gc.baseRing) << endl;
2261                                }                               
2262                               
2263                                gcOutputFile << "FACETS" << endl;                                                               
2264                                //while(fAct->next!=NULL)
2265                                while(fAct!=NULL)
2266                                {       
2267                                        intvec *iv = new intvec(gc.numVars);
2268                                        iv=fAct->getFacetNormal();
2269                                        for (int ii=0;ii<iv->length();ii++)
2270                                        {
2271                                                if (ii<iv->length()-1)
2272                                                {
2273                                                        gcOutputFile << (*iv)[ii] << ",";
2274                                                }
2275                                                else
2276                                                {
2277                                                        gcOutputFile << (*iv)[ii] << endl;
2278                                                }
2279                                        }
2280                                        fAct=fAct->next;
2281                                        //delete iv; iv=NULL;
2282                                }                               
2283                               
2284                                gcOutputFile.close();
2285                                //delete fAct; fAct=NULL;
2286                        }
2287                       
2288                }//writeConeToFile(gcone const &gc)
2289               
2290                /** \brief Reads a cone from a file identified by its number
2291                */
2292                void readConeFromFile(int gcNum)
2293                {
2294                }
2295               
2296        friend class facet;
2297};//class gcone
2298
2299int gcone::counter=0;
2300
2301ideal gfan(ideal inputIdeal)
2302{
2303        int numvar = pVariables; 
2304       
2305        enum searchMethod {
2306                reverseSearch,
2307                noRevS
2308        };
2309       
2310        searchMethod method;
2311        method = noRevS;
2312//      method = reverseSearch;
2313       
2314#ifdef gfan_DEBUG
2315        cout << "Now in subroutine gfan" << endl;
2316#endif
2317        ring inputRing=currRing;        // The ring the user entered
2318        ring rootRing;                  // The ring associated to the target ordering
2319        ideal res;     
2320        facet *fRoot;
2321       
2322        if (method==reverseSearch)
2323        {
2324       
2325        /* Construct a new ring which will serve as our root*/
2326        rootRing=rCopy0(currRing);
2327        rootRing->order[0]=ringorder_lp;
2328       
2329        rComplete(rootRing);
2330        rChangeCurrRing(rootRing);
2331       
2332        /* Fetch the inputIdeal into our rootRing */
2333        map theMap=(map)idMaxIdeal(1);  //evil hack!
2334        theMap->preimage=NULL;  //neccessary?
2335        ideal rootIdeal;
2336        rootIdeal=fast_map(inputIdeal,inputRing,(ideal)theMap, currRing);
2337#ifdef gfan_DEBUG
2338        cout << "Root ideal is " << endl;
2339        idShow(rootIdeal);
2340        cout << "The root ring is " << endl;
2341        rWrite(rootRing);
2342        cout << endl;
2343#endif 
2344       
2345        //gcone *gcRoot = new gcone();  //Instantiate the sink
2346        gcone *gcRoot = new gcone(rootRing,rootIdeal);
2347        gcone *gcAct;
2348        gcAct = gcRoot;
2349        gcAct->numVars=pVariables;
2350        gcAct->getGB(rootIdeal);        //sets gcone::gcBasis
2351        idShow(gcAct->gcBasis);
2352        gcAct->getConeNormals(gcAct->gcBasis);  //hopefully compute the normals
2353        //gcAct->flip(gcAct->gcBasis,gcAct->facetPtr); 
2354        /*Now it is time to compute the search facets, respectively start the reverse search.
2355        But since we are in the root all facets should be search facets. IS THIS TRUE?
2356        NOTE: Check for flippability is not very sophisticated
2357        */     
2358        //gcAct->reverseSearch(gcAct); 
2359        rChangeCurrRing(rootRing);
2360        res=gcRoot->gcBasis;   
2361        }//if method==reverSearch
2362       
2363        if(method==noRevS)
2364        {
2365                gcone *gcRoot = new gcone(currRing,inputIdeal);
2366                gcone *gcAct;
2367                gcAct = gcRoot;
2368                gcAct->numVars=pVariables;
2369                gcAct->getGB(inputIdeal);
2370                gcAct->getConeNormals(gcAct->gcBasis);         
2371                gcAct->noRevS(*gcAct);         
2372                res=gcAct->gcBasis;     
2373        }
2374       
2375        /*As of now extra.cc expects gfan to return type ideal. Probably this will change in near future.
2376        The return type will then be of type LIST_CMD
2377        Assume gfan has finished, thus we have enumerated all the cones
2378        Create an array of size of #cones. Let each entry in the array contain a pointer to the respective
2379        Groebner Basis and merge this somehow with LIST_CMD
2380        => Count the cones!
2381        */
2382        //rChangeCurrRing(rootRing);
2383        //res=gcAct->gcBasis;
2384        //res=gcRoot->gcBasis; 
2385        return res;
2386        //return GBlist;
2387}
2388/*
2389Since gfan.cc is #included from extra.cc there must not be a int main(){} here
2390*/
2391#endif
Note: See TracBrowser for help on using the repository browser.