source: git/kernel/gfan.cc @ 725ef18

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