source: git/kernel/gfan.cc @ 3b45cf

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