source: git/kernel/gfan.cc @ b3af93

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