source: git/kernel/gfan.cc @ 398e35

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