source: git/kernel/gfan.cc @ a23a297

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