source: git/kernel/gfan.cc @ c90b43

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