source: git/kernel/gfan.cc @ 631b6c8

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