source: git/kernel/gfan.cc @ 0d278c

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