source: git/kernel/gfan.cc @ f5a3167

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