source: git/kernel/gfan.cc @ f07b38c

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