source: git/kernel/gfan.cc @ 86f23e

spielwiese
Last change on this file since 86f23e was 86f23e, checked in by Martin Monerjan, 15 years ago
populated method revereSearch new method isSearchFacet; calling with references does not work as expected though rev will not compile git-svn-id: file:///usr/local/Singular/svn/trunk@11760 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 36.4 KB
Line 
1/*
2Compute the Groebner fan of an ideal
3$Author: monerjan $
4$Date: 2009-04-30 09:32:01 $
5$Header: /exports/cvsroot-2/cvsroot/kernel/gfan.cc,v 1.43 2009-04-30 09:32:01 monerjan Exp $
6$Id: gfan.cc,v 1.43 2009-04-30 09:32:01 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.h>   //deprecated
24#include <bitset>
25
26/*remove the following at your own risk*/
27#ifndef GMPRATIONAL
28#define GMPRATIONAL
29#endif
30
31//Hacks for different working places
32#define ITWM
33
34#ifdef UNI
35#include "/users/urmel/alggeom/monerjan/cddlib/include/setoper.h" //Support for cddlib. Dirty hack
36#include "/users/urmel/alggeom/monerjan/cddlib/include/cdd.h"
37#endif
38
39#ifdef HOME
40#include "/home/momo/studium/diplomarbeit/cddlib/include/setoper.h"
41#include "/home/momo/studium/diplomarbeit/cddlib/include/cdd.h"
42#endif
43
44#ifdef ITWM
45#include "/u/slg/monerjan/cddlib/include/setoper.h"
46#include "/u/slg/monerjan/cddlib/include/cdd.h"
47#include "/u/slg/monerjan/cddlib/include/cddmp.h"
48#endif
49
50#ifndef gfan_DEBUG
51#define gfan_DEBUG
52#endif
53
54//#include gcone.h
55
56/**
57*\brief Class facet
58*       Implements the facet structure as a linked list
59*
60*/
61class facet
62{
63        private:
64                /** \brief Inner normal of the facet, describing it uniquely up to isomorphism */
65                intvec *fNormal;
66               
67                /** \brief The Groebner basis on the other side of a shared facet
68                 *
69                 * In order not to have to compute the flipped GB twice we store the basis we already get
70                 * when identifying search facets. Thus in the next step of the reverse search we can
71                 * just copy the old cone and update the facet and the gcBasis.
72                 * facet::flibGB is set via facet::setFlipGB() and printed via facet::printFlipGB
73                 */
74                ideal flipGB;           //The Groebner Basis on the other side, computed via gcone::flip
75
76                       
77        public:
78                /** The default constructor. Do I need a constructor of type facet(intvec)? */
79                facet()                 
80                {
81                        // Pointer to next facet.  */
82                        /* Defaults to NULL. This way there is no need to check explicitly */
83                        this->next=NULL; 
84                }
85               
86                /** The default destructor */
87                ~facet(){;}
88               
89                /** Stores the facet normal \param intvec*/
90                void setFacetNormal(intvec *iv)
91                {
92                        this->fNormal = ivCopy(iv);
93                        //return;
94                }
95               
96                /** Hopefully returns the facet normal */
97                intvec *getFacetNormal()
98                {       
99                        //this->fNormal->show();        cout << endl;   
100                        return this->fNormal;
101                }
102               
103                /** Method to print the facet normal*/
104                void printNormal()
105                {
106                        fNormal->show();
107                }
108               
109                /** Store the flipped GB*/
110                void setFlipGB(ideal I)
111                {
112                        this->flipGB=I;
113                }
114               
115                /** Return the flipped GB*/
116                ideal getFlipGB()
117                {
118                        return this->flipGB;
119                }
120               
121                /** Print the flipped GB*/
122                void printFlipGB()
123                {
124                        idShow(this->flipGB);
125                }
126               
127                bool isFlippable;       //flippable facet? Want to have cone->isflippable.facet[i]
128                bool isIncoming;        //Is the facet incoming or outgoing?
129                facet *next;            //Pointer to next facet
130               
131                friend class gcone;     //Bad style
132};
133
134/**
135*\brief Implements the cone structure
136*
137* A cone is represented by a linked list of facet normals
138* @see facet
139*/
140/*class gcone
141finally this should become s.th. like gconelib.{h,cc} to provide an API
142*/
143class gcone
144{
145        private:
146                int numFacets;          //#of facets of the cone
147                ring rootRing;          //good to know this -> generic walk
148                ideal inputIdeal;       //the original
149                ring baseRing;          //the basering of the cone             
150                /* TODO in order to save memory use pointers to rootRing and inputIdeal instead */
151                intvec *ivIntPt;        //an interior point of the cone
152               
153        public:
154                /** \brief Default constructor.
155                *
156                * Initialises this->next=NULL and this->facetPtr=NULL
157                */
158                gcone()
159                {
160                        this->next=NULL;
161                        this->facetPtr=NULL;
162                        this->baseRing=currRing;
163                }
164               
165                /** \brief Constructor with ring and ideal
166                *
167                * This constructor takes the root ring and the root ideal as parameters and stores
168                * them in the private members gcone::rootRing and gcone::inputIdeal
169                */
170                gcone(ring r, ideal I)
171                {
172                        this->next=NULL;
173                        this->facetPtr=NULL;
174                        this->rootRing=r;
175                        this->inputIdeal=I;
176                        this->baseRing=currRing;
177                }
178               
179                /** \brief Copy constructor
180                *
181                * Copies one cone, sets this->gcBasis to the flipped GB and reverses the
182                * direction of the according facet normal
183                */                     
184                gcone(const gcone& gc)         
185                {
186                        this->next=NULL;
187                        this->numVars=gc.numVars;                       
188                        facet *fAct= new facet();                       
189                        this->facetPtr=fAct;
190                       
191                        intvec *ivtmp = new intvec(this->numVars);                                             
192                        ivtmp = gc.facetPtr->getFacetNormal();
193                        ivtmp->show();                 
194                       
195                        ideal gb;
196                        gb=gc.facetPtr->getFlipGB();                   
197                        this->gcBasis=gb;//gc.facetPtr->getFlipGB();    //this cone's GB is the flipped GB
198                        idShow(this->gcBasis);
199                       
200                        /*Reverse direction of the facet normal to make it an inner normal*/                   
201                        for (int ii=0; ii<this->numVars;ii++)
202                        {
203                                (*ivtmp)[ii]=-(*ivtmp)[ii];                             
204                        }
205                        //ivtmp->show(); cout << endl;
206                        fAct->setFacetNormal(ivtmp);
207                        //fAct->printNormal();cout << endl;
208                        //ivtmp->show();cout << endl;
209                }
210               
211                /** \brief Default destructor */
212                ~gcone();               //destructor
213               
214                /** Pointer to the first facet */
215                facet *facetPtr;        //Will hold the adress of the first facet; set by gcone::getConeNormals
216               
217                /** # of variables in the ring */
218                int numVars;            //#of variables in the ring
219               
220                /** Contains the Groebner basis of the cone. Is set by gcone::getGB(ideal I)*/
221                ideal gcBasis;          //GB of the cone, set by gcone::getGB();
222                gcone *next;            //Pointer to *previous* cone in search tree
223               
224                /** \brief Set the interior point of a cone */
225                void setIntPoint(intvec *iv)
226                {
227                        this->ivIntPt=ivCopy(iv);
228                }
229               
230                /** \brief Return the interior point */
231                intvec *getIntPoint()
232                {
233                        return this->ivIntPt;
234                }
235               
236                void showIntPoint()
237                {
238                        ivIntPt->show();
239                }
240               
241                /** \brief Compute the normals of the cone
242                *
243                * This method computes a representation of the cone in terms of facet normals. It takes an ideal
244                * as its input. Redundancies are automatically removed using cddlib's dd_MatrixCanonicalize.
245                * Other methods for redundancy checkings might be implemented later. See Anders' diss p.44.
246                * Note that in order to use cddlib a 0-th column has to be added to the matrix since cddlib expects
247                * each row to represent an inequality of type const+x1+...+xn <= 0. While computing the normals we come across
248                * the set \f$ \partial\mathcal{G} \f$ which we might store for later use. C.f p71 of journal
249                * As a result of this procedure the pointer facetPtr points to the first facet of the cone.
250                *
251                * Optionally, if the parameter bool compIntPoint is set to TRUE the method will also compute
252                * an interior point of the cone.
253                */
254                void getConeNormals(ideal const &I, bool compIntPoint=FALSE)
255                {
256#ifdef gfan_DEBUG
257                        std::cout << "*** Computing Inequalities... ***" << std::endl;
258#endif         
259                        //All variables go here - except ineq matrix and *v, see below
260                        int lengthGB=IDELEMS(I);        // # of polys in the groebner basis
261                        int pCompCount;                 // # of terms in a poly
262                        poly aktpoly;
263                        int numvar = pVariables;        // # of variables in a polynomial (or ring?)
264                        int leadexp[numvar];            // dirty hack of exp.vects
265                        int aktexp[numvar];
266                        int cols,rows;                  // will contain the dimensions of the ineq matrix - deprecated by
267                        dd_rowrange ddrows;
268                        dd_colrange ddcols;
269                        dd_rowset ddredrows;            // # of redundant rows in ddineq
270                        dd_rowset ddlinset;             // the opposite
271                        dd_rowindex ddnewpos;             // all to make dd_Canonicalize happy
272                        dd_NumberType ddnumb=dd_Integer; //Number type
273                        dd_ErrorType dderr=dd_NoError;  //
274                        // End of var declaration
275#ifdef gfan_DEBUG
276                        cout << "The Groebner basis has " << lengthGB << " elements" << endl;
277                        cout << "The current ring has " << numvar << " variables" << endl;
278#endif
279                        cols = numvar;
280               
281                        //Compute the # inequalities i.e. rows of the matrix
282                        rows=0; //Initialization
283                        for (int ii=0;ii<IDELEMS(I);ii++)
284                        {
285                                aktpoly=(poly)I->m[ii];
286                                rows=rows+pLength(aktpoly)-1;
287                        }
288#ifdef gfan_DEBUG
289                        cout << "rows=" << rows << endl;
290                        cout << "Will create a " << rows << " x " << cols << " matrix to store inequalities" << endl;
291#endif
292                        dd_rowrange aktmatrixrow=0;     // needed to store the diffs of the expvects in the rows of ddineq
293                        dd_set_global_constants();
294                        ddrows=rows;
295                        ddcols=cols;
296                        dd_MatrixPtr ddineq;            //Matrix to store the inequalities                     
297                        ddineq=dd_CreateMatrix(ddrows,ddcols+1); //The first col has to be 0 since cddlib checks for additive consts there
298               
299                        // We loop through each g\in GB and compute the resulting inequalities
300                        for (int i=0; i<IDELEMS(I); i++)
301                        {
302                                aktpoly=(poly)I->m[i];          //get aktpoly as i-th component of I
303                                pCompCount=pLength(aktpoly);    //How many terms does aktpoly consist of?
304                                cout << "Poly No. " << i << " has " << pCompCount << " components" << endl;
305               
306                                int *v=(int *)omAlloc((numvar+1)*sizeof(int));
307                                pGetExpV(aktpoly,v);    //find the exp.vect in v[1],...,v[n], use pNext(p)
308                               
309                                //Store leadexp for aktpoly
310                                for (int kk=0;kk<numvar;kk++)
311                                {
312                                        leadexp[kk]=v[kk+1];
313                                        //Since we need to know the difference of leadexp with the other expvects we do nothing here
314                                        //but compute the diff below
315                                }
316               
317                               
318                                while (pNext(aktpoly)!=NULL) //move to next term until NULL
319                                {
320                                        aktpoly=pNext(aktpoly);
321                                        pSetm(aktpoly);         //doesn't seem to help anything
322                                        pGetExpV(aktpoly,v);
323                                        for (int kk=0;kk<numvar;kk++)
324                                        {
325                                                aktexp[kk]=v[kk+1];
326                                                //ineq[aktmatrixrow][kk]=leadexp[kk]-aktexp[kk];        //dito
327                                                dd_set_si(ddineq->matrix[(dd_rowrange)aktmatrixrow][kk+1],leadexp[kk]-aktexp[kk]); //because of the 1st col being const 0
328                                        }
329                                        aktmatrixrow=aktmatrixrow+1;
330                                }//while
331               
332                        } //for
333               
334                        //Maybe add another row to contain the constraints of the standard simplex?
335
336#ifdef gfan_DEBUG
337                        cout << "The inequality matrix is" << endl;
338                        dd_WriteMatrix(stdout, ddineq);
339#endif
340
341                        // The inequalities are now stored in ddineq
342                        // Next we check for superflous rows
343                        ddredrows = dd_RedundantRows(ddineq, &dderr);
344                        if (dderr!=dd_NoError)                  // did an error occur?
345                        {
346                                dd_WriteErrorMessages(stderr,dderr);    //if so tell us
347                        } else
348                        {
349                                cout << "Redundant rows: ";
350                                set_fwrite(stdout, ddredrows);          //otherwise print the redundant rows
351                        }//if dd_Error
352               
353                        //Remove reduntant rows here!
354                        dd_MatrixCanonicalize(&ddineq, &ddlinset, &ddredrows, &ddnewpos, &dderr);
355                        ddrows = ddineq->rowsize;       //Size of the matrix with redundancies removed
356                        ddcols = ddineq->colsize;
357#ifdef gfan_DEBUG
358                        cout << "Having removed redundancies, the normals now read:" << endl;
359                        dd_WriteMatrix(stdout,ddineq);
360                        cout << "Rows = " << ddrows << endl;
361                        cout << "Cols = " << ddcols << endl;
362#endif
363                       
364                        /*Write the normals into class facet*/
365#ifdef gfan_DEBUG
366                        cout << "Creating list of normals" << endl;
367#endif
368                        /*The pointer *fRoot should be the return value of this function*/
369                        facet *fRoot = new facet();     //instantiate new facet
370                        this->facetPtr = fRoot;         //set variable facetPtr of class gcone to first facet
371                        facet *fAct;                    //instantiate pointer to active facet
372                        fAct = fRoot;                   //Seems to do the trick. fRoot and fAct have to point to the same adress!
373                        std::cout << "fRoot = " << fRoot << ", fAct = " << fAct << endl;
374                        for (int kk = 0; kk<ddrows; kk++)
375                        {
376                                intvec *load = new intvec(numvar);      //intvec to store a single facet normal that will then be stored via setFacetNormal
377                                for (int jj = 1; jj <ddcols; jj++)
378                                {
379#ifdef GMPRATIONAL
380                                        double foo;
381                                        foo = mpq_get_d(ddineq->matrix[kk][jj]);
382/*#ifdef gfan_DEBUG
383                                        std::cout << "fAct is " << foo << " at " << fAct << std::endl;
384#endif*/
385                                        (*load)[jj-1] = (int)foo;               //store typecasted entry at pos jj-1 of load
386#endif
387#ifndef GMPRATIONAL
388                                        double *foo;
389                                        foo = (double*)ddineq->matrix[kk][jj];  //get entry from actual position#endif
390/*#ifdef gfan_DEBUG
391                                        std::cout << "fAct is " << *foo << " at " << fAct << std::endl;
392#endif*/
393                                        (*load)[jj-1] = (int)*foo;              //store typecasted entry at pos jj-1 of load
394#endif //GMPRATIONAL                                   
395                       
396
397                                        //(*load)[jj-1] = (int)foo;             //store typecasted entry at pos jj-1 of load
398                                        //check for flipability here
399                                        if (jj<ddcols)                          //Is this facet NOT the last facet? Writing while instead of if is a really bad idea :)
400                                        {
401                                                //fAct->next = new facet();     //If so: instantiate new facet. Otherwise this->next=NULL due to the constructor                                               
402                                        }
403                                }//for (int jj = 1; jj <ddcols; jj++)
404                                /*Quick'n'dirty hack for flippability*/ 
405                                bool isFlippable;                       
406                                for (int jj = 0; jj<this->numVars; jj++)
407                                {                                       
408                                        intvec *ivCanonical = new intvec(this->numVars);
409                                        (*ivCanonical)[jj]=1;                                   
410                                        if (dotProduct(load,ivCanonical)>=0)
411                                        {
412                                                isFlippable=FALSE;                                             
413                                        }
414                                        else
415                                        {
416                                                isFlippable=TRUE;
417                                        }                                       
418                                        delete ivCanonical;
419                                }//for (int jj = 0; jj<this->numVars; jj++)
420                                if (isFlippable==FALSE)
421                                {
422                                        cout << "Ignoring facet";
423                                        load->show();
424                                        //fAct->next=NULL;
425                                }
426                                else
427                                {       /*Now load should be full and we can call setFacetNormal*/
428                                        fAct->setFacetNormal(load);
429                                        fAct->next = new facet();
430                                        //fAct->printNormal();
431                                        fAct=fAct->next;        //this should definitely not be called in the above while-loop :D
432                                }//if (isFlippable==FALSE)
433                                delete load;
434                        }//for (int kk = 0; kk<ddrows; kk++)
435                        /*
436                        Now we should have a linked list containing the facet normals of those facets that are
437                        -irredundant
438                        -flipable
439                        Adressing is done via *facetPtr
440                        */
441                       
442                        if (compIntPoint==TRUE)
443                        {
444                                intvec *iv = new intvec(this->numVars);
445                                interiorPoint(ddineq, *iv);
446                                this->setIntPoint(iv);  //stores the interior point in gcone::ivIntPt
447                                delete iv;
448                        }
449                       
450                        //Clean up but don't delete the return value! (Whatever it will turn out to be)
451                       
452                        dd_FreeMatrix(ddineq);
453                        set_free(ddredrows);
454                        free(ddnewpos);
455                        set_free(ddlinset);
456                        dd_free_global_constants();
457
458                }//method getConeNormals(ideal I)       
459               
460               
461                /** \brief Compute the Groebner Basis on the other side of a shared facet
462                *
463                * Implements algorithm 4.3.2 from Anders' thesis.
464                * As shown there it is not necessary to compute an interior point. The knowledge of the facet normal
465                * suffices. A term \f$ x^\gamma \f$ of \f$ g \f$ is in \f$  in_\omega(g) \f$ iff \f$ \gamma - leadexp(g)\f$
466                * is parallel to \f$ leadexp(g) \f$
467                * Parallelity is checked using basic linear algebra. See gcone::isParallel.
468                * Other possibilities include computing the rank of the matrix consisting of the vectors in question and
469                * computing an interior point of the facet and taking all terms having the same weight with respect
470                * to this interior point.
471                *\param ideal, facet
472                * Input: a marked,reduced Groebner basis and a facet
473                */
474                void flip(ideal gb, facet *f)           //Compute "the other side"
475                {                       
476                        intvec *fNormal = new intvec(this->numVars);    //facet normal, check for parallelity                   
477                        fNormal = f->getFacetNormal();  //read this->fNormal;
478#ifdef gfan_DEBUG
479                        std::cout << "===" << std::endl;
480                        std::cout << "running gcone::flip" << std::endl;
481                        std::cout << "fNormal=";
482                        fNormal->show();
483                        std::cout << std::endl;
484#endif                         
485                        /*1st step: Compute the initial ideal*/
486                        poly initialFormElement[IDELEMS(gb)];   //array of #polys in GB to store initial form
487                        ideal initialForm=idInit(IDELEMS(gb),this->gcBasis->rank);
488                        poly aktpoly;
489                        intvec *check = new intvec(this->numVars);      //array to store the difference of LE and v
490                       
491                        for (int ii=0;ii<IDELEMS(gb);ii++)
492                        {
493                                aktpoly = (poly)gb->m[ii];                                                             
494                                int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
495                                int *leadExpV=(int *)omAlloc((this->numVars+1)*sizeof(int));
496                                pGetExpV(aktpoly,leadExpV);     //find the leading exponent in leadExpV[1],...,leadExpV[n], use pNext(p)
497                                initialFormElement[ii]=pHead(aktpoly);
498                               
499                                while(pNext(aktpoly)!=NULL)     /*loop trough terms and check for parallelity*/
500                                {
501                                        aktpoly=pNext(aktpoly); //next term
502                                        pSetm(aktpoly);
503                                        pGetExpV(aktpoly,v);           
504                                        /* Convert (int)v into (intvec)check */                 
505                                        for (int jj=0;jj<this->numVars;jj++)
506                                        {
507                                                //cout << "v["<<jj+1<<"]="<<v[jj+1]<<endl;
508                                                //cout << "leadExpV["<<jj+1<<"]="<<leadExpV[jj+1]<<endl;
509                                                (*check)[jj]=v[jj+1]-leadExpV[jj+1];
510                                        }
511#ifdef gfan_DEBUG
512                                        cout << "check=";                       
513                                        check->show();
514                                        cout << endl;
515#endif
516                                        if (isParallel(check,fNormal)) //pass *check when
517                                        {
518                                                cout << "Parallel vector found, adding to initialFormElement" << endl;                 
519                                                initialFormElement[ii] = pAdd(pCopy(initialFormElement[ii]),(poly)pHead(aktpoly));
520                                        }                                               
521                                }//while
522#ifdef gfan_DEBUG
523                                cout << "Initial Form=";                               
524                                pWrite(initialFormElement[ii]);
525                                cout << "---" << endl;
526#endif
527                                /*Now initialFormElement must be added to (ideal)initialForm */
528                                initialForm->m[ii]=initialFormElement[ii];
529                        }//for
530                        //f->setFlipGB(initialForm);    //FIXME PROBABLY WRONG TO STORE HERE SINCE INA!=flibGB                 
531#ifdef gfan_DEBUG
532                        cout << "Initial ideal is: " << endl;
533                        idShow(initialForm);
534                        //f->printFlipGB();
535                        cout << "===" << endl;
536#endif
537                        delete check;
538                       
539                        /*2nd step: lift initial ideal to a GB of the neighbouring cone using minus alpha as weight*/
540                        /*Substep 2.1
541                        compute $G_{-\alpha}(in_v(I))
542                        see journal p. 66
543                        */
544                        ring srcRing=currRing;
545                       
546                        /* copied and modified from ring.cc::rAssureSyzComp */
547                        //ring tmpRing=rCopyAndChangeWeight(srcRing,fNormal);
548                        ring tmpRing=rCopy0(srcRing);
549                        int i=rBlocks(srcRing);
550                        int j;
551                        tmpRing->order=(int *)omAlloc((i+1)*sizeof(int));
552                        /*NOTE This should probably be set, but as of now crashes Singular*/
553                        /*tmpRing->block0=(int *)omAlloc0((i+1)*sizeof(int));
554                        tmpRing->block1=(int *)omAlloc0((i+1)*sizeof(int));*/
555                        tmpRing->wvhdl[0] =( int *)omAlloc((fNormal->length())*sizeof(int)); //found in Singular/ipshell.cc
556                        for(j=i;j>0;j--)
557                        {
558                                tmpRing->order[j]=srcRing->order[j-1];
559                                tmpRing->block0[j]=srcRing->block0[j-1];
560                                tmpRing->block1[j]=srcRing->block1[j-1];
561                                if (srcRing->wvhdl[j-1] != NULL)
562                                {
563                                        tmpRing->wvhdl[j] = (int*) omMemDup(srcRing->wvhdl[j-1]);
564                                }
565                        }
566                        tmpRing->order[0]=ringorder_a;
567                        tmpRing->order[1]=ringorder_dp;
568                        tmpRing->order[2]=ringorder_C;
569                        //tmpRing->wvhdl[0] =( int *)omAlloc((fNormal->length())*sizeof(int)); //found in Singular/ipshell.cc
570                       
571                        for (int ii=0;ii<this->numVars;ii++)
572                        {                               
573                                tmpRing->wvhdl[0][ii]=-(*fNormal)[ii];  //What exactly am I doing here?
574                                //cout << tmpring->wvhdl[0][ii] << endl;
575                        }
576                        rComplete(tmpRing);
577                        rChangeCurrRing(tmpRing);
578                       
579                        rWrite(currRing); cout << endl;
580                        ideal ina;                     
581                        ina=idrCopyR(initialForm,srcRing);                     
582#ifdef gfan_DEBUG
583                        cout << "ina=";
584                        idShow(ina); cout << endl;
585#endif
586                        ideal H;
587                        H=kStd(ina,NULL,isHomog,NULL);  //we know it is homogeneous
588                        idSkipZeroes(H);
589#ifdef gfan_DEBUG
590                        cout << "H="; idShow(H); cout << endl;
591#endif
592                        /*Substep 2.2
593                        do the lifting and mark according to H
594                        */
595                        rChangeCurrRing(srcRing);
596                        ideal srcRing_H;
597                        ideal srcRing_HH;                       
598                        srcRing_H=idrCopyR(H,tmpRing);
599#ifdef gfan_DEBUG
600                        cout << "srcRing_H = ";
601                        idShow(srcRing_H); cout << endl;
602#endif
603                        srcRing_HH=ffG(srcRing_H,this->gcBasis);               
604#ifdef gfan_DEBUG
605                        cout << "srcRing_HH = ";
606                        idShow(srcRing_HH); cout << endl;
607#endif
608                        /*Substep 2.2.1
609                        Mark according to G_-\alpha
610                        Here we have a minimal basis srcRing_HH. In order to turn this basis into a reduced basis
611                        we have to compute an interior point of C(srcRing_HH). For this we need to know the cone
612                        represented by srcRing_HH MARKED ACCORDING TO G_{-\alpha}
613                        Thus we check whether the leading monomials of srcRing_HH and srcRing_H coincide. If not we
614                        compute the difference accordingly
615                        */
616                        dd_set_global_constants();
617                        bool markingsAreCorrect=FALSE;
618                        dd_MatrixPtr intPointMatrix;
619                        int iPMatrixRows=0;
620                        dd_rowrange aktrow=0;                   
621                        for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
622                        {
623                                poly aktpoly=(poly)srcRing_HH->m[ii];
624                                iPMatrixRows = iPMatrixRows+pLength(aktpoly)-1;
625                        }
626                        /* additionally one row for the standard-simplex and another for a row that becomes 0 during
627                        construction of the differences
628                        */
629                        intPointMatrix = dd_CreateMatrix(iPMatrixRows+2,this->numVars+1);
630                        intPointMatrix->numbtype=dd_Integer;    //NOTE: DO NOT REMOVE OR CHANGE TO dd_Rational
631                       
632                        for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
633                        {
634                                markingsAreCorrect=FALSE;       //crucial to initialise here
635                                poly aktpoly=srcRing_HH->m[ii];
636                                /*Comparison of leading monomials is done via exponent vectors*/
637                                for (int jj=0;jj<IDELEMS(H);jj++)
638                                {
639                                        int *src_ExpV = (int *)omAlloc((this->numVars+1)*sizeof(int));
640                                        int *dst_ExpV = (int *)omAlloc((this->numVars+1)*sizeof(int));
641                                        pGetExpV(aktpoly,src_ExpV);
642                                        rChangeCurrRing(tmpRing);       //this ring change is crucial!
643                                        pGetExpV(pCopy(H->m[ii]),dst_ExpV);
644                                        rChangeCurrRing(srcRing);
645                                        bool expVAreEqual=TRUE;
646                                        for (int kk=1;kk<=this->numVars;kk++)
647                                        {
648                                                cout << src_ExpV[kk] << "," << dst_ExpV[kk] << endl;
649                                                if (src_ExpV[kk]!=dst_ExpV[kk])
650                                                {
651                                                        expVAreEqual=FALSE;
652                                                }
653                                        }                                       
654                                        //if (*src_ExpV == *dst_ExpV)
655                                        if (expVAreEqual==TRUE)
656                                        {
657                                                markingsAreCorrect=TRUE; //everything is fine
658                                                cout << "correct markings" << endl;
659                                        }//if (pHead(aktpoly)==pHead(H->m[jj])
660                                        delete src_ExpV;
661                                        delete dst_ExpV;
662                                }//for (int jj=0;jj<IDELEMS(H);jj++)
663                               
664                                int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
665                                int *leadExpV=(int *)omAlloc((this->numVars+1)*sizeof(int));
666                                if (markingsAreCorrect==TRUE)
667                                {
668                                        pGetExpV(aktpoly,leadExpV);
669                                }
670                                else
671                                {
672                                        rChangeCurrRing(tmpRing);
673                                        pGetExpV(pHead(H->m[ii]),leadExpV); //We use H->m[ii] as leading monomial
674                                        rChangeCurrRing(srcRing);
675                                }
676                                /*compute differences of the expvects*/                         
677                                while (pNext(aktpoly)!=NULL)
678                                {
679                                        /*The following if-else-block makes sure the first term (i.e. the wrongly marked term)
680                                        is not omitted when computing the differences*/
681                                        if(markingsAreCorrect==TRUE)
682                                        {
683                                                aktpoly=pNext(aktpoly);
684                                                pGetExpV(aktpoly,v);
685                                        }
686                                        else
687                                        {
688                                                pGetExpV(pHead(aktpoly),v);
689                                                markingsAreCorrect=TRUE;
690                                        }
691
692                                        for (int jj=0;jj<this->numVars;jj++)
693                                        {                               
694                                                /*Store into ddMatrix*/                                                         
695                                                dd_set_si(intPointMatrix->matrix[aktrow][jj+1],leadExpV[jj+1]-v[jj+1]);
696                                        }
697                                        aktrow +=1;
698                                }
699                                delete v;
700                                delete leadExpV;
701                        }//for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
702                        /*Now we add the constraint for the standard simplex*/
703                        /*NOTE:Might actually work without the standard simplex*/
704                        dd_set_si(intPointMatrix->matrix[aktrow][0],-1);
705                        for (int jj=1;jj<=this->numVars;jj++)
706                        {
707                                dd_set_si(intPointMatrix->matrix[aktrow][jj],1);
708                        }
709                        dd_WriteMatrix(stdout,intPointMatrix);
710                        intvec *iv_weight = new intvec(this->numVars);
711                        interiorPoint(intPointMatrix, *iv_weight);      //iv_weight now contains the interior point
712                        dd_FreeMatrix(intPointMatrix);
713                        dd_free_global_constants();
714                       
715                        /*Step 3
716                        turn the minimal basis into a reduced one
717                        */
718                        ring dstRing=rCopy0(srcRing);
719                        i=rBlocks(srcRing);
720                       
721                        dstRing->order=(int *)omAlloc((i+1)*sizeof(int));
722                        for(j=i;j>0;j--)
723                        {
724                                dstRing->order[j]=srcRing->order[j-1];
725                                dstRing->block0[j]=srcRing->block0[j-1];
726                                dstRing->block1[j]=srcRing->block1[j-1];
727                                if (srcRing->wvhdl[j-1] != NULL)
728                                {
729                                        dstRing->wvhdl[j] = (int*) omMemDup(srcRing->wvhdl[j-1]);
730                                }
731                        }
732                        dstRing->order[0]=ringorder_a;
733                        dstRing->order[1]=ringorder_dp;
734                        dstRing->order[2]=ringorder_C;                 
735                        dstRing->wvhdl[0] =( int *)omAlloc((iv_weight->length())*sizeof(int));
736                       
737                        for (int ii=0;ii<this->numVars;ii++)
738                        {                               
739                                dstRing->wvhdl[0][ii]=(*iv_weight)[ii];                         
740                        }
741                        rComplete(dstRing);
742                        rChangeCurrRing(dstRing);
743#ifdef gfan_DEBUG
744                        rWrite(dstRing); cout << endl;
745#endif
746                        ideal dstRing_I;                       
747                        dstRing_I=idrCopyR(srcRing_HH,srcRing);                 
748                        //validOpts<1>=TRUE;
749#ifdef gfan_DEBUG
750                        idShow(dstRing_I);
751#endif                 
752                        BITSET save=test;
753                        test|=Sy_bit(OPT_REDSB);
754                        test|=Sy_bit(6);        //OPT_DEBUG                                     
755                        dstRing_I=kStd(idrCopyR(this->inputIdeal,this->rootRing),NULL,testHomog,NULL);                                 
756                        kInterRed(dstRing_I);
757                        idSkipZeroes(dstRing_I);
758                        test=save;
759                        /*End of step 3 - reduction*/
760                       
761                        f->setFlipGB(dstRing_I);//store the flipped GB
762#ifdef gfan_DEBUG
763                        cout << "Flipped GB is: " << endl;
764                        f->printFlipGB();
765#endif                 
766                }//void flip(ideal gb, facet *f)
767                               
768                /** \brief Compute the remainder of a polynomial by a given ideal
769                *
770                * Compute \f$ f^{\mathcal{G}} \f$
771                * Algorithm is taken from Cox, Little, O'Shea, IVA 2nd Ed. p 62
772                * However, since we are only interested in the remainder, there is no need to
773                * compute the factors \f$ a_i \f$
774                */
775                //NOTE: Should be replaced by kNF or kNF2
776                poly restOfDiv(poly const &f, ideal const &I)
777                {
778                        cout << "Entering restOfDiv" << endl;
779                        poly p=f;
780                        pWrite(p);
781                        //poly r=kCreateZeroPoly(,currRing,currRing);   //The 0-polynomial, hopefully
782                        poly r=NULL;    //The zero polynomial
783                        int ii;
784                        bool divOccured;
785                       
786                        while (p!=NULL)
787                        {
788                                ii=1;
789                                divOccured=FALSE;
790                               
791                                while( (ii<=IDELEMS(I) && (divOccured==FALSE) ))
792                                {                                       
793                                        if (pDivisibleBy(I->m[ii-1],p)) //does LM(I->m[ii]) divide LM(p) ?
794                                        {
795                                                //cout << "TICK 3" << endl;
796                                                poly step1,step2,step3;
797                                                //cout << "dividing "; pWrite(pHead(p));cout << "by ";pWrite(pHead(I->m[ii-1])); cout << endl;
798                                                step1 = pDivideM(pHead(p),pHead(I->m[ii-1]));
799                                                //cout << "LT(p)/LT(f_i)="; pWrite(step1); cout << endl;
800                                                //cout << "TICK 3.1" << endl;
801                                                step2 = ppMult_qq(step1, I->m[ii-1]);
802                                                //cout << "TICK 3.2" << endl;
803                                                step3 = pSub(pCopy(p), step2);
804                                                //p=pSub(p,pMult( pDivide(pHead(p),pHead(I->m[ii])), I->m[ii]));
805                                                //cout << "TICK 4" << endl;
806                                                //pSetm(p);
807                                                pSort(step3); //must be here, otherwise strange behaviour with many +o+o+o+o+ terms
808                                                p=step3;
809                                                pWrite(p);                                             
810                                                divOccured=TRUE;
811                                        }
812                                        else
813                                        {
814                                                ii += 1;
815                                        }//if (pLmDivisibleBy(I->m[ii],p,currRing))
816                                }//while( (ii<IDELEMS(I) && (divOccured==FALSE) ))
817                                if (divOccured==FALSE)
818                                {
819                                        //cout << "TICK 5" << endl;
820                                        r=pAdd(pCopy(r),pHead(p));
821                                        pSetm(r);
822                                        pSort(r);
823                                        //cout << "r="; pWrite(r); cout << endl;
824                                        //cout << "TICK 6" << endl;
825                                        if (pLength(p)!=1)
826                                        {
827                                                p=pSub(pCopy(p),pHead(p));      //Here it may occur that p=0 instead of p=NULL
828                                        }
829                                        else
830                                        {
831                                                p=NULL; //Hack to correct this situation                                               
832                                        }
833                                        //cout << "TICK 7" << endl;
834                                        //cout << "p="; pWrite(p);
835                                }//if (divOccured==FALSE)
836                        }//while (p!=0)
837                        return r;
838                }//poly restOfDiv(poly const &f, ideal const &I)
839               
840                /** \brief Compute \f$ f-f^{\mathcal{G}} \f$
841                */
842                //NOTE: use kNF or kNF2 instead of restOfDivision
843                ideal ffG(ideal const &H, ideal const &G)
844                {
845                        cout << "Entering ffG" << endl;
846                        int size=IDELEMS(H);
847                        ideal res=idInit(size,1);
848                        poly temp1, temp2, temp3;       //polys to temporarily store values for pSub
849                        for (int ii=0;ii<size;ii++)
850                        {
851                                res->m[ii]=restOfDiv(H->m[ii],G);
852                                //res->m[ii]=kNF(H->m[ii],G);
853                                temp1=H->m[ii];
854                                temp2=res->m[ii];                               
855                                temp3=pSub(temp1, temp2);
856                                res->m[ii]=temp3;
857                                //res->m[ii]=pSub(temp1,temp2); //buggy
858                                //pSort(res->m[ii]);
859                                //pSetm(res->m[ii]);
860                                cout << "res->m["<<ii<<"]=";pWrite(res->m[ii]);                                         
861                        }                       
862                        return res;
863                }
864               
865                /** \brief Compute a Groebner Basis
866                *
867                * Computes the Groebner basis and stores the result in gcone::gcBasis
868                *\param ideal
869                *\return void
870                */
871                void getGB(ideal const &inputIdeal)
872                {
873                        ideal gb;
874                        gb=kStd(inputIdeal,NULL,testHomog,NULL);
875                        idSkipZeroes(gb);
876                        this->gcBasis=gb;       //write the GB into gcBasis
877                }//void getGB
878               
879                /** \brief The Generic Groebner Walk due to FJLT
880                * Needed for computing the search facet
881                */
882                ideal GenGrbWlk(ideal, ideal)
883                {
884                }//GGW
885
886
887                /** \brief Compute the dot product of two intvecs
888                *
889                */
890                int dotProduct(intvec const &iva, intvec const &ivb)                           
891                {
892                        //intvec iva=a;
893                        //intvec ivb=b;
894                        int res=0;
895                        for (int i=0;i<this->numVars;i++)
896                        {
897                                res = res+(iva[i]*ivb[i]);
898                        }
899                        return res;
900                }//int dotProduct
901
902                /** \brief Check whether two intvecs are parallel
903                *
904                * \f$ \alpha\parallel\beta\Leftrightarrow\langle\alpha,\beta\rangle^2=\langle\alpha,\alpha\rangle\langle\beta,\beta\rangle \f$
905                */
906                bool isParallel(intvec const &a, intvec const &b)
907                {                       
908                        int lhs,rhs;
909                        lhs=dotProduct(a,b)*dotProduct(a,b);
910                        rhs=dotProduct(a,a)*dotProduct(b,b);
911                        cout << "LHS="<<lhs<<", RHS="<<rhs<<endl;
912                        if (lhs==rhs)
913                        {
914                                return TRUE;
915                        }
916                        else
917                        {
918                                return FALSE;
919                        }
920                }//bool isParallel
921               
922                /** \brief Compute an interior point of a given cone
923                */
924                void interiorPoint(dd_MatrixPtr const &M, intvec &iv) //no const &M here since we want to remove redundant rows
925                {
926                        dd_LPPtr lp,lpInt;
927                        dd_ErrorType err=dd_NoError;
928                        dd_LPSolverType solver=dd_DualSimplex;
929                        dd_LPSolutionPtr lpSol=NULL;
930                        dd_rowset ddlinset,ddredrows;   //needed for dd_FindRelativeInterior
931                        dd_rowindex ddnewpos;
932                        dd_NumberType numb;     
933                        //M->representation=dd_Inequality;
934                        //M->objective-dd_LPMin;  //Not sure whether this is needed
935                        dd_set_si(M->rowvec[0],1);dd_set_si(M->rowvec[1],1);dd_set_si(M->rowvec[2],1);
936                        //cout << "TICK 1" << endl;
937                                               
938                        //dd_MatrixCanonicalize(&M, &ddlinset, &ddredrows, &ddnewpos, &err);
939                        //if (err!=dd_NoError){cout << "Error during dd_MatrixCanonicalize" << endl;}
940                        //cout << "Tick 2" << endl;
941                        //dd_WriteMatrix(stdout,M);
942                       
943                        lp=dd_Matrix2LP(M, &err);
944                        if (err!=dd_NoError){cout << "Error during dd_Matrix2LP in gcone::interiorPoint" << endl;}                     
945                        if (lp==NULL){cout << "LP is NULL" << endl;}
946                        dd_WriteLP(stdout,lp);
947                        //cout << "Tick 3" << endl;
948                                               
949                        lpInt=dd_MakeLPforInteriorFinding(lp);
950                        if (err!=dd_NoError){cout << "Error during dd_MakeLPForInteriorFinding in gcone::interiorPoint" << endl;}
951                        dd_WriteLP(stdout,lpInt);
952                        //cout << "Tick 4" << endl;
953                       
954                        dd_FindRelativeInterior(M,&ddlinset,&ddredrows,&lpSol,&err);
955                        if (err!=dd_NoError)
956                        {
957                                cout << "Error during dd_FindRelativeInterior in gcone::interiorPoint" << endl;
958                                dd_WriteErrorMessages(stdout, err);
959                        }
960                       
961                        //dd_LPSolve(lpInt,solver,&err);        //This will not result in a point from the relative interior
962                        if (err!=dd_NoError){cout << "Error during dd_LPSolve" << endl;}
963                        //cout << "Tick 5" << endl;
964                                                                       
965                        //lpSol=dd_CopyLPSolution(lpInt);
966                        if (err!=dd_NoError){cout << "Error during dd_CopyLPSolution" << endl;}                 
967                        //cout << "Tick 6" << endl;
968#ifdef gfan_DEBUG
969                        cout << "Interior point: ";
970#endif
971                        for (int ii=1; ii<(lpSol->d)-1;ii++)
972                        {
973#ifdef gfan_DEBUG
974                                dd_WriteNumber(stdout,lpSol->sol[ii]);
975#endif
976                                /* NOTE This works only as long as gmp returns fractions with the same denominator*/
977                                (iv)[ii-1]=(int)mpz_get_d(mpq_numref(lpSol->sol[ii]));  //looks evil, but does the trick
978                        }
979                        dd_FreeLPSolution(lpSol);
980                        dd_FreeLPData(lpInt);
981                        dd_FreeLPData(lp);
982                        set_free(ddlinset);
983                        set_free(ddredrows);                   
984                       
985                }//void interiorPoint(dd_MatrixPtr const &M)
986               
987                ring rCopyAndChangeWeight(ring const r, intvec const *ivw)                             
988                {
989                        ring res=rCopy0(r, FALSE, FALSE);
990                        int i=rBlocks(r);
991                        int j;
992
993                        res->order=(int *)omAlloc((i+1)*sizeof(int));
994                        /*res->block0=(int *)omAlloc0((i+1)*sizeof(int));
995                        res->block1=(int *)omAlloc0((i+1)*sizeof(int));
996                        int ** wvhdl =(int **)omAlloc0((i+1)*sizeof(int**));*/
997                        for(j=i;j>0;j--)
998                        {
999                                res->order[j]=r->order[j-1];
1000                                res->block0[j]=r->block0[j-1];
1001                                res->block1[j]=r->block1[j-1];
1002                                if (r->wvhdl[j-1] != NULL)
1003                                {
1004                                        res->wvhdl[j] = (int*) omMemDup(r->wvhdl[j-1]);
1005                                }
1006                        }
1007                        res->order[0]=ringorder_a;
1008                        res->order[1]=ringorder_dp;
1009                        res->order[2]=ringorder_C;
1010                        //res->wvhdl = wvhdl;
1011                       
1012                        res->wvhdl[0] =( int *)omAlloc((ivw->length())*sizeof(int));
1013                        for (int ii=0;ii<this->numVars;ii++)
1014                        {                               
1015                                res->wvhdl[0][ii]=(*ivw)[ii];                           
1016                        }                       
1017                       
1018                        rComplete(res);
1019                        return res;
1020                }//rCopyAndChange
1021               
1022                /**
1023                * Determines whether a given facet of a cone is the search facet of a neighbouring cone
1024                *
1025                */
1026                bool isSearchFacet(gcone &tmpcone, facet *testfacet)
1027                {                       
1028                        ring actRing=currRing;
1029                       
1030                        facet *fMin=new facet();        //Pointer to the "minimal" facet
1031                        facet *fAct;
1032                        fMin = testfacet;
1033                        fAct = fMin;
1034                       
1035                        rChangeCurrRing(this->rootRing);
1036                        poly p=NULL;
1037                        poly q=NULL;
1038                        intvec *p_weight = new intvec(this->numVars);                   
1039                        intvec *q_weight = new intvec(this->numVars);
1040                        intvec *sigma = new intvec(this->numVars);
1041                        sigma=tmpcone.getIntPoint();
1042                        int *u=(int *)omAlloc((this->numVars+1)*sizeof(int));
1043                        int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
1044                        int weight1,weight2;
1045                        while(tmpcone.facetPtr->next!=NULL)
1046                        {
1047                                /* Get alpha_i and alpha_{i+1} */
1048                                p_weight=fMin->getFacetNormal();
1049                                q_weight=fMin->next->getFacetNormal();
1050                               
1051                                /*Compute the dot product of sigma and alpha_{i,j}*/
1052                                weight1=dotProduct(sigma,p_weight);
1053                                weight2=dotProduct(sigma,q_weight);
1054                               
1055                                /*Adjust alpha_i and alpha_i+1 accordingly*/
1056                                for(int ii=1;ii<=this->numVars;ii++)
1057                                {
1058                                        /*p_weight[ii]=weight1*(*p_weight)[ii];
1059                                        q_weight[ii]=weight2*(*q_weight)[ii];*/
1060                                        u[ii]=weight1*(*p_weight)[ii];
1061                                        v[ii]=weight2*(*q_weight)[ii];
1062                                }
1063                               
1064                                /*Now p_weight and q_weight need to be compared as exponent vectors*/
1065                                pSetExpV(p,u);
1066                                pSetExpV(q,v);
1067                                /*We want to check whether x^p < x^q
1068                                => want to check for return value 1 */
1069                                if (pLmCmp(p,q)==1)     //i.e. x^q is smaller
1070                                {
1071                                        fMin=fMin->next;
1072                                        fAct=fMin;
1073                                }
1074                                else
1075                                {
1076                                        fAct=fAct->next;
1077                                }
1078                        }//while(tmpcone.facetPtr->next!=NULL)
1079                        rChangeCurrRing(actRing);
1080                }//bool isSearchFacet
1081               
1082                void reverseSearch(gcone gcAct) //no const possible here since we call gcAct->flip
1083                {
1084                        facet *fAct=new facet();
1085                        fAct = gcAct.facetPtr;                 
1086                       
1087                        while(fAct->next!=NULL)
1088                        {
1089                                gcAct.flip(gcAct.gcBasis,gcAct.facetPtr);
1090                                gcone *gcTmp = new gcone(gcAct);
1091                                idShow(gcTmp->gcBasis);
1092                                gcTmp->getConeNormals(gcTmp->gcBasis, TRUE);
1093                                gcTmp->showIntPoint();
1094                                /*recursive part goes gere*/
1095                                if (isSearchFacet(gcTmp,gcAct.facetPtr))
1096                                {
1097                                        gcAct.next=gcTmp;
1098                                        reverseSearch(*gcTmp);
1099                                }
1100                                else
1101                                {
1102                                        delete gcTmp;
1103                                        /*NOTE remove fAct from linked list. It's no longer needed*/
1104                                }
1105                                /*recursion ends*/
1106                                fAct = fAct->next;             
1107                        }//while(fAct->next!=NULL)
1108                }//reverseSearch
1109};//class gcone
1110
1111ideal gfan(ideal inputIdeal)
1112{
1113        int numvar = pVariables; 
1114       
1115        #ifdef gfan_DEBUG
1116        cout << "Now in subroutine gfan" << endl;
1117        #endif
1118        ring inputRing=currRing;        // The ring the user entered
1119        ring rootRing;                  // The ring associated to the target ordering
1120        ideal res;     
1121        facet *fRoot;
1122       
1123        /*
1124        1. Select target order, say dp.
1125        2. Compute GB of inputIdeal wrt target order -> newRing, setCurrRing etc...
1126        3. getConeNormals
1127        */
1128       
1129        /* Construct a new ring which will serve as our root
1130        Does not yet work as expected. Will work fine with order dp,Dp but otherwise hangs in getGB
1131        resolved 07.04.2009 MM
1132        */
1133        rootRing=rCopy0(currRing);
1134        rootRing->order[0]=ringorder_lp;
1135        //NOTE: Build ring accordiing to rCopyAndChangeWeight
1136        /*rootRing->order[0]=ringorder_a;
1137        rootRing->order[1]=ringorder_lp;
1138        rootRing->wvhdl[0] =( int *)omAlloc(numvar*sizeof(int));
1139        rootRing->wvhdl[0][1]=1;
1140        rootRing->wvhdl[0][2]=1;*/
1141        rComplete(rootRing);
1142        rChangeCurrRing(rootRing);
1143       
1144        /* Fetch the inputIdeal into our rootRing */
1145        map theMap=(map)idMaxIdeal(1);  //evil hack!
1146        theMap->preimage=NULL;  //neccessary?
1147        ideal rootIdeal;
1148        rootIdeal=fast_map(inputIdeal,inputRing,(ideal)theMap, currRing);
1149#ifdef gfan_DEBUG
1150        cout << "Root ideal is " << endl;
1151        idShow(rootIdeal);
1152        cout << "The root ring is " << endl;
1153        rWrite(rootRing);
1154        cout << endl;
1155#endif 
1156       
1157        //gcone *gcRoot = new gcone();  //Instantiate the sink
1158        gcone *gcRoot = new gcone(rootRing,rootIdeal);
1159        gcone *gcAct;
1160        gcAct = gcRoot;
1161        gcAct->numVars=pVariables;
1162        gcAct->getGB(rootIdeal);        //sets gcone::gcBasis
1163        idShow(gcAct->gcBasis);
1164        gcAct->getConeNormals(gcAct->gcBasis);  //hopefully compute the normals
1165        //gcAct->flip(gcAct->gcBasis,gcAct->facetPtr);
1166        /*Now it is time to compute the search facets, respectively start the reverse search.
1167        But since we are in the root all facets should be search facets. IS THIS TRUE?
1168        NOTE: Check for flippability is not very sophisticated
1169        */
1170        /*facet *fAct=new facet();
1171        fAct=gcAct->facetPtr;
1172        while(fAct->next!=NULL)
1173        {
1174                gcAct->flip(gcAct->gcBasis,gcAct->facetPtr);
1175                gcone *gcTmp = new gcone(*gcAct);
1176                idShow(gcTmp->gcBasis);
1177                gcTmp->getConeNormals(gcTmp->gcBasis, TRUE);
1178                gcTmp->getIntPoint();
1179                fAct = fAct->next;             
1180        }*/
1181        gcAct->reverseSearch(*gcAct);
1182        /*As of now extra.cc expects gfan to return type ideal. Probably this will change in near future.
1183        The return type will then be of type LIST_CMD
1184        Assume gfan has finished, thus we have enumerated all the cones
1185        Create an array of size of #cones. Let each entry in the array contain a pointer to the respective
1186        Groebner Basis and merge this somehow with LIST_CMD
1187        => Count the cones!
1188        */
1189        rChangeCurrRing(rootRing);
1190        //res=gcAct->gcBasis;
1191        res=gcRoot->gcBasis;   
1192        return res;
1193        //return GBlist;
1194}
1195/*
1196Since gfan.cc is #included from extra.cc there must not be a int main(){} here
1197*/
1198#endif
Note: See TracBrowser for help on using the repository browser.