source: git/kernel/gfan.cc @ 6123d46

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