source: git/kernel/gfan.cc @ d2cd515

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