source: git/kernel/gfan.cc @ 4c4a80

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