source: git/kernel/gfan.cc @ ca02ab

spielwiese
Last change on this file since ca02ab was ca02ab, checked in by Martin Monerjan, 14 years ago
Enabled writeConeToFile to write files depending on UCN git-svn-id: file:///usr/local/Singular/svn/trunk@11911 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 55.3 KB
Line 
1/*
2Compute the Groebner fan of an ideal
3$Author: monerjan $
4$Date: 2009-06-19 11:22:06 $
5$Header: /exports/cvsroot-2/cvsroot/kernel/gfan.cc,v 1.63 2009-06-19 11:22:06 monerjan Exp $
6$Id: gfan.cc,v 1.63 2009-06-19 11:22:06 monerjan Exp $
7*/
8
9#include "mod2.h"
10
11#ifdef HAVE_GFAN
12
13#include "kstd1.h"
14#include "kutil.h"
15#include "intvec.h"
16#include "polys.h"
17#include "ideals.h"
18#include "kmatrix.h"
19#include "fast_maps.h"  //Mapping of ideals
20#include "maps.h"
21#include "ring.h"
22#include "prCopy.h"
23#include <iostream>
24#include <bitset>
25#include <fstream>      //read-write cones to files
26#include <gmp.h>
27#include <string>
28#include <sstream>
29//#include <gmpxx.h>
30
31/*DO NOT REMOVE THIS*/
32#ifndef GMPRATIONAL
33#define GMPRATIONAL
34#endif
35
36//Hacks for different working places
37#define ITWM
38
39#ifdef UNI
40#include "/users/urmel/alggeom/monerjan/cddlib/include/setoper.h" //Support for cddlib. Dirty hack
41#include "/users/urmel/alggeom/monerjan/cddlib/include/cdd.h"
42#endif
43
44#ifdef HOME
45#include "/home/momo/studium/diplomarbeit/cddlib/include/setoper.h"
46#include "/home/momo/studium/diplomarbeit/cddlib/include/cdd.h"
47#endif
48
49#ifdef ITWM
50#include "/u/slg/monerjan/cddlib/include/setoper.h"
51#include "/u/slg/monerjan/cddlib/include/cdd.h"
52#include "/u/slg/monerjan/cddlib/include/cddmp.h"
53#endif
54
55#ifndef gfan_DEBUG
56#define gfan_DEBUG
57#endif
58
59//#include gcone.h
60using namespace std;
61
62/**
63*\brief Class facet
64*       Implements the facet structure as a linked list
65*
66*/
67class facet
68{
69        private:
70                /** \brief Inner normal of the facet, describing it uniquely up to isomorphism */
71                intvec *fNormal;
72               
73                /** \brief An interior point of the facet*/
74                intvec *interiorPoint;
75               
76                /** \brief Universal Cone Number
77                * The number of the cone the facet belongs to
78                */
79                int UCN;
80               
81                /** \brief The codim of the facet
82                */
83                int codim;
84               
85                /** \brief The Groebner basis on the other side of a shared facet
86                 *
87                 * In order not to have to compute the flipped GB twice we store the basis we already get
88                 * when identifying search facets. Thus in the next step of the reverse search we can
89                 * just copy the old cone and update the facet and the gcBasis.
90                 * facet::flibGB is set via facet::setFlipGB() and printed via facet::printFlipGB
91                 */
92                ideal flipGB;           //The Groebner Basis on the other side, computed via gcone::flip               
93                       
94        public:         
95                //bool isFlippable;     //flippable facet? Want to have cone->isflippable.facet[i]
96                bool isIncoming;        //Is the facet incoming or outgoing?
97                facet *next;            //Pointer to next facet
98                facet *codim2Ptr;       //Pointer to (codim-2)-facet. Bit of recursion here ;-)
99                int numCodim2Facets;
100                ring flipRing;          //the ring on the other side of the facet
101                                               
102                /** The default constructor. Do I need a constructor of type facet(intvec)? */
103                facet()                 
104                {
105                        // Pointer to next facet.  */
106                        /* Defaults to NULL. This way there is no need to check explicitly */
107                        this->next=NULL; 
108                        this->UCN=NULL;
109                        this->codim2Ptr=NULL;
110                        this->codim=1;          //default for (codim-1)-facets
111                        this->numCodim2Facets=0;
112                }
113               
114                /** \brief Constructor for facets of codim >= 2
115                */
116                facet(int const &n)
117                {
118                        this->next=NULL; 
119                        this->UCN=NULL;
120                        this->codim2Ptr=NULL;
121                        if(n>1)
122                        {
123                                this->codim=n;
124                        }//NOTE Handle exception here!
125                        this->numCodim2Facets=0;
126                }
127               
128                /** The default destructor */
129                ~facet(){;}
130               
131                /** \brief Comparison of facets*/
132                bool areEqual(facet &f, facet &g)
133                {
134                        bool res = TRUE;
135                        intvec *fNormal = new intvec(pVariables);
136                        intvec *gNormal = new intvec(pVariables);
137                        fNormal = f.getFacetNormal();
138                        gNormal = g.getFacetNormal();
139                        if((fNormal == gNormal))//||(gcone::isParallel(fNormal,gNormal)))
140                        {
141                                if(f.numCodim2Facets==g.numCodim2Facets)
142                                {
143                                        facet *f2Act;
144                                        facet *g2Act;
145                                        f2Act = f.codim2Ptr;
146                                        g2Act = g.codim2Ptr;
147                                        intvec *f2N = new intvec(pVariables);
148                                        intvec *g2N = new intvec(pVariables);
149                                        while(f2Act->next!=NULL && g2Act->next!=NULL)
150                                        {
151                                                for(int ii=0;ii<f2N->length();ii++)
152                                                {
153                                                        if(f2Act->getFacetNormal() != g2Act->getFacetNormal())
154                                                        {
155                                                                res=FALSE;                                                             
156                                                        }
157                                                        if (res==FALSE)
158                                                                break;
159                                                }
160                                                if(res==FALSE)
161                                                        break;
162                                               
163                                                f2Act = f2Act->next;
164                                                g2Act = g2Act->next;
165                                        }//while
166                                }//if           
167                        }//if
168                        else
169                        {
170                                res = FALSE;
171                        }
172                        return res;
173                }
174               
175                /** Stores the facet normal \param intvec*/
176                void setFacetNormal(intvec *iv)
177                {
178                        this->fNormal = ivCopy(iv);                     
179                }
180               
181                /** Hopefully returns the facet normal */
182                intvec *getFacetNormal()
183                {                               
184                        return this->fNormal;
185                }
186               
187                /** Method to print the facet normal*/
188                void printNormal()
189                {
190                        fNormal->show();
191                }
192               
193                /** Store the flipped GB*/
194                void setFlipGB(ideal I)
195                {
196                        this->flipGB=idCopy(I);
197                }
198               
199                /** Return the flipped GB*/
200                ideal getFlipGB()
201                {
202                        return this->flipGB;
203                }
204               
205                /** Print the flipped GB*/
206                void printFlipGB()
207                {
208                        idShow(this->flipGB);
209                }
210               
211                void setUCN(int n)
212                {
213                        this->UCN=n;
214                }
215               
216                int getUCN()
217                {
218                        return this->UCN;
219                }
220               
221                void setInteriorPoint(intvec *iv)
222                {
223                        this->interiorPoint = ivCopy(iv);
224                }
225               
226                intvec *getInteriorPoint()
227                {
228                        return this->interiorPoint;
229                }               
230               
231                /*bool isFlippable(intvec &load)
232                {
233                        bool res=TRUE;                 
234                        int jj;
235                        for (int jj = 0; jj<load.length(); jj++)
236                        {
237                                intvec *ivCanonical = new intvec(load.length());
238                                (*ivCanonical)[jj]=1;                           
239                                if (ivMult(&load,ivCanonical)<0)
240                                {
241                                        res=FALSE;
242                                        break;
243                                }
244                        }
245                        return res;
246                       
247                        /*while (dotProduct(load,ivCanonical)>=0)
248                        {
249                                if (jj!=this->numVars)
250                                {
251                                        intvec *ivCanonical = new intvec(this->numVars);
252                                        (*ivCanonical)[jj]=1;                   
253                                        res=TRUE;
254                                        jj += 1;
255                                }
256                        }
257                        if (jj==this->numVars)
258                        {                       
259                                delete ivCanonical;
260                                return FALSE;
261                        }
262                        else
263                        {
264                                delete ivCanonical;
265                                return TRUE;
266                }*/                                             
267                //}//bool isFlippable(facet &f)
268               
269               
270                friend class gcone;     //Bad style
271};
272
273/**
274*\brief Implements the cone structure
275*
276* A cone is represented by a linked list of facet normals
277* @see facet
278*/
279/*class gcone
280finally this should become s.th. like gconelib.{h,cc} to provide an API
281*/
282class gcone
283{
284        private:               
285                ring rootRing;          //good to know this -> generic walk
286                ideal inputIdeal;       //the original
287                ring baseRing;          //the basering of the cone             
288                /* TODO in order to save memory use pointers to rootRing and inputIdeal instead */
289                intvec *ivIntPt;        //an interior point of the cone
290                static int UCN;         //unique number of the cone
291               
292        public: 
293                /** \brief Pointer to the first facet */
294                facet *facetPtr;        //Will hold the adress of the first facet; set by gcone::getConeNormals
295               
296                /** # of variables in the ring */
297                int numVars;            //#of variables in the ring
298               
299                /** # of facets of the cone
300                * This value is set by gcone::getConeNormals
301                */
302                int numFacets;          //#of facets of the cone
303               
304                /** Contains the Groebner basis of the cone. Is set by gcone::getGB(ideal I)*/
305                ideal gcBasis;          //GB of the cone, set by gcone::getGB();
306                gcone *next;            //Pointer to *previous* cone in search tree     
307               
308                /** \brief Default constructor.
309                *
310                * Initialises this->next=NULL and this->facetPtr=NULL
311                */
312                gcone()
313                {
314                        this->next=NULL;
315                        this->facetPtr=NULL;    //maybe this->facetPtr = new facet();                   
316                        this->baseRing=currRing;
317                        this->UCN++;
318                        this->numFacets=0;
319                }
320               
321                /** \brief Constructor with ring and ideal
322                *
323                * This constructor takes the root ring and the root ideal as parameters and stores
324                * them in the private members gcone::rootRing and gcone::inputIdeal
325                * Since knowledge of the root ring is only needed when using reverse search,
326                * this constructor is not needed when using the "second" method
327                */
328                gcone(ring r, ideal I)
329                {
330                        this->next=NULL;
331                        this->facetPtr=NULL;                   
332                        this->rootRing=r;
333                        this->inputIdeal=I;
334                        this->baseRing=currRing;
335                        this->UCN++;
336                        this->numFacets=0;
337                }
338               
339                /** \brief Copy constructor
340                *
341                * Copies a cone, sets this->gcBasis to the flipped GB and reverses the
342                * direction of the according facet normal
343                * Call this only after a successfull call to gcone::flip which sets facet::flipGB
344                */                     
345                //NOTE Prolly need to specify the facet to flip over
346//              gcone(const gcone& gc, const facet &f)         
347//              {
348//                      this->next=NULL;
349//                      this->numVars=gc.numVars;
350//                      this->UCN=(gc.UCN)+1;   //add 1 to the UCN of previous cone. This is NOT UNIQUE!
351//                      facet *fAct= new facet();                       
352//                      this->facetPtr=fAct;
353//                     
354//                      intvec *ivtmp = new intvec(this->numVars);
355//                      //NOTE ivtmp = f->getFacetNormal();                                             
356//                      ivtmp = gc.facetPtr->getFacetNormal();                 
357//                     
358//                      ideal gb;
359//                      //NOTE gb=f->getFlipGB();
360//                      gb=gc.facetPtr->getFlipGB();                   
361//                      this->gcBasis=gb;       //this cone's GB is the flipped GB                     
362//                     
363//                      /*Reverse direction of the facet normal to make it an inner normal*/                   
364//                      for (int ii=0; ii<this->numVars;ii++)
365//                      {
366//                              (*ivtmp)[ii]=-(*ivtmp)[ii];                             
367//                      }
368//                     
369//                      fAct->setFacetNormal(ivtmp);
370//                      delete ivtmp;
371//                      delete fAct;                                           
372//              }
373               
374                gcone(const gcone& gc, const facet &f)
375                {
376                        this->next=NULL;
377                        this->numVars=gc.numVars;
378                        //this->UCN=(gc.UCN)+1;
379                        this->UCN++;
380                        this->facetPtr=NULL;
381                        this->gcBasis=idCopy(f.flipGB);
382                        this->inputIdeal=idCopy(this->gcBasis);
383                        this->baseRing=rCopy0(f.flipRing);
384                        this->numFacets=0;
385                        //rComplete(this->baseRing);
386                        //rChangeCurrRing(this->baseRing);
387                }
388               
389                /** \brief Default destructor
390                */
391                ~gcone()
392                {
393                        //NOTE SAVE THE FACET STRUCTURE!!!
394                }                       
395               
396                /** \brief Set the interior point of a cone */
397                void setIntPoint(intvec *iv)
398                {
399                        this->ivIntPt=ivCopy(iv);
400                }
401               
402                /** \brief Return the interior point */
403                intvec *getIntPoint()
404                {
405                        return this->ivIntPt;
406                }
407               
408                void showIntPoint()
409                {
410                        ivIntPt->show();
411                }
412               
413                /** \brief Print facets
414                * This is mainly for debugging purposes. Usually called from within gdb
415                */
416                void showFacets(short codim=1)
417                {
418                        facet *f;
419                        switch(codim)
420                        {
421                                case 1:
422                                        f = this->facetPtr;
423                                        break;
424                                case 2:
425                                        f = this->facetPtr->codim2Ptr;
426                                        break;
427                        }                       
428                       
429                        intvec *iv = new intvec(this->numVars);
430                       
431                        while (f->next!=NULL)
432                        {
433                                iv = f->getFacetNormal();
434                                iv->show();
435                                f=f->next;
436                        }
437                        //delete iv;                   
438                }
439               
440                /** \brief Set gcone::numFacets */
441                void setNumFacets()
442                {
443                }
444               
445                /** \brief Get gcone::numFacets */
446                int getNumFacets()
447                {
448                        return this->numFacets;
449                }
450               
451                int getUCN()
452                {
453                        return this->UCN;
454                }
455               
456                /** \brief Compute the normals of the cone
457                *
458                * This method computes a representation of the cone in terms of facet normals. It takes an ideal
459                * as its input. Redundancies are automatically removed using cddlib's dd_MatrixCanonicalize.
460                * Other methods for redundancy checkings might be implemented later. See Anders' diss p.44.
461                * Note that in order to use cddlib a 0-th column has to be added to the matrix since cddlib expects
462                * each row to represent an inequality of type const+x1+...+xn <= 0. While computing the normals we come across
463                * the set \f$ \partial\mathcal{G} \f$ which we might store for later use. C.f p71 of journal
464                * As a result of this procedure the pointer facetPtr points to the first facet of the cone.
465                *
466                * Optionally, if the parameter bool compIntPoint is set to TRUE the method will also compute
467                * an interior point of the cone.
468                */
469                void getConeNormals(ideal const &I, bool compIntPoint=FALSE)
470                {
471#ifdef gfan_DEBUG
472                        std::cout << "*** Computing Inequalities... ***" << std::endl;
473#endif         
474                        //All variables go here - except ineq matrix and *v, see below
475                        int lengthGB=IDELEMS(I);        // # of polys in the groebner basis
476                        int pCompCount;                 // # of terms in a poly
477                        poly aktpoly;
478                        int numvar = pVariables;        // # of variables in a polynomial (or ring?)
479                        int leadexp[numvar];            // dirty hack of exp.vects
480                        int aktexp[numvar];
481                        int cols,rows;                  // will contain the dimensions of the ineq matrix - deprecated by
482                        dd_rowrange ddrows;
483                        dd_colrange ddcols;
484                        dd_rowset ddredrows;            // # of redundant rows in ddineq
485                        dd_rowset ddlinset;             // the opposite
486                        dd_rowindex ddnewpos;             // all to make dd_Canonicalize happy
487                        dd_NumberType ddnumb=dd_Integer; //Number type
488                        dd_ErrorType dderr=dd_NoError;  //
489                        // End of var declaration
490#ifdef gfan_DEBUG
491                        cout << "The Groebner basis has " << lengthGB << " elements" << endl;
492                        cout << "The current ring has " << numvar << " variables" << endl;
493#endif
494                        cols = numvar;
495               
496                        //Compute the # inequalities i.e. rows of the matrix
497                        rows=0; //Initialization
498                        for (int ii=0;ii<IDELEMS(I);ii++)
499                        {
500                                aktpoly=(poly)I->m[ii];
501                                rows=rows+pLength(aktpoly)-1;
502                        }
503#ifdef gfan_DEBUG
504                        cout << "rows=" << rows << endl;
505                        cout << "Will create a " << rows << " x " << cols << " matrix to store inequalities" << endl;
506#endif
507                        dd_rowrange aktmatrixrow=0;     // needed to store the diffs of the expvects in the rows of ddineq
508                        dd_set_global_constants();
509                        ddrows=rows;
510                        ddcols=cols;
511                        dd_MatrixPtr ddineq;            //Matrix to store the inequalities                     
512                        ddineq=dd_CreateMatrix(ddrows,ddcols+1); //The first col has to be 0 since cddlib checks for additive consts there
513               
514                        // We loop through each g\in GB and compute the resulting inequalities
515                        for (int i=0; i<IDELEMS(I); i++)
516                        {
517                                aktpoly=(poly)I->m[i];          //get aktpoly as i-th component of I
518                                pCompCount=pLength(aktpoly);    //How many terms does aktpoly consist of?
519#ifdef gfan_DEBUG
520                                cout << "Poly No. " << i << " has " << pCompCount << " components" << endl;
521#endif
522               
523                                int *v=(int *)omAlloc((numvar+1)*sizeof(int));
524                                pGetExpV(aktpoly,v);    //find the exp.vect in v[1],...,v[n], use pNext(p)
525                               
526                                //Store leadexp for aktpoly
527                                for (int kk=0;kk<numvar;kk++)
528                                {
529                                        leadexp[kk]=v[kk+1];
530                                        //Since we need to know the difference of leadexp with the other expvects we do nothing here
531                                        //but compute the diff below
532                                }
533               
534                               
535                                while (pNext(aktpoly)!=NULL) //move to next term until NULL
536                                {
537                                        aktpoly=pNext(aktpoly);
538                                        pSetm(aktpoly);         //doesn't seem to help anything
539                                        pGetExpV(aktpoly,v);
540                                        for (int kk=0;kk<numvar;kk++)
541                                        {
542                                                aktexp[kk]=v[kk+1];
543                                                //ineq[aktmatrixrow][kk]=leadexp[kk]-aktexp[kk];        //dito
544                                                dd_set_si(ddineq->matrix[(dd_rowrange)aktmatrixrow][kk+1],leadexp[kk]-aktexp[kk]); //because of the 1st col being const 0
545                                        }
546                                        aktmatrixrow=aktmatrixrow+1;
547                                }//while
548               
549                        } //for
550               
551                        //Maybe add another row to contain the constraints of the standard simplex?
552
553#ifdef gfan_DEBUG
554                        cout << "The inequality matrix is" << endl;
555                        dd_WriteMatrix(stdout, ddineq);
556#endif
557
558                        // The inequalities are now stored in ddineq
559                        // Next we check for superflous rows
560                        ddredrows = dd_RedundantRows(ddineq, &dderr);
561                        if (dderr!=dd_NoError)                  // did an error occur?
562                        {
563                                dd_WriteErrorMessages(stderr,dderr);    //if so tell us
564                        } else
565                        {
566                                cout << "Redundant rows: ";
567                                set_fwrite(stdout, ddredrows);          //otherwise print the redundant rows
568                        }//if dd_Error
569               
570                        //Remove reduntant rows here!
571                        dd_MatrixCanonicalize(&ddineq, &ddlinset, &ddredrows, &ddnewpos, &dderr);
572                        ddrows = ddineq->rowsize;       //Size of the matrix with redundancies removed
573                        ddcols = ddineq->colsize;
574#ifdef gfan_DEBUG
575                        cout << "Having removed redundancies, the normals now read:" << endl;
576                        dd_WriteMatrix(stdout,ddineq);
577                        cout << "Rows = " << ddrows << endl;
578                        cout << "Cols = " << ddcols << endl;
579#endif
580                       
581                        /*Write the normals into class facet*/
582#ifdef gfan_DEBUG
583                        cout << "Creating list of normals" << endl;
584#endif
585                        /*The pointer *fRoot should be the return value of this function*/
586                        facet *fRoot = new facet();     //instantiate new facet
587                        this->facetPtr = fRoot;         //set variable facetPtr of class gcone to first facet
588                        facet *fAct;                    //instantiate pointer to active facet
589                        fAct = fRoot;                   //Seems to do the trick. fRoot and fAct have to point to the same adress!
590                        //std::cout << "fRoot = " << fRoot << ", fAct = " << fAct << endl;
591                        for (int kk = 0; kk<ddrows; kk++)
592                        {
593                                intvec *load = new intvec(this->numVars);       //intvec to store a single facet normal that will then be stored via setFacetNormal
594                                for (int jj = 1; jj <ddcols; jj++)
595                                {
596                                        double foo;
597                                        foo = mpq_get_d(ddineq->matrix[kk][jj]);
598#ifdef gfan_DEBUG
599                                        std::cout << "fAct is " << foo << " at " << fAct << std::endl;
600#endif
601                                        (*load)[jj-1] = (int)foo;               //store typecasted entry at pos jj-1 of load           
602                                }//for (int jj = 1; jj <ddcols; jj++)
603                               
604                                /*Quick'n'dirty hack for flippability*/ 
605                                bool isFlippable=FALSE;                         
606                                for (int jj = 0; jj<load->length(); jj++)
607                                {
608                                        intvec *ivCanonical = new intvec(load->length());
609                                        (*ivCanonical)[jj]=1;
610                                        cout << "dotProd=" << dotProduct(*load,*ivCanonical) << endl;
611                                        if (dotProduct(*load,*ivCanonical)<0)   
612                                        //if (ivMult(load,ivCanonical)<0)
613                                        {
614                                                isFlippable=TRUE;
615                                                break;  //URGHS
616                                        }
617                                }       
618                                if (isFlippable==FALSE)
619                                {
620                                        cout << "Ignoring facet";
621                                        load->show();
622                                        //fAct->next=NULL;
623                                }
624                                else
625                                {       /*Now load should be full and we can call setFacetNormal*/
626                                        fAct->setFacetNormal(load);
627                                        fAct->next = new facet();                                       
628                                        fAct=fAct->next;        //this should definitely not be called in the above while-loop :D
629                                        this->numFacets++;
630                                }//if (isFlippable==FALSE)
631                                //delete load;
632                        }//for (int kk = 0; kk<ddrows; kk++)
633                       
634                        /*
635                        Now we should have a linked list containing the facet normals of those facets that are
636                        -irredundant
637                        -flipable
638                        Adressing is done via *facetPtr
639                        */
640                       
641                        if (compIntPoint==TRUE)
642                        {
643                                intvec *iv = new intvec(this->numVars);
644                                interiorPoint(ddineq, *iv);     //NOTE ddineq contains non-flippable facets
645                                this->setIntPoint(iv);  //stores the interior point in gcone::ivIntPt
646                                //delete iv;
647                        }
648                       
649                        //Compute the number of facets
650                        // wrong because ddineq->rowsize contains only irredundant facets. There can still be
651                        // non-flippable ones!
652                        //this->numFacets=ddineq->rowsize;
653                       
654                        //Clean up but don't delete the return value! (Whatever it will turn out to be)                 
655                        //dd_FreeMatrix(ddineq);
656                        //set_free(ddredrows);
657                        //free(ddnewpos);
658                        //set_free(ddlinset);
659                        //NOTE Commented out. Solved the bug that after facet2Matrix there were facets lost
660                        //THIS SUCKS
661                        //dd_free_global_constants();
662
663                }//method getConeNormals(ideal I)       
664               
665                /** \brief Compute the (codim-2)-facets of a given cone
666                * This method is used during noRevS
667                */
668                void getCodim2Normals(gcone const &gc)
669                {
670                        this->facetPtr->codim2Ptr = new facet(2);       //instantiate a (codim-2)-facet                 
671                        facet *codim2Act;
672                        codim2Act = this->facetPtr->codim2Ptr;
673                       
674                        dd_set_global_constants();
675                       
676                        dd_MatrixPtr ddineq,P,ddakt;
677                        dd_rowset impl_linset, redset;
678                        dd_ErrorType err;
679                        dd_rowindex newpos;             
680
681                        ddineq = facets2Matrix(gc);     //get a matrix representation of the cone
682                               
683                        /*Now set appropriate linearity*/
684                        dd_PolyhedraPtr ddpolyh;
685                        for (int ii=0; ii<this->numFacets; ii++)
686                        {                               
687                                ddakt = dd_CopyMatrix(ddineq);
688                                set_addelem(ddakt->linset,ii+1);
689                                                                               
690                                dd_MatrixCanonicalize(&ddakt, &impl_linset, &redset, &newpos, &err);                   
691                                       
692                                        //dd_WriteMatrix(stdout,ddakt);
693                                ddpolyh=dd_DDMatrix2Poly(ddakt, &err);
694                                P=dd_CopyGenerators(ddpolyh);
695                                dd_WriteMatrix(stdout,P);
696                                       
697                                /* We loop through each row of P
698                                * normalize it by making all entries integer ones
699                                * and add the resulting vector to the int matrix facet::codim2Facets
700                                */
701                                for (int jj=1;jj<=P->rowsize;jj++)
702                                {
703                                        intvec *n = new intvec(this->numVars);
704                                        makeInt(P,jj,*n);                                               
705                                        codim2Act->setFacetNormal(n);
706                                        this->facetPtr->numCodim2Facets++;      //Honor the creation of a codim-2-facet
707                                        codim2Act->next = new facet(2);
708                                        codim2Act = codim2Act->next;                                           
709                                        delete n;                                                                       
710                                }                                                                               
711                                       
712                                dd_FreeMatrix(ddakt);
713                                dd_FreePolyhedra(ddpolyh);
714                        }
715                }
716               
717                /** \brief Compute the Groebner Basis on the other side of a shared facet
718                *
719                * Implements algorithm 4.3.2 from Anders' thesis.
720                * As shown there it is not necessary to compute an interior point. The knowledge of the facet normal
721                * suffices. A term \f$ x^\gamma \f$ of \f$ g \f$ is in \f$  in_\omega(g) \f$ iff \f$ \gamma - leadexp(g)\f$
722                * is parallel to \f$ leadexp(g) \f$
723                * Parallelity is checked using basic linear algebra. See gcone::isParallel.
724                * Other possibilities include computing the rank of the matrix consisting of the vectors in question and
725                * computing an interior point of the facet and taking all terms having the same weight with respect
726                * to this interior point.
727                *\param ideal, facet
728                * Input: a marked,reduced Groebner basis and a facet
729                */
730                void flip(ideal gb, facet *f)           //Compute "the other side"
731                {                       
732                        intvec *fNormal = new intvec(this->numVars);    //facet normal, check for parallelity                   
733                        fNormal = f->getFacetNormal();  //read this->fNormal;
734#ifdef gfan_DEBUG
735                        std::cout << "===" << std::endl;
736                        std::cout << "running gcone::flip" << std::endl;
737//                      std::cout << "fNormal=";
738//                      fNormal->show();
739//                      std::cout << std::endl;
740#endif                         
741                        /*1st step: Compute the initial ideal*/
742                        poly initialFormElement[IDELEMS(gb)];   //array of #polys in GB to store initial form
743                        ideal initialForm=idInit(IDELEMS(gb),this->gcBasis->rank);
744                        poly aktpoly;
745                        intvec *check = new intvec(this->numVars);      //array to store the difference of LE and v
746                       
747                        for (int ii=0;ii<IDELEMS(gb);ii++)
748                        {
749                                aktpoly = (poly)gb->m[ii];                                                             
750                                int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
751                                int *leadExpV=(int *)omAlloc((this->numVars+1)*sizeof(int));
752                                pGetExpV(aktpoly,leadExpV);     //find the leading exponent in leadExpV[1],...,leadExpV[n], use pNext(p)
753                                initialFormElement[ii]=pHead(aktpoly);
754                               
755                                while(pNext(aktpoly)!=NULL)     /*loop trough terms and check for parallelity*/
756                                {
757                                        aktpoly=pNext(aktpoly); //next term
758                                        pSetm(aktpoly);
759                                        pGetExpV(aktpoly,v);           
760                                        /* Convert (int)v into (intvec)check */                 
761                                        for (int jj=0;jj<this->numVars;jj++)
762                                        {
763                                                //cout << "v["<<jj+1<<"]="<<v[jj+1]<<endl;
764                                                //cout << "leadExpV["<<jj+1<<"]="<<leadExpV[jj+1]<<endl;
765                                                (*check)[jj]=v[jj+1]-leadExpV[jj+1];
766                                        }
767#ifdef gfan_DEBUG
768//                                      cout << "check=";                       
769//                                      check->show();
770//                                      cout << endl;
771#endif
772                                        //TODO why not *check, *fNormal????
773                                        if (isParallel(*check,*fNormal)) //pass *check when
774                                        {
775//                                              cout << "Parallel vector found, adding to initialFormElement" << endl;                 
776                                                initialFormElement[ii] = pAdd(pCopy(initialFormElement[ii]),(poly)pHead(aktpoly));
777                                        }                                               
778                                }//while
779#ifdef gfan_DEBUG
780                                cout << "Initial Form=";                               
781                                pWrite(initialFormElement[ii]);
782                                cout << "---" << endl;
783#endif
784                                /*Now initialFormElement must be added to (ideal)initialForm */
785                                initialForm->m[ii]=initialFormElement[ii];
786                        }//for                 
787#ifdef gfan_DEBUG
788                        cout << "Initial ideal is: " << endl;
789                        idShow(initialForm);
790                        //f->printFlipGB();
791                        cout << "===" << endl;
792#endif
793                        //delete check;
794                       
795                        /*2nd step: lift initial ideal to a GB of the neighbouring cone using minus alpha as weight*/
796                        /*Substep 2.1
797                        compute $G_{-\alpha}(in_v(I))
798                        see journal p. 66
799                        NOTE Check for different rings. Prolly it will not always be necessary to add a weight, if the
800                        srcRing already has a weighted ordering
801                        */
802                        ring srcRing=currRing;
803                        ring tmpRing;
804
805                        //intvec *negfNormal = new intvec(this->numVars);
806                        //negfNormal=ivNeg(fNormal);
807                        if( (srcRing->order[0]==ringorder_dp)
808                                || (srcRing->order[0]==ringorder_Dp)
809                                 || (srcRing->order[0]==ringorder_ds)
810                                 || (srcRing->order[0]==ringorder_ls) )
811                        {
812                                tmpRing=rCopyAndAddWeight(srcRing,ivNeg(fNormal));
813                        }
814                        else
815                        {
816                                tmpRing=rCopy0(srcRing);
817                                int length=fNormal->length();
818                                int *A=(int *)omAlloc(length*sizeof(int));
819                                for(int jj=0;jj<length;jj++)
820                                {
821                                        A[jj]=-(*fNormal)[jj];
822                                }
823                                tmpRing->wvhdl[0]=(int*)A;
824                                rComplete(tmpRing);     
825                        }
826                        rChangeCurrRing(tmpRing);
827                       
828                        //rWrite(currRing); cout << endl;
829                       
830                        ideal ina;                     
831                        ina=idrCopyR(initialForm,srcRing);                     
832#ifdef gfan_DEBUG
833                        cout << "ina=";
834                        idShow(ina); cout << endl;
835#endif
836                        ideal H;
837                        H=kStd(ina,NULL,isHomog,NULL);  //we know it is homogeneous
838                        idSkipZeroes(H);
839#ifdef gfan_DEBUG
840//                      cout << "H="; idShow(H); cout << endl;
841#endif
842                        /*Substep 2.2
843                        do the lifting and mark according to H
844                        */
845                        rChangeCurrRing(srcRing);
846                        ideal srcRing_H;
847                        ideal srcRing_HH;                       
848                        srcRing_H=idrCopyR(H,tmpRing);
849#ifdef gfan_DEBUG
850//                      cout << "srcRing_H = ";
851//                      idShow(srcRing_H); cout << endl;
852#endif
853                        srcRing_HH=ffG(srcRing_H,this->gcBasis);               
854#ifdef gfan_DEBUG
855//                      cout << "srcRing_HH = ";
856//                      idShow(srcRing_HH); cout << endl;
857#endif
858                        /*Substep 2.2.1
859                        Mark according to G_-\alpha
860                        Here we have a minimal basis srcRing_HH. In order to turn this basis into a reduced basis
861                        we have to compute an interior point of C(srcRing_HH). For this we need to know the cone
862                        represented by srcRing_HH MARKED ACCORDING TO G_{-\alpha}
863                        Thus we check whether the leading monomials of srcRing_HH and srcRing_H coincide. If not we
864                        compute the difference accordingly
865                        */
866                        dd_set_global_constants();
867                        bool markingsAreCorrect=FALSE;
868                        dd_MatrixPtr intPointMatrix;
869                        int iPMatrixRows=0;
870                        dd_rowrange aktrow=0;                   
871                        for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
872                        {
873                                poly aktpoly=(poly)srcRing_HH->m[ii];
874                                iPMatrixRows = iPMatrixRows+pLength(aktpoly)-1;
875                        }
876                        /* additionally one row for the standard-simplex and another for a row that becomes 0 during
877                        construction of the differences
878                        */
879                        intPointMatrix = dd_CreateMatrix(iPMatrixRows+2,this->numVars+1);
880                        intPointMatrix->numbtype=dd_Integer;    //NOTE: DO NOT REMOVE OR CHANGE TO dd_Rational
881                       
882                        for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
883                        {
884                                markingsAreCorrect=FALSE;       //crucial to initialise here
885                                poly aktpoly=srcRing_HH->m[ii];
886                                /*Comparison of leading monomials is done via exponent vectors*/
887                                for (int jj=0;jj<IDELEMS(H);jj++)
888                                {
889                                        int *src_ExpV = (int *)omAlloc((this->numVars+1)*sizeof(int));
890                                        int *dst_ExpV = (int *)omAlloc((this->numVars+1)*sizeof(int));
891                                        pGetExpV(aktpoly,src_ExpV);
892                                        rChangeCurrRing(tmpRing);       //this ring change is crucial!
893                                        pGetExpV(pCopy(H->m[ii]),dst_ExpV);
894                                        rChangeCurrRing(srcRing);
895                                        bool expVAreEqual=TRUE;
896                                        for (int kk=1;kk<=this->numVars;kk++)
897                                        {
898#ifdef gfan_DEBUG
899                                                //cout << src_ExpV[kk] << "," << dst_ExpV[kk] << endl;
900#endif
901                                                if (src_ExpV[kk]!=dst_ExpV[kk])
902                                                {
903                                                        expVAreEqual=FALSE;
904                                                }
905                                        }                                       
906                                        //if (*src_ExpV == *dst_ExpV)
907                                        if (expVAreEqual==TRUE)
908                                        {
909                                                markingsAreCorrect=TRUE; //everything is fine
910#ifdef gfan_DEBUG
911//                                              cout << "correct markings" << endl;
912#endif
913                                        }//if (pHead(aktpoly)==pHead(H->m[jj])
914                                        delete src_ExpV;
915                                        delete dst_ExpV;
916                                }//for (int jj=0;jj<IDELEMS(H);jj++)
917                               
918                                int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
919                                int *leadExpV=(int *)omAlloc((this->numVars+1)*sizeof(int));
920                                if (markingsAreCorrect==TRUE)
921                                {
922                                        pGetExpV(aktpoly,leadExpV);
923                                }
924                                else
925                                {
926                                        rChangeCurrRing(tmpRing);
927                                        pGetExpV(pHead(H->m[ii]),leadExpV); //We use H->m[ii] as leading monomial
928                                        rChangeCurrRing(srcRing);
929                                }
930                                /*compute differences of the expvects*/                         
931                                while (pNext(aktpoly)!=NULL)
932                                {
933                                        /*The following if-else-block makes sure the first term (i.e. the wrongly marked term)
934                                        is not omitted when computing the differences*/
935                                        if(markingsAreCorrect==TRUE)
936                                        {
937                                                aktpoly=pNext(aktpoly);
938                                                pGetExpV(aktpoly,v);
939                                        }
940                                        else
941                                        {
942                                                pGetExpV(pHead(aktpoly),v);
943                                                markingsAreCorrect=TRUE;
944                                        }
945
946                                        for (int jj=0;jj<this->numVars;jj++)
947                                        {                               
948                                                /*Store into ddMatrix*/                                                         
949                                                dd_set_si(intPointMatrix->matrix[aktrow][jj+1],leadExpV[jj+1]-v[jj+1]);
950                                        }
951                                        aktrow +=1;
952                                }
953                                delete v;
954                                delete leadExpV;
955                        }//for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
956                        /*Now we add the constraint for the standard simplex*/
957                        /*NOTE:Might actually work without the standard simplex*/
958                        dd_set_si(intPointMatrix->matrix[aktrow][0],-1);
959                        for (int jj=1;jj<=this->numVars;jj++)
960                        {
961                                dd_set_si(intPointMatrix->matrix[aktrow][jj],1);
962                        }
963                        dd_WriteMatrix(stdout,intPointMatrix);
964                        intvec *iv_weight = new intvec(this->numVars);
965                        interiorPoint(intPointMatrix, *iv_weight);      //iv_weight now contains the interior point
966                        dd_FreeMatrix(intPointMatrix);
967                        dd_free_global_constants();
968                       
969                        /*Step 3
970                        turn the minimal basis into a reduced one
971                        */
972                        //ring dstRing=rCopyAndAddWeight(tmpRing,iv_weight);   
973                       
974//                      int i,j;
975//                      ring dstRing=rCopy0(srcRing);
976//                      i=rBlocks(srcRing);
977//                     
978//                      dstRing->order=(int *)omAlloc((i+1)*sizeof(int));
979//                      for(j=i;j>0;j--)
980//                      {
981//                              dstRing->order[j]=srcRing->order[j-1];
982//                              dstRing->block0[j]=srcRing->block0[j-1];
983//                              dstRing->block1[j]=srcRing->block1[j-1];
984//                              if (srcRing->wvhdl[j-1] != NULL)
985//                              {
986//                                      dstRing->wvhdl[j] = (int*) omMemDup(srcRing->wvhdl[j-1]);
987//                              }
988//                      }
989//                      dstRing->order[0]=ringorder_a;
990//                      dstRing->order[1]=ringorder_dp;
991//                      dstRing->order[2]=ringorder_C;                 
992//                      dstRing->wvhdl[0] =( int *)omAlloc((iv_weight->length())*sizeof(int));
993//                     
994//                      for (int ii=0;ii<this->numVars;ii++)
995//                      {                               
996//                              dstRing->wvhdl[0][ii]=(*iv_weight)[ii];                         
997//                      }
998//                      rComplete(dstRing);
999                       
1000                        // NOTE May assume that at this point srcRing already has 3 blocks of orderins, starting with a
1001                        // Thus:
1002                        //ring dstRing=rCopyAndChangeWeight(srcRing,iv_weight);
1003                        //cout << "PLING" << endl;
1004                        /*ring dstRing=rCopy0(srcRing);
1005                        for (int ii=0;ii<this->numVars;ii++)
1006                        {                               
1007                                dstRing->wvhdl[0][ii]=(*iv_weight)[ii];                         
1008                        }*/
1009                        ring dstRing=rCopy0(tmpRing);
1010                        int length=iv_weight->length();
1011                        int *A=(int *)omAlloc(length*sizeof(int));
1012                        for(int jj=0;jj<length;jj++)
1013                        {
1014                                A[jj]=(*iv_weight)[jj];
1015                        }
1016                        dstRing->wvhdl[0]=(int*)A;
1017                        rComplete(dstRing);
1018                        //rSetWeightVec(dstRing,iv_weight);
1019                        //assume(dstRing!=NULL);
1020                        //assume(dstRing->OrdSize>0);
1021                        //assume(dstRing->typ[0].ord_typ==ro_dp);
1022                        //memcpy(dstRing->typ[0].data.wp.weights,iv_weight,dstRing->N*sizeof(int));             
1023                        rChangeCurrRing(dstRing);
1024                       
1025#ifdef gfan_DEBUG
1026                        rWrite(dstRing); cout << endl;
1027#endif
1028                        ideal dstRing_I;                       
1029                        dstRing_I=idrCopyR(srcRing_HH,srcRing);                 
1030                        //validOpts<1>=TRUE;
1031#ifdef gfan_DEBUG
1032                        //idShow(dstRing_I);
1033#endif                 
1034                        BITSET save=test;
1035                        test|=Sy_bit(OPT_REDSB);
1036                        test|=Sy_bit(6);        //OPT_DEBUG                                     
1037                        dstRing_I=kStd(idrCopyR(this->inputIdeal,this->baseRing),NULL,testHomog,NULL);                                 
1038                        kInterRed(dstRing_I);
1039                        idSkipZeroes(dstRing_I);
1040                        test=save;
1041                        /*End of step 3 - reduction*/
1042                       
1043                        f->setFlipGB(dstRing_I);//store the flipped GB
1044                        f->flipRing=rCopy0(dstRing);    //store the ring on the other side
1045#ifdef gfan_DEBUG
1046                        cout << "Flipped GB is: " << endl;
1047                        f->printFlipGB();
1048#endif                 
1049                        rChangeCurrRing(srcRing);       //return to the ring we started the computation of flipGB in
1050                }//void flip(ideal gb, facet *f)
1051                               
1052                /** \brief Compute the remainder of a polynomial by a given ideal
1053                *
1054                * Compute \f$ f^{\mathcal{G}} \f$
1055                * Algorithm is taken from Cox, Little, O'Shea, IVA 2nd Ed. p 62
1056                * However, since we are only interested in the remainder, there is no need to
1057                * compute the factors \f$ a_i \f$
1058                */
1059                //NOTE: Should be replaced by kNF or kNF2
1060                poly restOfDiv(poly const &f, ideal const &I)
1061                {
1062                        cout << "Entering restOfDiv" << endl;
1063                        poly p=f;
1064                        //pWrite(p);
1065                        //poly r=kCreateZeroPoly(,currRing,currRing);   //The 0-polynomial, hopefully
1066                        poly r=NULL;    //The zero polynomial
1067                        int ii;
1068                        bool divOccured;
1069                       
1070                        while (p!=NULL)
1071                        {
1072                                ii=1;
1073                                divOccured=FALSE;
1074                               
1075                                while( (ii<=IDELEMS(I) && (divOccured==FALSE) ))
1076                                {                                       
1077                                        if (pDivisibleBy(I->m[ii-1],p)) //does LM(I->m[ii]) divide LM(p) ?
1078                                        {                                               
1079                                                poly step1,step2,step3;
1080                                                //cout << "dividing "; pWrite(pHead(p));cout << "by ";pWrite(pHead(I->m[ii-1])); cout << endl;
1081                                                step1 = pDivideM(pHead(p),pHead(I->m[ii-1]));
1082                                                //cout << "LT(p)/LT(f_i)="; pWrite(step1); cout << endl;                               
1083                                                step2 = ppMult_qq(step1, I->m[ii-1]);                                           
1084                                                step3 = pSub(pCopy(p), step2);
1085                                                //p=pSub(p,pMult( pDivide(pHead(p),pHead(I->m[ii])), I->m[ii]));                       
1086                                                //pSetm(p);
1087                                                pSort(step3); //must be here, otherwise strange behaviour with many +o+o+o+o+ terms
1088                                                p=step3;
1089                                                //pWrite(p);                                           
1090                                                divOccured=TRUE;
1091                                        }
1092                                        else
1093                                        {
1094                                                ii += 1;
1095                                        }//if (pLmDivisibleBy(I->m[ii],p,currRing))
1096                                }//while( (ii<IDELEMS(I) && (divOccured==FALSE) ))
1097                                if (divOccured==FALSE)
1098                                {
1099                                        //cout << "TICK 5" << endl;
1100                                        r=pAdd(pCopy(r),pHead(p));
1101                                        pSetm(r);
1102                                        pSort(r);
1103                                        //cout << "r="; pWrite(r); cout << endl;
1104                                       
1105                                        if (pLength(p)!=1)
1106                                        {
1107                                                p=pSub(pCopy(p),pHead(p));      //Here it may occur that p=0 instead of p=NULL
1108                                        }
1109                                        else
1110                                        {
1111                                                p=NULL; //Hack to correct this situation                                               
1112                                        }                                       
1113                                        //cout << "p="; pWrite(p);
1114                                }//if (divOccured==FALSE)
1115                        }//while (p!=0)
1116                        return r;
1117                }//poly restOfDiv(poly const &f, ideal const &I)
1118               
1119                /** \brief Compute \f$ f-f^{\mathcal{G}} \f$
1120                */
1121                //NOTE: use kNF or kNF2 instead of restOfDivision
1122                ideal ffG(ideal const &H, ideal const &G)
1123                {
1124                        cout << "Entering ffG" << endl;
1125                        int size=IDELEMS(H);
1126                        ideal res=idInit(size,1);
1127                        poly temp1, temp2, temp3;       //polys to temporarily store values for pSub
1128                        for (int ii=0;ii<size;ii++)
1129                        {
1130                                res->m[ii]=restOfDiv(H->m[ii],G);
1131                                //res->m[ii]=kNF(H->m[ii],G);
1132                                temp1=H->m[ii];
1133                                temp2=res->m[ii];                               
1134                                temp3=pSub(temp1, temp2);
1135                                res->m[ii]=temp3;
1136                                //res->m[ii]=pSub(temp1,temp2); //buggy
1137                                //pSort(res->m[ii]);
1138                                //pSetm(res->m[ii]);
1139                                //cout << "res->m["<<ii<<"]=";pWrite(res->m[ii]);                                               
1140                        }                       
1141                        return res;
1142                }
1143               
1144                /** \brief Compute a Groebner Basis
1145                *
1146                * Computes the Groebner basis and stores the result in gcone::gcBasis
1147                *\param ideal
1148                *\return void
1149                */
1150                void getGB(ideal const &inputIdeal)
1151                {
1152                        ideal gb;
1153                        gb=kStd(inputIdeal,NULL,testHomog,NULL);
1154                        idSkipZeroes(gb);
1155                        this->gcBasis=gb;       //write the GB into gcBasis
1156                }//void getGB
1157               
1158                /** \brief The Generic Groebner Walk due to FJLT
1159                * Needed for computing the search facet
1160                */
1161                ideal GenGrbWlk(ideal, ideal)
1162                {
1163                }//GGW
1164               
1165                /** \brief Compute the negative of a given intvec
1166                */             
1167                intvec *ivNeg(const intvec *iv)
1168                {
1169                        intvec *res = new intvec(iv->length());
1170                        res=ivCopy(iv);
1171                        *res *= (int)-1;
1172                        //for(int ii=0;ii<this->numVars;ii++)
1173                        //{                     
1174                                //(res)[ii] = (*res[ii])*(int)(-1);
1175                        //}
1176                        res->show();                   
1177                        return res;
1178                }
1179
1180
1181                /** \brief Compute the dot product of two intvecs
1182                *
1183                */
1184                int dotProduct(intvec const &iva, intvec const &ivb)                           
1185                {
1186                        //intvec iva=a;
1187                        //intvec ivb=b;
1188                        int res=0;
1189                        for (int i=0;i<this->numVars;i++)
1190                        {
1191                                res = res+(iva[i]*ivb[i]);
1192                        }
1193                        return res;
1194                }//int dotProduct
1195
1196                /** \brief Check whether two intvecs are parallel
1197                *
1198                * \f$ \alpha\parallel\beta\Leftrightarrow\langle\alpha,\beta\rangle^2=\langle\alpha,\alpha\rangle\langle\beta,\beta\rangle \f$
1199                */
1200                bool isParallel(intvec const &a, intvec const &b)
1201                {                       
1202                        int lhs,rhs;
1203                        lhs=dotProduct(a,b)*dotProduct(a,b);
1204                        rhs=dotProduct(a,a)*dotProduct(b,b);
1205                        //cout << "LHS="<<lhs<<", RHS="<<rhs<<endl;
1206                        if (lhs==rhs)
1207                        {
1208                                return TRUE;
1209                        }
1210                        else
1211                        {
1212                                return FALSE;
1213                        }
1214                }//bool isParallel
1215               
1216                /** \brief Compute an interior point of a given cone
1217                * Result will be written into intvec iv
1218                */
1219                void interiorPoint(dd_MatrixPtr const &M, intvec &iv) //no const &M here since we want to remove redundant rows
1220                {
1221                        dd_LPPtr lp,lpInt;
1222                        dd_ErrorType err=dd_NoError;
1223                        dd_LPSolverType solver=dd_DualSimplex;
1224                        dd_LPSolutionPtr lpSol=NULL;
1225                        dd_rowset ddlinset,ddredrows;   //needed for dd_FindRelativeInterior
1226                        dd_rowindex ddnewpos;
1227                        dd_NumberType numb;     
1228                        //M->representation=dd_Inequality;
1229                        //M->objective-dd_LPMin;  //Not sure whether this is needed
1230                       
1231                        //NOTE: Make this n-dimensional!
1232                        //dd_set_si(M->rowvec[0],1);dd_set_si(M->rowvec[1],1);dd_set_si(M->rowvec[2],1);
1233                                                                       
1234                        //dd_MatrixCanonicalize(&M, &ddlinset, &ddredrows, &ddnewpos, &err);
1235                        //if (err!=dd_NoError){cout << "Error during dd_MatrixCanonicalize" << endl;}
1236                        //cout << "Tick 2" << endl;
1237                        //dd_WriteMatrix(stdout,M);
1238                       
1239                        lp=dd_Matrix2LP(M, &err);
1240                        if (err!=dd_NoError){cout << "Error during dd_Matrix2LP in gcone::interiorPoint" << endl;}                     
1241                        if (lp==NULL){cout << "LP is NULL" << endl;}
1242#ifdef gfan_DEBUG
1243//                      dd_WriteLP(stdout,lp);
1244#endif 
1245                                       
1246                        lpInt=dd_MakeLPforInteriorFinding(lp);
1247                        if (err!=dd_NoError){cout << "Error during dd_MakeLPForInteriorFinding in gcone::interiorPoint" << endl;}
1248#ifdef gfan_DEBUG
1249//                      dd_WriteLP(stdout,lpInt);
1250#endif                 
1251
1252                        dd_FindRelativeInterior(M,&ddlinset,&ddredrows,&lpSol,&err);
1253                        if (err!=dd_NoError)
1254                        {
1255                                cout << "Error during dd_FindRelativeInterior in gcone::interiorPoint" << endl;
1256                                dd_WriteErrorMessages(stdout, err);
1257                        }
1258                       
1259                        //dd_LPSolve(lpInt,solver,&err);        //This will not result in a point from the relative interior
1260                        if (err!=dd_NoError){cout << "Error during dd_LPSolve" << endl;}
1261                                                                       
1262                        //lpSol=dd_CopyLPSolution(lpInt);
1263                        if (err!=dd_NoError){cout << "Error during dd_CopyLPSolution" << endl;}                 
1264#ifdef gfan_DEBUG
1265                        cout << "Interior point: ";
1266                        for (int ii=1; ii<(lpSol->d)-1;ii++)
1267                        {
1268                                dd_WriteNumber(stdout,lpSol->sol[ii]);
1269                        }
1270                        cout << endl;
1271#endif
1272                       
1273                        //NOTE The following strongly resembles parts of makeInt.
1274                        //Maybe merge sometimes
1275                        mpz_t kgV; mpz_init(kgV);
1276                        mpz_set_str(kgV,"1",10);
1277                        mpz_t den; mpz_init(den);
1278                        mpz_t tmp; mpz_init(tmp);
1279                        mpq_get_den(tmp,lpSol->sol[1]);
1280                        for (int ii=1;ii<(lpSol->d)-1;ii++)
1281                        {
1282                                mpq_get_den(den,lpSol->sol[ii+1]);
1283                                mpz_lcm(kgV,tmp,den);
1284                                mpz_set(tmp, kgV);
1285                        }
1286                        mpq_t qkgV;
1287                        mpq_init(qkgV);
1288                        mpq_set_z(qkgV,kgV);
1289                        for (int ii=1;ii<(lpSol->d)-1;ii++)
1290                        {
1291                                mpq_t product;
1292                                mpq_init(product);
1293                                mpq_mul(product,qkgV,lpSol->sol[ii]);
1294                                iv[ii-1]=(int)mpz_get_d(mpq_numref(product));
1295                                mpq_clear(product);
1296                        }
1297#ifdef gfan_DEBUG
1298                        iv.show();
1299                        cout << endl;
1300#endif
1301                        mpq_clear(qkgV);
1302                        mpz_clear(tmp);
1303                        mpz_clear(den);
1304                        mpz_clear(kgV);                 
1305                       
1306                        dd_FreeLPSolution(lpSol);
1307                        dd_FreeLPData(lpInt);
1308                        dd_FreeLPData(lp);
1309                        set_free(ddlinset);
1310                        set_free(ddredrows);                   
1311                       
1312                }//void interiorPoint(dd_MatrixPtr const &M)
1313               
1314                /** \brief Copy a ring and add a weighted ordering in first place
1315                * Kudos to walkSupport.cc
1316                */
1317                ring rCopyAndAddWeight(ring const &r, intvec const *ivw)                               
1318                {
1319                        ring res=(ring)omAllocBin(ip_sring_bin);
1320                        memcpy4(res,r,sizeof(ip_sring));
1321                        res->VarOffset = NULL;
1322                        res->ref=0;
1323                       
1324                        if (r->algring!=NULL)
1325                                r->algring->ref++;
1326                        if (r->parameter!=NULL)
1327                        {
1328                                res->minpoly=nCopy(r->minpoly);
1329                                int l=rPar(r);
1330                                res->parameter=(char **)omAlloc(l*sizeof(char_ptr));
1331                                int i;
1332                                for(i=0;i<rPar(r);i++)
1333                                {
1334                                        res->parameter[i]=omStrDup(r->parameter[i]);
1335                                }
1336                        }
1337                       
1338                        int i=rBlocks(r);
1339                        int jj;
1340                       
1341                        res->order =(int *)omAlloc((i+1)*sizeof(int));
1342                        res->block0=(int *)omAlloc((i+1)*sizeof(int));
1343                        res->block1=(int *)omAlloc((i+1)*sizeof(int));
1344                        res->wvhdl =(int **)omAlloc((i+1)*sizeof(int**));
1345                        for(jj=0;jj<i;jj++)
1346                        {                               
1347                                if (r->wvhdl[jj] != NULL)
1348                                {
1349                                        res->wvhdl[jj] = (int*) omMemDup(r->wvhdl[jj-1]);
1350                                }
1351                                else
1352                                {
1353                                        res->wvhdl[jj+1]=NULL;
1354                                }
1355                        }
1356                       
1357                        for (jj=0;jj<i;jj++)
1358                        {
1359                                res->order[jj+1]=r->order[jj];
1360                                res->block0[jj+1]=r->block0[jj];
1361                                res->block1[jj+1]=r->block1[jj];
1362                        }                                               
1363                       
1364                        res->order[0]=ringorder_a;
1365                        res->order[1]=ringorder_dp;     //basically useless, since that should never be used                   
1366                        int length=ivw->length();
1367                        int *A=(int *)omAlloc(length*sizeof(int));
1368                        for (jj=0;jj<length;jj++)
1369                        {                               
1370                                A[jj]=(*ivw)[jj];                               
1371                        }                       
1372                        res->wvhdl[0]=(int *)A;
1373                        res->block0[0]=1;
1374                        res->block1[0]=length;
1375                       
1376                        res->names = (char **)omAlloc0(rVar(r) * sizeof(char_ptr));
1377                        for (i=rVar(res)-1;i>=0; i--)
1378                        {
1379                                res->names[i] = omStrDup(r->names[i]);
1380                        }                       
1381                        rComplete(res);
1382                        return res;
1383                }//rCopyAndAdd
1384               
1385                ring rCopyAndChangeWeight(ring const &r, intvec *ivw)
1386                {
1387                        ring res=rCopy0(currRing);
1388                        rComplete(res);
1389                        rSetWeightVec(res,(int64*)ivw);
1390                        //rChangeCurrRing(rnew);
1391                        return res;
1392                }
1393               
1394                /** \brief Checks whether a given facet is a search facet
1395                * Determines whether a given facet of a cone is the search facet of a neighbouring cone
1396                * This is done in the following way:
1397                * We loop through all facets of the cone and find the "smallest" facet, i.e. the unique facet
1398                * that is first crossed during the generic walk.
1399                * We then check whether the fNormal of this facet is parallel to the fNormal of our testfacet.
1400                * If this is the case, then our facet is indeed a search facet and TRUE is retuned.
1401                */
1402                bool isSearchFacet(gcone &gcTmp, facet *testfacet)
1403                {                               
1404                        ring actRing=currRing;
1405                        facet *facetPtr=(facet*)gcTmp.facetPtr;                 
1406                        facet *fMin=new facet(*facetPtr);       //Pointer to the "minimal" facet
1407                        //facet *fMin = new facet(tmpcone.facetPtr);
1408                        //fMin=tmpcone.facetPtr;                //Initialise to first facet of tmpcone
1409                        facet *fAct;    //Ptr to alpha_i
1410                        facet *fCmp;    //Ptr to alpha_j
1411                        fAct = fMin;
1412                        fCmp = fMin->next;                             
1413                       
1414                        rChangeCurrRing(this->rootRing);        //because we compare the monomials in the rootring                     
1415                        poly p=pInit();
1416                        poly q=pInit();
1417                        intvec *alpha_i = new intvec(this->numVars);                   
1418                        intvec *alpha_j = new intvec(this->numVars);
1419                        intvec *sigma = new intvec(this->numVars);
1420                        sigma=gcTmp.getIntPoint();
1421                       
1422                        int *u=(int *)omAlloc((this->numVars+1)*sizeof(int));
1423                        int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
1424                        u[0]=0; v[0]=0;
1425                        int weight1,weight2;
1426                        while(fAct->next->next!=NULL)   //NOTE this is ugly. Can it be done without fCmp?
1427                        {
1428                                /* Get alpha_i and alpha_{i+1} */
1429                                alpha_i=fAct->getFacetNormal();
1430                                alpha_j=fCmp->getFacetNormal();
1431#ifdef gfan_DEBUG
1432                                alpha_i->show(); 
1433                                alpha_j->show();
1434#endif
1435                                /*Compute the dot product of sigma and alpha_{i,j}*/
1436                                weight1=dotProduct(sigma,alpha_i);
1437                                weight2=dotProduct(sigma,alpha_j);
1438#ifdef gfan_DEBUG
1439                                cout << "weight1=" << weight1 << " " << "weight2=" << weight2 << endl;
1440#endif
1441                                /*Adjust alpha_i and alpha_i+1 accordingly*/
1442                                for(int ii=1;ii<=this->numVars;ii++)
1443                                {                                       
1444                                        u[ii]=weight1*(*alpha_i)[ii-1];
1445                                        v[ii]=weight2*(*alpha_j)[ii-1];
1446                                }                               
1447                               
1448                                /*Now p_weight and q_weight need to be compared as exponent vectors*/
1449                                pSetCoeff0(p,nInit(1));
1450                                pSetCoeff0(q,nInit(1));
1451                                pSetExpV(p,u); 
1452                                pSetm(p);                       
1453                                pSetExpV(q,v); 
1454                                pSetm(q);
1455#ifdef gfan_DEBUG                               
1456                                pWrite(p);pWrite(q);
1457#endif 
1458                                /*We want to check whether x^p < x^q
1459                                => want to check for return value 1 */
1460                                if (pLmCmp(p,q)==1)     //i.e. x^q is smaller
1461                                {
1462                                        fMin=fCmp;
1463                                        fAct=fMin;
1464                                        fCmp=fCmp->next;
1465                                }
1466                                else
1467                                {
1468                                        //fAct=fAct->next;
1469                                        if(fCmp->next!=NULL)
1470                                        {
1471                                                fCmp=fCmp->next;
1472                                        }
1473                                        else
1474                                        {
1475                                                fAct=fAct->next;
1476                                        }
1477                                }
1478                                //fAct=fAct->next;
1479                        }//while(fAct.facetPtr->next!=NULL)
1480                        delete alpha_i,alpha_j,sigma;
1481                       
1482                        /*If testfacet was minimal then fMin should still point there */
1483                       
1484                        //if(fMin->getFacetNormal()==ivNeg(testfacet.getFacetNormal()))                 
1485#ifdef gfan_DEBUG
1486                        cout << "Checking for parallelity" << endl <<" fMin is";
1487                        fMin->printNormal();
1488                        cout << "testfacet is ";
1489                        testfacet->printNormal();
1490                        cout << endl;
1491#endif
1492                        if (fMin==gcTmp.facetPtr)                       
1493                        //if(areEqual(fMin->getFacetNormal(),ivNeg(testfacet.getFacetNormal())))
1494                        //if (isParallel(fMin->getFacetNormal(),testfacet->getFacetNormal()))
1495                        {                               
1496                                cout << "Parallel" << endl;
1497                                rChangeCurrRing(actRing);
1498                                //delete alpha_min, test;
1499                                return TRUE;
1500                        }
1501                        else 
1502                        {
1503                                cout << "Not parallel" << endl;
1504                                rChangeCurrRing(actRing);
1505                                //delete alpha_min, test;
1506                                return FALSE;
1507                        }
1508                }//bool isSearchFacet
1509               
1510                /** \brief Check for equality of two intvecs
1511                */
1512                bool areEqual(intvec const &a, intvec const &b)
1513                {
1514                        bool res=TRUE;
1515                        for(int ii=0;ii<this->numVars;ii++)
1516                        {
1517                                if(a[ii]!=b[ii])
1518                                {
1519                                        res=FALSE;
1520                                        break;
1521                                }
1522                        }
1523                        return res;
1524                }
1525               
1526                /** \brief The reverse search algorithm
1527                */
1528                void reverseSearch(gcone *gcAct) //no const possible here since we call gcAct->flip
1529                {
1530                        facet *fAct=new facet();
1531                        fAct = gcAct->facetPtr;                 
1532                       
1533                        while(fAct->next!=NULL)  //NOTE NOT SURE WHETHER THIS IS RIGHT! Do I reach EVERY facet or only all but the last?
1534                        {
1535                                cout << "==========================================================================================="<< endl;
1536                                gcAct->flip(gcAct->gcBasis,gcAct->facetPtr);
1537                                gcone *gcTmp = new gcone(*gcAct);
1538                                //idShow(gcTmp->gcBasis);
1539                                gcTmp->getConeNormals(gcTmp->gcBasis, TRUE);
1540#ifdef gfan_DEBUG
1541                                facet *f = new facet();
1542                                f=gcTmp->facetPtr;
1543                                while(f->next!=NULL)
1544                                {
1545                                        f->printNormal();
1546                                        f=f->next;                                     
1547                                }
1548#endif
1549                                gcTmp->showIntPoint();
1550                                /*recursive part goes gere*/
1551                                if (isSearchFacet(*gcTmp,(facet*)gcAct->facetPtr))
1552                                {
1553                                        gcAct->next=gcTmp;
1554                                        cout << "PING"<< endl;
1555                                        reverseSearch(gcTmp);
1556                                }
1557                                else
1558                                {
1559                                        delete gcTmp;
1560                                        /*NOTE remove fAct from linked list. It's no longer needed*/
1561                                }
1562                                /*recursion ends*/
1563                                fAct = fAct->next;             
1564                        }//while(fAct->next!=NULL)
1565                }//reverseSearch
1566               
1567                /** \brief The new method of Markwig and Jensen
1568                * Compute gcBasis and facets for the arbitrary starting cone. Store \f$(codim-1)\f$-facets as normals.
1569                * In order to represent a facet uniquely compute also the \f$(codim-2)\f$-facets and norm by the gcd of the components.
1570                * Keep a list of facets as a linked list containing an intvec and an integer matrix.
1571                * Since a \f$(codim-1)\f$-facet belongs to exactly two full dimensional cones, we remove a facet from the list as
1572                * soon as we compute this facet again. Comparison of facets is done by...
1573                */
1574                void noRevS(gcone &gcRoot, bool usingIntPoint=FALSE)
1575                {       
1576                        facet *SearchListRoot = new facet(); //The list containing ALL facets we come across
1577                        facet *SearchListAct;
1578                        SearchListAct = SearchListRoot;
1579                       
1580                        gcone *gcAct;
1581                        gcAct = &gcRoot;
1582                        gcone *gcPtr;
1583                        gcPtr = &gcRoot;
1584                       
1585                        facet *fAct;
1586                        fAct = gcAct->facetPtr;                 
1587                                               
1588                        int UCNcounter=gcAct->getUCN();
1589#ifdef gfan_DEBUG
1590                        cout << "NoRevs" << endl;
1591                        cout << "Facets are:" << endl;
1592                        gcAct->showFacets();
1593#endif                 
1594                       
1595                        gcAct->getCodim2Normals(*gcAct);
1596                               
1597                        //Compute unique representation of codim-2-facets
1598                        gcAct->normalize();
1599                       
1600                        /*Make a copy of the facet list of first cone
1601                        Since the operations getCodim2Normals and normalize affect the facets
1602                        we must not memcpy them before these ops!
1603                        */
1604                        while(fAct->next!=NULL)
1605                        {                               
1606                                memcpy(SearchListAct,fAct,sizeof(facet));
1607                                SearchListAct->next = new facet();
1608                                SearchListAct = SearchListAct->next;
1609                                fAct = fAct->next;
1610                        }
1611                        SearchListAct = SearchListRoot; //Set to beginning of list
1612                       
1613                        fAct = gcAct->facetPtr;
1614                        if(areEqual(fAct->getFacetNormal(),fAct->next->getFacetNormal()))
1615                        {
1616                                cout <<"HI" << endl;
1617                        }
1618                       
1619                        gcAct->writeConeToFile(*gcAct);
1620                       
1621                        /*End of initialisation*/
1622                        fAct = SearchListAct;
1623                        /*2nd step
1624                        Choose a facet from fListPtr, flip it and forget the previous cone
1625                        We always choose the first facet from fListPtr as facet to be flipped
1626                        */
1627                        while(SearchListAct->next!=NULL)
1628                        {//NOTE See to it that the cone is only changed after ALL facets have been flipped!
1629                                //As of now this is not the case!
1630                                int flag=1;
1631                                fAct = SearchListAct;
1632                                //while( ( (fAct->next!=NULL) && (fAct->getUCN()==fAct->next->getUCN() ) ) )
1633                                do
1634                                {
1635                                        gcAct->flip(gcAct->gcBasis,fAct);
1636                                        ring rTmp=rCopy(SearchListAct->flipRing);
1637                                        rComplete(rTmp);
1638                                        rChangeCurrRing(rTmp);
1639                                        gcone *gcTmp = new gcone::gcone(*gcAct,*SearchListAct);
1640                                        gcTmp->getConeNormals(gcTmp->gcBasis, FALSE);
1641                                        gcTmp->getCodim2Normals(*gcTmp);
1642                                        /*add facets to SLA here*/                                     
1643                                        rChangeCurrRing(gcAct->baseRing);
1644                                        gcPtr->next=gcTmp;
1645                                        if(flag==1)
1646                                                gcAct->next=gcTmp;
1647                                        gcPtr=gcPtr->next;
1648                                        if(fAct->getUCN() == fAct->next->getUCN())
1649                                        {
1650                                                fAct=fAct->next;
1651                                        }
1652                                        else
1653                                                break;
1654                                        flag++;
1655                                }while( ( (fAct->next!=NULL) && (fAct->getUCN()==fAct->next->getUCN() ) ) );   
1656                                if (fAct->next!=NULL)
1657                                {
1658                                        SearchListAct=fAct->next;
1659                                        ring r=rCopy(SearchListAct->flipRing);
1660                                        rComplete(r);
1661                                        rChangeCurrRing(r);
1662                                        gcAct = gcAct->next;
1663                                }
1664                                else
1665                                {
1666                                        SearchListAct=NULL;
1667                                }
1668                               
1669                        }                       
1670               
1671                        //NOTE Hm, comment in and get a crash for free...
1672                        //dd_free_global_constants();                           
1673                        //gc.writeConeToFile(gc);
1674                       
1675                       
1676                        //fAct = fListPtr;
1677                        //gcone *gcTmp = new gcone(gc); //copy
1678                        //gcTmp->flip(gcTmp->gcBasis,fAct);
1679                        //NOTE: gcTmp may be deleted, gcRoot from main proc should probably not!
1680                       
1681                }//void noRevS(gcone &gc)       
1682               
1683               
1684                /** \brief Make a set of rational vectors into integers
1685                *
1686                * We compute the lcm of the denominators and multiply with this to get integer values.         
1687                * \param dd_MatrixPtr,intvec
1688                */
1689                void makeInt(dd_MatrixPtr const &M, int const line, intvec &n)
1690                {                       
1691                        mpz_t denom[this->numVars];
1692                        for(int ii=0;ii<this->numVars;ii++)
1693                        {
1694                                mpz_init_set_str(denom[ii],"0",10);
1695                        }
1696               
1697                        mpz_t kgV,tmp;
1698                        mpz_init(kgV);
1699                        mpz_init(tmp);
1700                       
1701                        for (int ii=0;ii<(M->colsize)-1;ii++)
1702                        {
1703                                mpz_t z;
1704                                mpz_init(z);
1705                                mpq_get_den(z,M->matrix[line-1][ii+1]);
1706                                mpz_set( denom[ii], z);
1707                                mpz_clear(z);                           
1708                        }
1709                       
1710                        /*Compute lcm of the denominators*/
1711                        mpz_set(tmp,denom[0]);
1712                        for (int ii=0;ii<(M->colsize)-1;ii++)
1713                        {
1714                                mpz_lcm(kgV,tmp,denom[ii]);                             
1715                        }
1716                       
1717                        /*Multiply the nominators by kgV*/
1718                        mpq_t qkgV,res;
1719                        mpq_init(qkgV);
1720                        mpq_set_str(qkgV,"1",10);
1721                        mpq_canonicalize(qkgV);
1722                       
1723                        mpq_init(res);
1724                        mpq_set_str(res,"1",10);
1725                        mpq_canonicalize(res);
1726                       
1727                        mpq_set_num(qkgV,kgV);
1728                       
1729//                      mpq_canonicalize(qkgV);
1730                        for (int ii=0;ii<(M->colsize)-1;ii++)
1731                        {
1732                                mpq_mul(res,qkgV,M->matrix[line-1][ii+1]);
1733                                n[ii]=(int)mpz_get_d(mpq_numref(res));
1734                        }
1735                        //mpz_clear(denom[this->numVars]);
1736                        mpz_clear(kgV);
1737                        mpq_clear(qkgV); mpq_clear(res);                       
1738                       
1739                }
1740                /**
1741                 * We compute the gcd of the components of the codim-2-facets and
1742                 * multiply the each codim-2facet by it. Thus we get a normalized representation of each
1743                 * (codim-2)-facet normal.
1744                */
1745                void normalize()
1746                {
1747                        int ggT=1;
1748                        facet *codim2Act;
1749                        codim2Act = this->facetPtr->codim2Ptr;
1750                        intvec *n = new intvec(this->numVars);
1751                       
1752                        while(codim2Act->next!=NULL)
1753                        {                               
1754                                n=codim2Act->getFacetNormal();
1755                                for(int ii=0;ii<this->numVars;ii++)
1756                                {
1757                                        ggT = intgcd(ggT,(*n)[ii]);
1758                                }
1759                                codim2Act = codim2Act->next;                           
1760                        }
1761                        //delete n;
1762                        codim2Act = this->facetPtr->codim2Ptr;  //reset to start of linked list
1763                        while(codim2Act->next!=NULL)
1764                        {
1765                                //intvec *n = new intvec(this->numVars);
1766                                n=codim2Act->getFacetNormal();
1767                                intvec *new_n = new intvec(this->numVars);
1768                                for(int ii=0;ii<this->numVars;ii++)
1769                                {
1770                                        (*new_n)[ii] = (*n)[ii]*ggT;
1771                                }
1772                                codim2Act->setFacetNormal(new_n);
1773                                codim2Act = codim2Act->next;
1774                                //delete n;
1775                                //delete new_n;
1776                        }                       
1777                }
1778               
1779                /** \brief Compute the gcd of two ints
1780                */
1781                int intgcd(int a, int b)
1782                {
1783                        int r, p=a, q=b;
1784                        if(p < 0)
1785                                p = -p;
1786                        if(q < 0)
1787                                q = -q;
1788                        while(q != 0)
1789                        {
1790                                r = p % q;
1791                                p = q;
1792                                q = r;
1793                        }
1794                        return p;
1795                }               
1796               
1797                /** \brief Construct a dd_MatrixPtr from a cone's list of facets
1798                *
1799                */
1800                dd_MatrixPtr facets2Matrix(gcone const &gc)
1801                {
1802                        facet *fAct;
1803                        fAct = gc.facetPtr;
1804       
1805                        dd_MatrixPtr M;
1806                        dd_rowrange ddrows;
1807                        dd_colrange ddcols;
1808                        ddcols=(this->numVars)+1;
1809                        ddrows=this->numFacets;
1810                        dd_NumberType numb = dd_Integer;
1811                        M=dd_CreateMatrix(ddrows,ddcols);                       
1812                       
1813                        int jj=0;
1814                        while(fAct->next!=NULL)
1815                        {
1816                                intvec *comp;
1817                                comp = fAct->getFacetNormal();
1818                                for(int ii=0;ii<this->numVars;ii++)
1819                                {
1820                                        dd_set_si(M->matrix[jj][ii+1],(*comp)[ii]);
1821                                }
1822                                jj++;
1823                                fAct=fAct->next;                               
1824                        }                       
1825                       
1826                        return M;
1827                }
1828               
1829                /** \brief Write information about a cone into a file on disk
1830                *
1831                * This methods writes the information needed for the "second" method into a file.
1832                * The file's is divided in sections containing information on
1833                * 1) the ring
1834                * 2) the cone's Groebner Basis
1835                * 3) the cone's facets
1836                * Each line contains exactly one date
1837                * Each section starts with its name in CAPITALS
1838                */
1839                void writeConeToFile(gcone const &gc, bool usingIntPoints=FALSE)
1840                {
1841                        int UCN=gc.UCN;
1842                        stringstream ss;
1843                        ss << UCN;
1844                        string UCNstr = ss.str();               
1845                       
1846                        char prefix[]="/tmp/cone";
1847                        char *UCNstring;
1848                        strcpy(UCNstring,UCNstr.c_str());
1849                        char suffix[]=".sg";
1850                        char *filename=strcat(prefix,UCNstring);
1851                        strcat(filename,suffix);
1852                                       
1853                        ofstream gcOutputFile(filename);
1854                        facet *fAct = new facet(); //NOTE Why new?
1855                        fAct = gc.facetPtr;                     
1856                       
1857                        char *ringString = rString(currRing);
1858                       
1859                        if (!gcOutputFile)
1860                        {
1861                                cout << "Error opening file for writing in writeConeToFile" << endl;
1862                        }
1863                        else
1864                        {       gcOutputFile << "UCN" << endl;
1865                                gcOutputFile << this->UCN << endl;
1866                                gcOutputFile << "RING" << endl; 
1867                                gcOutputFile << ringString << endl;                     
1868                                //Write this->gcBasis into file
1869                                gcOutputFile << "GCBASIS" << endl;                             
1870                                for (int ii=0;ii<IDELEMS(gc.gcBasis);ii++)
1871                                {                                       
1872                                        gcOutputFile << p_String((poly)gc.gcBasis->m[ii],gc.baseRing) << endl;
1873                                }                               
1874                               
1875                                gcOutputFile << "FACETS" << endl;                                                               
1876                                while(fAct->next!=NULL)
1877                                {       
1878                                        intvec *iv = new intvec(gc.numVars);
1879                                        iv=fAct->getFacetNormal();
1880                                        for (int ii=0;ii<iv->length();ii++)
1881                                        {
1882                                                if (ii<iv->length()-1)
1883                                                {
1884                                                        gcOutputFile << (*iv)[ii] << ",";
1885                                                }
1886                                                else
1887                                                {
1888                                                        gcOutputFile << (*iv)[ii] << endl;
1889                                                }
1890                                        }
1891                                        fAct=fAct->next;
1892                                        //delete iv; iv=NULL;
1893                                }                               
1894                               
1895                                gcOutputFile.close();
1896                                //delete fAct; fAct=NULL;
1897                        }
1898                       
1899                }//writeConeToFile(gcone const &gc)
1900               
1901                /** \brief Reads a cone from a file identified by its number
1902                */
1903                void readConeFromFile(int gcNum)
1904                {
1905                }
1906               
1907        friend class facet;
1908};//class gcone
1909
1910int gcone::UCN=0;
1911
1912ideal gfan(ideal inputIdeal)
1913{
1914        int numvar = pVariables; 
1915       
1916        enum searchMethod {
1917                reverseSearch,
1918                noRevS
1919        };
1920       
1921        searchMethod method;
1922        method = noRevS;
1923//      method = reverseSearch;
1924       
1925#ifdef gfan_DEBUG
1926        cout << "Now in subroutine gfan" << endl;
1927#endif
1928        ring inputRing=currRing;        // The ring the user entered
1929        ring rootRing;                  // The ring associated to the target ordering
1930        ideal res;     
1931        facet *fRoot;
1932       
1933        if (method==reverseSearch)
1934        {
1935       
1936        /* Construct a new ring which will serve as our root*/
1937        rootRing=rCopy0(currRing);
1938        rootRing->order[0]=ringorder_lp;
1939       
1940        rComplete(rootRing);
1941        rChangeCurrRing(rootRing);
1942       
1943        /* Fetch the inputIdeal into our rootRing */
1944        map theMap=(map)idMaxIdeal(1);  //evil hack!
1945        theMap->preimage=NULL;  //neccessary?
1946        ideal rootIdeal;
1947        rootIdeal=fast_map(inputIdeal,inputRing,(ideal)theMap, currRing);
1948#ifdef gfan_DEBUG
1949        cout << "Root ideal is " << endl;
1950        idShow(rootIdeal);
1951        cout << "The root ring is " << endl;
1952        rWrite(rootRing);
1953        cout << endl;
1954#endif 
1955       
1956        //gcone *gcRoot = new gcone();  //Instantiate the sink
1957        gcone *gcRoot = new gcone(rootRing,rootIdeal);
1958        gcone *gcAct;
1959        gcAct = gcRoot;
1960        gcAct->numVars=pVariables;
1961        gcAct->getGB(rootIdeal);        //sets gcone::gcBasis
1962        idShow(gcAct->gcBasis);
1963        gcAct->getConeNormals(gcAct->gcBasis);  //hopefully compute the normals
1964        //gcAct->flip(gcAct->gcBasis,gcAct->facetPtr); 
1965        /*Now it is time to compute the search facets, respectively start the reverse search.
1966        But since we are in the root all facets should be search facets. IS THIS TRUE?
1967        NOTE: Check for flippability is not very sophisticated
1968        */     
1969        //gcAct->reverseSearch(gcAct); 
1970        rChangeCurrRing(rootRing);
1971        res=gcRoot->gcBasis;   
1972        }//if method==reverSearch
1973       
1974        if(method==noRevS)
1975        {
1976                gcone *gcRoot = new gcone(currRing,inputIdeal);
1977                gcone *gcAct;
1978                gcAct = gcRoot;
1979                gcAct->numVars=pVariables;
1980                gcAct->getGB(inputIdeal);
1981                gcAct->getConeNormals(gcAct->gcBasis);         
1982                gcAct->noRevS(*gcAct);         
1983                res=gcAct->gcBasis;     
1984        }
1985       
1986        /*As of now extra.cc expects gfan to return type ideal. Probably this will change in near future.
1987        The return type will then be of type LIST_CMD
1988        Assume gfan has finished, thus we have enumerated all the cones
1989        Create an array of size of #cones. Let each entry in the array contain a pointer to the respective
1990        Groebner Basis and merge this somehow with LIST_CMD
1991        => Count the cones!
1992        */
1993        //rChangeCurrRing(rootRing);
1994        //res=gcAct->gcBasis;
1995        //res=gcRoot->gcBasis; 
1996        return res;
1997        //return GBlist;
1998}
1999/*
2000Since gfan.cc is #included from extra.cc there must not be a int main(){} here
2001*/
2002#endif
Note: See TracBrowser for help on using the repository browser.