source: git/kernel/gfan.cc @ 197a82

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