source: git/kernel/gfan.cc @ b082fc

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