source: git/kernel/gfan.cc @ 63a2f8

spielwiese
Last change on this file since 63a2f8 was 63a2f8, checked in by Martin Monerjan, 14 years ago
Cleanup in destructors gcone::setBaseRing Bugfix in getConeNormals Removed one nDelete(&nCoeffNom) (Thomas' example) Hack for guessing memory usage in the local part git-svn-id: file:///usr/local/Singular/svn/trunk@12681 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 123.5 KB
Line 
1/*
2Compute the Groebner fan of an ideal
3$Author: monerjan $
4$Date: 2009/11/03 06:57:32 $
5$Header: /usr/local/Singular/cvsroot/kernel/gfan.cc,v 1.103 2009/11/03 06:57:32 monerjan Exp $
6$Id$
7*/
8
9#include "mod2.h"
10
11#ifdef HAVE_GFAN
12#include "options.h"
13#include "kstd1.h"
14#include "kutil.h"      //ksCreateSpoly
15// #include "int64vec.h"
16#include "polys.h"
17#include "ideals.h"
18#include "kmatrix.h"
19#include "GMPrat.h"
20//#include "fast_maps.h"        //Mapping of ideals
21// #include "maps.h"
22// #include "ring.h"    //apparently not needed
23// #include "structs.h"
24#include "../Singular/lists.h"
25#include "prCopy.h"     //Needed for idrCopyR
26#include "stairc.h"     //For Hilbert series
27// #include <bitset>
28#include <fstream>      //read-write cones to files
29// #include <gmp.h>
30#include <string>
31#include <sstream>
32// #include <time.h>
33#include <stdlib.h>
34//#include <gmpxx.h>
35// #include <vector>
36#include <assert.h>
37
38
39/*DO NOT REMOVE THIS*/
40#ifndef GMPRATIONAL
41#define GMPRATIONAL
42#endif
43
44//Hacks for different working places
45#define p800
46
47#ifdef UNI
48#include "/users/urmel/alggeom/monerjan/cddlib/include/setoper.h" //Support for cddlib. Dirty hack
49#include "/users/urmel/alggeom/monerjan/cddlib/include/cdd.h"
50#endif
51
52#ifdef HOME
53#include "/home/momo/studium/diplomarbeit/cddlib/include/setoper.h"
54#include "/home/momo/studium/diplomarbeit/cddlib/include/cdd.h"
55#endif
56
57#ifdef ITWM
58#include "/u/slg/monerjan/cddlib/include/setoper.h"
59#include "/u/slg/monerjan/cddlib/include/cdd.h"
60#include "/u/slg/monerjan/cddlib/include/cddmp.h"
61#endif
62
63#ifdef p800
64#include "../../cddlib/include/setoper.h"
65#include "../../cddlib/include/cdd.h"
66#include "../../cddlib/include/cddmp.h"
67#endif
68
69#ifndef gfan_DEBUG
70// #define gfan_DEBUG
71#ifndef gfan_DEBUGLEVEL
72#define gfan_DEBUGLEVEL 1
73#endif
74#endif
75
76//NOTE Defining this will slow things down!
77//Only good for very coarse profiling
78//#define gfanp
79#ifdef gfanp
80#include <sys/time.h>
81#include <iostream>
82#endif
83
84#ifndef SHALLOW
85#define SHALLOW
86#endif
87
88#include <gfan.h>
89using namespace std;
90
91#define ivIsStrictlyPositive iv64isStrictlyPositive
92
93/**
94*\brief Class facet
95*       Implements the facet structure as a linked list
96*
97*/
98               
99/** \brief The default constructor for facets
100*/
101facet::facet()                 
102{
103        // Pointer to next facet.  */
104        /* Defaults to NULL. This way there is no need to check explicitly */
105        this->fNormal=NULL;
106        this->interiorPoint=NULL;               
107        this->UCN=0;
108        this->codim2Ptr=NULL;
109        this->codim=1;          //default for (codim-1)-facets
110        this->numCodim2Facets=0;
111        this->numRays=0;
112        this->flipGB=NULL;
113        this->next=NULL;
114        this->prev=NULL;               
115        this->flipRing=NULL;    //the ring on the other side
116        this->isFlippable=FALSE;
117}
118               
119/** \brief Constructor for facets of codim == 2
120* Note that as of now the code of the constructors is only for facets and codim2-faces. One
121* could easily change that by renaming numCodim2Facets to numCodimNminusOneFacets or similar
122*/
123facet::facet(const int &n)
124{
125        this->fNormal=NULL;
126        this->interiorPoint=NULL;                       
127        this->UCN=0;
128        this->codim2Ptr=NULL;
129        if(n==2)
130        {
131                this->codim=n;
132        }//NOTE Handle exception here!                 
133        this->numCodim2Facets=0;
134        this->numRays=0;
135        this->flipGB=NULL;
136        this->next=NULL;
137        this->prev=NULL;
138        this->flipRing=NULL;
139        this->isFlippable=FALSE;
140}
141               
142/** \brief The copy constructor
143* By default only copies the fNormal, f2Normals and UCN
144*/
145facet::facet(const facet& f)
146{
147        this->fNormal=ivCopy(f.fNormal);
148        this->UCN=f.UCN;
149        this->isFlippable=f.isFlippable;
150        //Needed for flip2
151        //NOTE ONLY REFERENCE
152        this->interiorPoint=ivCopy(f.interiorPoint);//only referencing is prolly not the best thing to do in a copy constructor
153        facet* f2Copy;
154        f2Copy=f.codim2Ptr;
155        facet* f2Act;
156        f2Act=this->codim2Ptr;
157        while(f2Copy!=NULL)
158        {
159                if(f2Act==NULL || f2Act==(facet*)0xfefefefefefefefe)
160                {
161                        f2Act=new facet(2);
162                        this->codim2Ptr=f2Act;                 
163                }
164                else
165                {
166                        facet* marker;
167                        marker = f2Act;
168                        f2Act->next = new facet(2);
169                        f2Act = f2Act->next;
170                        f2Act->prev = marker;
171                }
172                intvec *f2Normal;
173                f2Normal = f2Copy->getFacetNormal();
174//              f2Act->setFacetNormal(f2Copy->getFacetNormal());
175                f2Act->setFacetNormal(f2Normal);
176                delete f2Normal;
177                f2Act->setUCN(f2Copy->getUCN());
178                f2Copy = f2Copy->next;
179        }       
180}
181
182/** \brief Shallow copy constructor for facets
183* We only need the interior point for equality testing
184*/
185facet* facet::shallowCopy(const facet& f)
186{
187        facet *res = new facet();
188        res->fNormal=(intvec * const)f.fNormal;
189        res->UCN=f.UCN;
190        res->isFlippable=f.isFlippable;
191        res->interiorPoint=(intvec * const)f.interiorPoint;
192        res->codim2Ptr=(facet * const)f.codim2Ptr;
193        res->prev=NULL;
194        res->next=NULL;
195        res->flipGB=NULL;
196        res->flipRing=NULL;
197        return res;
198}
199
200void facet::shallowDelete()
201{
202#ifdef gfan_DEBUG
203//      printf("shallowdel@UCN %i\n", this->getUCN());
204#endif
205        this->fNormal=NULL;
206//      this->UCN=0;
207        this->interiorPoint=NULL;
208        this->codim2Ptr=NULL;
209        this->prev=NULL;
210        this->next=NULL;
211        this->flipGB=NULL;
212        this->flipRing=NULL;
213        assert(this->fNormal==NULL);   
214//      delete(this);
215}
216               
217/** The default destructor */
218facet::~facet()
219{
220#ifdef gfan_DEBUG
221//      printf("~facet@UCN %i\n",this->getUCN());
222#endif
223        if(this->fNormal!=NULL)
224                delete this->fNormal;
225        if(this->interiorPoint!=NULL)
226                delete this->interiorPoint;
227        /* Cleanup the codim2-structure */
228//      if(this->codim==2)
229//      {
230//              facet *codim2Ptr;
231//              codim2Ptr = this->codim2Ptr;
232//              while(codim2Ptr!=NULL)
233//              {
234//                      if(codim2Ptr->fNormal!=NULL)
235//                      {
236//                              delete codim2Ptr->fNormal;//NOTE Do not want this anymore since the rays are now in gcone!
237//                              codim2Ptr = codim2Ptr->next;
238//                      }
239//              }
240//      }
241        //The rays are stored in the cone!
242        if(this->flipGB!=NULL)
243                idDelete((ideal *)&this->flipGB);
244//      if(this->flipRing!=NULL && this->flipRing->idroot!=(idhdl)0xfbfbfbfbfbfbfbfb)
245//              rDelete(this->flipRing); //See vol II/134
246//      this->flipRing=NULL;
247        this->prev=NULL;
248        this->next=NULL;
249}
250               
251inline const intvec *facet::getRef2FacetNormal() const
252{
253        return(this->fNormal);
254}       
255
256/** Equality check for facets based on unique interior points*/
257static bool areEqual2(facet* f, facet *g)
258{
259#ifdef gfanp
260        gcone::numberOfFacetChecks++;
261        timeval start, end;
262        gettimeofday(&start, 0);
263#endif
264        bool res = TRUE;
265        const intvec *fIntP = f->getRef2InteriorPoint();
266        const intvec *gIntP = g->getRef2InteriorPoint();
267        for(int ii=0;ii<pVariables;ii++)
268        {
269                if( (*fIntP)[ii] != (*gIntP)[ii] )
270                {
271                        res=FALSE;
272                        break;
273                }
274        }
275#ifdef gfanp
276        gettimeofday(&end, 0);
277        gcone::t_areEqual += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
278#endif 
279        return res;
280}
281
282/** \brief Comparison of facets
283 * called from enqueueNewFacets
284* The facet normals are primitve vectors since we call gcone::normalize() on all cones.
285* Hence it should suffice to check whether facet normal f equals minus facet normal s.
286* If so we check the extremal rays
287*
288* BEWARE: It would be better to use const intvec* but that will lead to call something like
289* int foo=((intvec*)f2Normal)->compare((intvec*)s2Normal) resulting in much higher memory usage
290*/
291static bool areEqual(facet *f, facet *s)
292{
293#ifdef gfanp
294        gcone::numberOfFacetChecks++;
295        timeval start, end;
296        gettimeofday(&start, 0);
297#endif
298        bool res = TRUE;
299        int notParallelCtr=0;
300        int ctr=0;
301        const intvec* fNormal; //No new since ivCopy and therefore getFacetNormal return a new
302        const intvec* sNormal;
303        fNormal = f->getRef2FacetNormal();//->getFacetNormal();
304        sNormal = s->getRef2FacetNormal();//->getFacetNormal();
305        //Do not need parallelity. Too time consuming
306//      if(!isParallel(*fNormal,*sNormal))
307//      if(fNormal->compare(ivNeg(sNormal))!=0)//This results in a Mandelbug
308 //             notParallelCtr++;
309//      else//parallelity, so we check the codim2-facets
310        intvec *fNRef=const_cast<intvec*>(fNormal);
311        intvec *sNRef=const_cast<intvec*>(sNormal);
312//      if(isParallel(*fNormal,*sNormal))       
313        if(isParallel(*fNRef,*sNRef))
314//      if(fNormal->compare((sNormal))!=0)//Behold! Teh definitive Mandelbug
315        {
316                facet* f2Act;
317                facet* s2Act;
318                f2Act = f->codim2Ptr;           
319                ctr=0;
320                while(f2Act!=NULL)
321                {
322                        const intvec* f2Normal;
323                        f2Normal = f2Act->getRef2FacetNormal();//->getFacetNormal();
324//                      intvec *f2Ref=const_cast<intvec*>(f2Normal);
325                        s2Act = s->codim2Ptr;
326                        while(s2Act!=NULL)
327                        {
328                                const intvec* s2Normal;
329                                s2Normal = s2Act->getRef2FacetNormal();//->getFacetNormal();
330//                              bool foo=areEqual(f2Normal,s2Normal);
331//                              intvec *s2Ref=const_cast<intvec*>(s2Normal);
332                                int foo=f2Normal->compare(s2Normal);
333                                if(foo==0)
334                                        ctr++;
335                                s2Act = s2Act->next;
336//                              delete s2Normal;
337                        }
338//                      delete f2Normal;
339                        f2Act = f2Act->next;
340                }               
341        }
342//      delete fNormal;
343//      delete sNormal;
344        if(ctr==f->numCodim2Facets)
345                res=TRUE;
346        else
347        {
348#ifdef gfanp
349                gcone::parallelButNotEqual++;
350#endif
351                res=FALSE;
352        }
353#ifdef gfanp
354        gettimeofday(&end, 0);
355        gcone::t_areEqual += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
356#endif
357        return res;
358//      intvec *foo=ivNeg(sNormal);
359//      if(fNormal->compare(foo)!=0) //facet normals
360//      {
361//              delete foo;
362//              res=FALSE;
363//      }
364//      else
365//      {
366//              facet* f2Act;
367//              facet* s2Act;
368//              f2Act = f->codim2Ptr;           
369//              ctr=0;
370//              while(f2Act!=NULL)
371//              {
372//                      intvec* f2Normal;
373//                      f2Normal = f2Act->getFacetNormal();
374//                      s2Act = s->codim2Ptr;
375//                      while(s2Act!=NULL)
376//                      {
377//                              intvec* s2Normal;
378//                              s2Normal = s2Act->getFacetNormal();
379// //                           bool foo=areEqual(f2Normal,s2Normal);
380//                              int foo=f2Normal->compare(s2Normal);
381//                              if(foo==0)
382//                                      ctr++;
383//                              s2Act = s2Act->next;
384//                              delete s2Normal;
385//                      }
386//                      delete f2Normal;
387//                      f2Act = f2Act->next;
388//              }
389//      }               
390//      delete fNormal;
391//      delete sNormal;
392//      if(ctr==f->numCodim2Facets)
393//              res=TRUE;
394//      return res;
395}       
396               
397/** Stores the facet normal \param intvec*/
398inline void facet::setFacetNormal(intvec *iv)
399{
400        if(this->fNormal!=NULL)
401                delete this->fNormal;
402        this->fNormal = ivCopy(iv);                     
403}
404               
405/** Hopefully returns the facet normal
406* Mind: ivCopy returns a new intvec, so use this in the following way:
407* intvec *iv;
408* iv = this->getFacetNormal();
409* [...]
410* delete(iv);
411*/
412inline intvec *facet::getFacetNormal() const
413{                               
414        return ivCopy(this->fNormal);
415//      return this->fNormal;
416}
417
418/** Method to print the facet normal*/
419inline void facet::printNormal() const
420{
421        fNormal->show();
422}
423               
424/** Store the flipped GB*/
425inline void facet::setFlipGB(ideal I)
426{
427        this->flipGB=idCopy(I);
428}
429               
430/** Returns a pointer to the flipped GB
431Seems not be used
432Anyhow idCopy would make sense here.
433*/
434inline ideal facet::getFlipGB()
435{
436        return this->flipGB;
437}
438               
439/** Print the flipped GB*/
440inline void facet::printFlipGB()
441{
442#ifndef NDEBUG
443        idShow(this->flipGB);
444#endif
445}
446               
447/** Set the UCN */
448inline void facet::setUCN(int n)
449{
450        this->UCN=n;
451}
452               
453/** \brief Get the UCN
454* Returns the UCN iff this != NULL, else -1
455*/
456inline int facet::getUCN()
457{
458#ifndef NDEBUG
459  #if SIZEOF_LONG==8
460        if((this!=NULL && this!=(facet * const)0xfbfbfbfbfbfbfbfb))
461  #elif SIZEOF_LONG==4
462        if((this!=NULL && this!=(facet * const)0xfbfbfbfb))
463  #endif
464#endif
465#ifdef NDEBUG
466        if(this!=NULL)
467#endif                 
468                return this->UCN;
469        else
470                return -1;
471}
472               
473/** Store an interior point of the facet */
474inline void facet::setInteriorPoint(intvec *iv)
475{
476        if(this->interiorPoint!=NULL)
477                delete this->interiorPoint;
478        this->interiorPoint = ivCopy(iv);
479}
480               
481/** Returns a pointer to this->interiorPoint
482* MIND: ivCopy returns a new intvec
483* @see facet::getFacetNormal
484*/
485inline intvec *facet::getInteriorPoint()
486{
487        return ivCopy(this->interiorPoint);
488}
489
490inline const intvec *facet::getRef2InteriorPoint()
491{
492        return (this->interiorPoint);
493}
494               
495/** \brief Debugging function
496* prints the facet normal an all (codim-2)-facets that belong to it
497*/
498volatile void facet::fDebugPrint()
499{                       
500        facet *codim2Act;                       
501        codim2Act = this->codim2Ptr;
502        intvec *fNormal;
503        fNormal = this->getFacetNormal();       
504        printf("=======================\n");
505        printf("Facet normal = (");fNormal->show(1,1);printf(")\n");
506        printf("-----------------------\n");
507        printf("Codim2 facets:\n");
508        while(codim2Act!=NULL)
509        {
510                intvec *f2Normal;
511                f2Normal = codim2Act->getFacetNormal();
512                printf("(");f2Normal->show(1,0);printf(")\n");
513                codim2Act = codim2Act->next;
514                delete f2Normal;
515        }
516        printf("=======================\n");
517        delete fNormal; 
518}               
519               
520//friend class gcone;   //Bad style
521
522
523/**
524*\brief Implements the cone structure
525*
526* A cone is represented by a linked list of facet normals
527* @see facet
528*/
529
530
531/** \brief Default constructor.
532 *
533 * Initialises this->next=NULL and this->facetPtr=NULL
534 */
535gcone::gcone()
536{
537        this->next=NULL;
538        this->prev=NULL;
539        this->facetPtr=NULL;    //maybe this->facetPtr = new facet();                   
540        this->baseRing=currRing;
541        this->counter++;
542        this->UCN=this->counter;                       
543        this->numFacets=0;
544        this->ivIntPt=NULL;
545        this->gcRays=NULL;
546}
547               
548/** \brief Constructor with ring and ideal
549 *
550 * This constructor takes the root ring and the root ideal as parameters and stores
551 * them in the private members gcone::rootRing and gcone::inputIdeal
552 * This constructor is only called once in the computation of the Gröbner fan,
553 * namely for the very first cone. Therefore pred is set to 1.
554 * Might set it to this->UCN though...
555 * Since knowledge of the root ring is only needed when using reverse search,
556 * this constructor is not needed when using the "second" method
557*/
558gcone::gcone(ring r, ideal I)
559{
560        this->next=NULL;
561        this->prev=NULL;
562        this->facetPtr=NULL;                   
563        this->inputIdeal=I;
564        this->baseRing=currRing;
565        this->counter++;
566        this->UCN=this->counter;
567        this->pred=1;
568        this->numFacets=0;
569        this->ivIntPt=NULL;
570        this->gcRays=NULL;
571}
572               
573/** \brief Copy constructor
574 *
575 * Copies a cone, sets this->gcBasis to the flipped GB
576 * Call this only after a successful call to gcone::flip which sets facet::flipGB
577*/             
578gcone::gcone(const gcone& gc, const facet &f)
579{
580        this->next=NULL;
581//      this->prev=(gcone *)&gc; //comment in to get a tree
582        this->prev=NULL;
583        this->numVars=gc.numVars;                                               
584        this->counter++;
585        this->UCN=this->counter;
586        this->pred=gc.UCN;
587        this->facetPtr=NULL;
588        this->gcBasis=idrCopyR(f.flipGB, f.flipRing);
589//      this->inputIdeal=idCopy(this->gcBasis);
590        this->baseRing=rCopy(f.flipRing);
591        this->numFacets=0;
592        this->ivIntPt=NULL;
593        this->gcRays=NULL;
594}
595               
596/** \brief Default destructor
597*/
598gcone::~gcone()
599{
600#ifndef NDEBUG
601  #if SIZEOF_LONG==8
602        if( ( this->gcBasis!=(ideal)(0xfbfbfbfbfbfbfbfb) ) && (this->gcBasis!=NULL) )
603                idDelete((ideal*)&this->gcBasis);
604  #elif SIZEOF_LONG!=8
605        if(this->gcBasis!=(ideal)0xfbfbfbfb)
606                idDelete((ideal *)&this->gcBasis);
607  #endif
608#else
609        if(this->gcBasis!=NULL)
610                idDelete((ideal *)&this->gcBasis);
611#endif
612//      idDelete((ideal *)&this->gcBasis);
613//      if(this->inputIdeal!=NULL)
614//              idDelete((ideal *)&this->inputIdeal);
615//      if (this->rootRing!=NULL && this->rootRing!=(ip_sring *)0xfefefefefefefefe)
616//              rDelete(this->rootRing);
617        if(this->UCN!=1 && this->baseRing!=NULL)
618                rDelete(this->baseRing);
619        facet *fAct;
620        facet *fDel;
621        /*Delete the facet structure*/
622        fAct=this->facetPtr;
623        fDel=fAct;
624        while(fAct!=NULL)
625        {
626                fDel=fAct;
627                fAct=fAct->next;
628                delete fDel;
629        }
630        this->counter--;
631        //should be deleted in noRevS
632//      dd_FreeMatrix(this->ddFacets);
633        //dd_FreeMatrix(this->ddFacets);
634        for(int ii=0;ii<this->numRays;ii++)
635                delete(gcRays[ii]);
636        omFree(gcRays);
637}                       
638
639/** Returns the number of cones existing at the time*/
640inline int gcone::getCounter()
641{
642        return this->counter;
643}
644       
645/** \brief Set the interior point of a cone */
646inline void gcone::setIntPoint(intvec *iv)
647{
648        if(this->ivIntPt!=NULL)
649                delete this->ivIntPt;
650        this->ivIntPt=ivCopy(iv);
651}
652               
653/** \brief Returns either a physical copy the interior point of a cone or just a reference to it.*/
654inline intvec *gcone::getIntPoint(bool shallow)
655{
656        if(shallow==TRUE)
657                return this->ivIntPt;
658        else
659                return ivCopy(this->ivIntPt);
660}
661               
662/** \brief Print the interior point */
663inline void gcone::showIntPoint()
664{
665        ivIntPt->show();
666}
667               
668/** \brief Print facets
669 * This is mainly for debugging purposes. Usually called from within gdb
670 */
671volatile void gcone::showFacets(const short codim)
672{
673        facet *f=this->facetPtr;
674        facet *f2=NULL;
675        if(codim==2)
676                f2=this->facetPtr->codim2Ptr;
677        while(f!=NULL)
678        {
679                intvec *iv;
680                iv = f->getFacetNormal();
681                printf("(");iv->show(1,0);
682                if(f->isFlippable==FALSE)
683                        printf(")* ");
684                else
685                        printf(") ");
686                delete iv;
687                if(codim==2)
688                {
689                        f2=f->codim2Ptr;
690                        while(f2!=NULL)
691                        {
692                                printf("[");f2->getFacetNormal()->show(1,0);printf("]");
693                                f2 = f2->next;
694                        }
695                        printf("\n");
696                }
697                f=f->next;
698        }
699        printf("\n");
700}
701               
702/** For debugging purposes only */
703static volatile void showSLA(facet &f)
704{
705        facet *fAct;
706        fAct = &f;
707        if(fAct!=NULL)
708        {
709                facet *codim2Act;
710                codim2Act = fAct->codim2Ptr;
711               
712                printf("\n");
713                while(fAct!=NULL)
714                {
715                        intvec *fNormal;               
716                        fNormal=fAct->getFacetNormal();
717                        printf("(");fNormal->show(1,0);
718                        if(fAct->isFlippable==TRUE)
719                                printf(") ");
720                        else
721                                printf(")* ");
722                        delete fNormal;
723                        codim2Act = fAct->codim2Ptr;
724                        printf(" Codim2: ");
725                        while(codim2Act!=NULL)
726                        {
727                                intvec *f2Normal;
728                                f2Normal = codim2Act->getFacetNormal();
729                                printf("(");f2Normal->show(1,0);printf(") ");
730                                delete f2Normal;
731                                codim2Act = codim2Act->next;
732                        }
733                        printf("UCN = %i\n",fAct->getUCN());
734                        fAct = fAct->next;
735                }
736        }
737}
738               
739static void idDebugPrint(const ideal &I)
740{
741        int numElts=IDELEMS(I);
742        printf("Ideal with %i generators\n", numElts);
743        printf("Leading terms: ");
744        for (int ii=0;ii<numElts;ii++)
745        {
746                pWrite0(pHead(I->m[ii]));
747                printf(",");
748        }
749        printf("\n");
750}
751
752static void invPrint(const ideal &I)
753{
754//      int numElts=IDELEMS(I);
755//      cout << "inv = ";
756//      for(int ii=0;ii<numElts;ii++);
757//      {
758//              pWrite0(pHead(I->m[ii]));
759//              cout << ",";
760//      }
761//      cout << endl;
762}
763
764static bool isMonomial(const ideal &I)
765{
766        bool res = TRUE;
767        for(int ii=0;ii<IDELEMS(I);ii++)
768        {
769                if(pLength((poly)I->m[ii])>1)
770                {
771                        res = FALSE;
772                        break;
773                }
774        }
775        return res;
776}
777               
778/** \brief Set gcone::numFacets */
779inline void gcone::setNumFacets()
780{
781}
782               
783/** \brief Get gcone::numFacets */
784inline int gcone::getNumFacets()
785{
786        return this->numFacets;
787}
788               
789inline int gcone::getUCN()
790{
791        if( this!=NULL)// && ( this!=(gcone * const)0xfbfbfbfbfbfbfbfb && this!=(gcone * const)0xfbfbfbfb ) )
792                return this->UCN;
793        else
794                return -1;
795}
796
797inline int gcone::getPredUCN()
798{
799        return this->pred;
800}
801/** Returns a copy of the this->baseRing */
802inline ring gcone::getBaseRing()
803{
804        return rCopy(this->baseRing);
805}
806
807inline void gcone::setBaseRing(ring r)
808{
809        this->baseRing=rCopy(r);
810}
811
812inline ring gcone::getRef2BaseRing()
813{
814        return this->baseRing;
815}
816
817/** \brief Compute the normals of the cone
818 *
819 * This method computes a representation of the cone in terms of facet normals. It takes an ideal
820 * as its input. Redundancies are automatically removed using cddlib's dd_MatrixCanonicalize.
821 * Other methods for redundancy checkings might be implemented later. See Anders' diss p.44.
822 * Note that in order to use cddlib a 0-th column has to be added to the matrix since cddlib expects
823 * each row to represent an inequality of type const+x1+...+xn <= 0. While computing the normals we come across
824 * the set \f$ \partial\mathcal{G} \f$ which we might store for later use. C.f p71 of journal
825 * As a result of this procedure the pointer facetPtr points to the first facet of the cone.
826 *
827 * Optionally, if the parameter bool compIntPoint is set to TRUE the method will also compute
828 * an interior point of the cone.
829                 */
830void gcone::getConeNormals(const ideal &I, bool compIntPoint)
831{
832#ifdef gfanp
833        timeval start, end;
834        gettimeofday(&start, 0);
835#endif
836        poly aktpoly;
837        int rows;                       // will contain the dimensions of the ineq matrix - deprecated by
838        dd_rowrange ddrows;
839        dd_colrange ddcols;
840        dd_rowset ddredrows;            // # of redundant rows in ddineq
841        dd_rowset ddlinset;             // the opposite
842        dd_rowindex ddnewpos;             // all to make dd_Canonicalize happy
843        dd_NumberType ddnumb=dd_Integer; //Number type
844        dd_ErrorType dderr=dd_NoError;         
845        //Compute the # inequalities i.e. rows of the matrix
846        rows=0; //Initialization
847        for (int ii=0;ii<IDELEMS(I);ii++)
848        {
849//              aktpoly=(poly)I->m[ii];
850//              rows=rows+pLength(aktpoly)-1;
851                rows=rows+pLength((poly)I->m[ii])-1;
852        }
853
854        dd_rowrange aktmatrixrow=0;     // needed to store the diffs of the expvects in the rows of ddineq
855        ddrows=rows;
856        ddcols=this->numVars;
857        dd_MatrixPtr ddineq;            //Matrix to store the inequalities                     
858        ddineq=dd_CreateMatrix(ddrows,ddcols+1); //The first col has to be 0 since cddlib checks for additive consts there
859               
860        // We loop through each g\in GB and compute the resulting inequalities
861        for (int i=0; i<IDELEMS(I); i++)
862        {
863                aktpoly=(poly)I->m[i];          //get aktpoly as i-th component of I
864                //simpler version of storing expvect diffs
865                int *leadexpv=(int*)omAlloc(((this->numVars)+1)*sizeof(int));
866                pGetExpV(aktpoly,leadexpv);
867                poly pNextTerm=aktpoly;
868                while(pNext(pNextTerm)/*pNext(aktpoly)*/!=NULL)
869                {
870                        pNextTerm/*aktpoly*/=pNext(pNextTerm);
871                        int *tailexpv=(int*)omAlloc(((this->numVars)+1)*sizeof(int));
872                        pGetExpV(pNextTerm,tailexpv);                   
873                        for(int kk=1;kk<=this->numVars;kk++)
874                        {                               
875                                dd_set_si(ddineq->matrix[(dd_rowrange)aktmatrixrow][kk],leadexpv[kk]-tailexpv[kk]);
876                        }
877                        aktmatrixrow += 1;
878                        omFree(tailexpv);
879                }               
880                omFree(leadexpv);       
881        } //for
882#if true
883        /*Let's make the preprocessing here. This could already be done in the above for-loop,
884        * but for a start it is more convenient here.
885        * We check the necessary condition of FJT p.18
886        * Quote: [...] every non-zero spoly should have at least one of its terms in inv(G)
887        */
888//      ideal initialForm=idInit(IDELEMS(I),1);
889//      intvec *gamma=new intvec(this->numVars);
890        int falseGammaCounter=0;
891        int *redRowsArray=NULL;
892        int num_alloc=0;
893        int num_elts=0; 
894        for(int ii=0;ii<ddineq->rowsize;ii++)
895        {
896                ideal initialForm=idInit(IDELEMS(I),1);
897                //read row ii into gamma
898                double tmp;
899                intvec *gamma=new intvec(this->numVars);
900                for(int jj=1;jj<=this->numVars;jj++)
901                {
902                        tmp=mpq_get_d(ddineq->matrix[ii][jj]);
903                        (*gamma)[jj-1]=(int)tmp;
904                }
905                computeInv((ideal&)I,initialForm,*gamma);
906                //Create leading ideal
907                ideal L=idInit(IDELEMS(initialForm),1);
908                for(int jj=0;jj<IDELEMS(initialForm);jj++)
909                {
910                        L->m[jj]=pCopy(pHead(initialForm->m[jj]));
911                }               
912               
913                LObject *P = new sLObject();
914                memset(P,0,sizeof(LObject));
915
916                for(int jj=0;jj<=IDELEMS(initialForm)-2;jj++)
917                {
918                        bool isMaybeFacet=FALSE;
919                        P->p1=initialForm->m[jj];       //build spolys of initialForm in_v
920
921                        for(int kk=jj+1;kk<=IDELEMS(initialForm)-1;kk++)
922                        {
923                                P->p2=initialForm->m[kk];
924                                ksCreateSpoly(P);                                                       
925                                if(P->p!=NULL)  //spoly non zero=?
926                                {       
927                                        poly p;//=pInit(); NOTE Evil memleak if pInit is used                   
928                                        poly q;//=pInit();
929                                        p=pCopy(P->p);
930                                        q=pHead(p);     //Monomial q
931                                        isMaybeFacet=FALSE;
932                                        //TODO: Suffices to check LTs here
933                                        while(p!=NULL)
934                                        {
935                                                q=pHead(p);
936                                                for(int ll=0;ll<IDELEMS(L);ll++)
937                                                {
938                                                        if(pLmEqual(L->m[ll],q) || pDivisibleBy(L->m[ll],q))
939                                                        {                                                       
940                                                                isMaybeFacet=TRUE;
941                                                                break;//for
942                                                        }
943                                                }
944                                                if(isMaybeFacet==TRUE)
945                                                {                                                       
946                                                        break;//while(p!=NULL)
947                                                }
948                                                p=pNext(p);                                             
949                                        }//while
950                                        pDelete(&p);
951                                        pDelete(&q);
952                                        if(isMaybeFacet==FALSE)
953                                        {
954                                                dd_set_si(ddineq->matrix[ii][0],1);                                             
955                                                if(num_alloc==0)
956                                                        num_alloc += 1;
957                                                else
958                                                        num_alloc += 1;
959                                                void *tmp = realloc(redRowsArray,(num_alloc*sizeof(int)));
960                                                if(!tmp)
961                                                {
962                                                        WerrorS("Woah dude! Couldn't realloc memory\n");
963                                                        exit(-1);
964                                                }
965                                                redRowsArray = (int*)tmp;
966                                                redRowsArray[num_elts]=ii;
967                                                num_elts++;
968                                                //break;//for(int kk, since we have found one that is not in L 
969                                                goto _start;    //mea culpa, mea culpa, mea maxima culpa
970                                        }
971                                }//if(P->p!=NULL)                               
972                        }//for k
973                }//for jj
974                _start:;
975                idDelete(&L);
976                delete P;
977                idDelete(&initialForm);
978                //idDelete(L);
979                delete gamma;
980        }//for(ii<ddineq-rowsize
981//      delete gamma;
982        int offset=0;//needed for correction of redRowsArray[ii]
983        for( int ii=0;ii<num_elts;ii++ )
984        {
985                dd_MatrixRowRemove(&ddineq,redRowsArray[ii]+1-offset);//cddlib sucks at enumeration
986                offset++;
987        }
988        free(redRowsArray);
989        /*And now for the strictly positive rows
990        * Doesn't gain significant speedup
991        */
992        /*int *posRowsArray=NULL;
993        num_alloc=0;
994        num_elts=0;
995        for(int ii=0;ii<ddineq->rowsize;ii++)
996        {
997                intvec *ivPos = new intvec(this->numVars);
998                for(int jj=0;jj<this->numVars;jj++)
999                        (*ivPos)[jj]=(int)mpq_get_d(ddineq->matrix[ii][jj+1]);
1000                bool isStrictlyPos=FALSE;
1001                int posCtr=0;           
1002                for(int jj=0;jj<this->numVars;jj++)
1003                {
1004                        intvec *ivCanonical = new intvec(this->numVars);
1005                        jj==0 ? (*ivCanonical)[ivPos->length()-1]=1 : (*ivCanonical)[jj-1]=1;
1006                        if(dotProduct(*ivCanonical,*ivPos)!=0)
1007                        {
1008                                if ((*ivPos)[jj]>=0)
1009                                {                               
1010                                        posCtr++;                               
1011                                }
1012                        }                       
1013                        delete ivCanonical;
1014                }
1015                if(posCtr==ivPos->length())
1016                        isStrictlyPos=TRUE;
1017                if(isStrictlyPos==TRUE)
1018                {
1019                        if(num_alloc==0)
1020                                num_alloc += 1;
1021                        else
1022                                num_alloc += 1;
1023                        void *tmp = realloc(posRowsArray,(num_alloc*sizeof(int)));
1024                        if(!tmp)
1025                        {
1026                                WerrorS("Woah dude! Couldn't realloc memory\n");
1027                                exit(-1);
1028                        }
1029                        posRowsArray = (int*)tmp;
1030                        posRowsArray[num_elts]=ii;
1031                        num_elts++;     
1032                }
1033                delete ivPos;
1034        }
1035        offset=0;
1036        for(int ii=0;ii<num_elts;ii++)
1037        {
1038                dd_MatrixRowRemove(&ddineq,posRowsArray[ii]+1-offset);
1039                offset++;
1040        }
1041        free(posRowsArray);*/
1042#endif
1043
1044        dd_MatrixCanonicalize(&ddineq, &ddlinset, &ddredrows, &ddnewpos, &dderr);       
1045        ddrows = ddineq->rowsize;       //Size of the matrix with redundancies removed
1046        ddcols = ddineq->colsize;
1047       
1048        this->ddFacets = dd_CopyMatrix(ddineq);
1049                       
1050        /*Write the normals into class facet*/ 
1051        facet *fAct;    //pointer to active facet       
1052        int numNonFlip=0;
1053        for (int kk = 0; kk<ddrows; kk++)
1054        {
1055                int ggT=1;//NOTE Why does (int)mpq_get_d(ddineq->matrix[kk][1]) not work?
1056                intvec *load = new intvec(this->numVars);//intvec to store a single facet normal that will then be stored via setFacetNormal
1057                for (int jj = 1; jj <ddcols; jj++)
1058                {
1059                        double foo;
1060                        foo = mpq_get_d(ddineq->matrix[kk][jj]);
1061                        (*load)[jj-1] = (int)foo;       //store typecasted entry at pos jj-1 of load
1062                        ggT = intgcd(ggT,(int&)foo);
1063                }//for (int jj = 1; jj <ddcols; jj++)
1064                if(ggT>1)
1065                {
1066                        for(int ll=0;ll<this->numVars;ll++)
1067                                (*load)[ll] /= ggT;//make primitive vector
1068                }
1069                /*Quick'n'dirty hack for flippability. Executed only if gcone::hasHomInput==FALSE
1070                * Otherwise every facet intersects the positive orthant
1071                */     
1072                if(gcone::hasHomInput==FALSE)
1073                {
1074                        //TODO: No dP needed
1075                        bool isFlip=FALSE;
1076                        for(int jj = 0; jj<load->length(); jj++)
1077                        {
1078//                              intvec *ivCanonical = new intvec(load->length());
1079//                              (*ivCanonical)[jj]=1;
1080//                              if (dotProduct(*load,*ivCanonical)<0)   
1081//                              {
1082//                                      isFlip=TRUE;
1083//                                      break;  //URGHS
1084//                              }
1085//                              delete ivCanonical;
1086                                if((*load)[jj]<0)
1087                                {
1088                                        isFlip=TRUE;
1089                                        break;
1090                                }                               
1091                        }/*End of check for flippability*/
1092//                      if(iv64isStrictlyPositive(load))
1093//                              isFlip=TRUE;
1094                        if(isFlip==FALSE)
1095                        {
1096                                this->numFacets++;
1097                                numNonFlip++;
1098                                if(this->numFacets==1)
1099                                {
1100                                        facet *fRoot = new facet();
1101                                        this->facetPtr = fRoot;
1102                                        fAct = fRoot;                                                   
1103                                }
1104                                else
1105                                {
1106                                        fAct->next = new facet();
1107                                        fAct = fAct->next;
1108                                }
1109                                fAct->isFlippable=FALSE;
1110                                fAct->setFacetNormal(load);
1111                                fAct->setUCN(this->getUCN());
1112#ifdef gfan_DEBUG
1113                                printf("Marking facet (");load->show(1,0);printf(") as non flippable\n");               
1114#endif
1115                        }
1116                        else
1117                        {
1118                                this->numFacets++;
1119                                if(this->numFacets==1)
1120                                {
1121                                        facet *fRoot = new facet();
1122                                        this->facetPtr = fRoot;
1123                                        fAct = fRoot;
1124                                }
1125                                else
1126                                {
1127                                        fAct->next = new facet();
1128                                        fAct = fAct->next;
1129                                }
1130                                fAct->isFlippable=TRUE;
1131                                fAct->setFacetNormal(load);
1132                                fAct->setUCN(this->getUCN());                                   
1133                        }
1134                }//hasHomInput==FALSE
1135                else    //Every facet is flippable
1136                {       /*Now load should be full and we can call setFacetNormal*/                                     
1137                        this->numFacets++;
1138                        if(this->numFacets==1)
1139                        {
1140                                facet *fRoot = new facet();
1141                                this->facetPtr = fRoot;
1142                                fAct = fRoot;
1143                        }
1144                        else
1145                        {
1146                                fAct->next = new facet();
1147                                fAct = fAct->next;
1148                        }
1149                        fAct->isFlippable=TRUE;
1150                        fAct->setFacetNormal(load);
1151                        fAct->setUCN(this->getUCN());                                   
1152                }//if (isFlippable==FALSE)
1153                delete load;                           
1154        }//for (int kk = 0; kk<ddrows; kk++)
1155                       
1156        //In cases like I=<x-1,y-1> there are only non-flippable facets...
1157        if(numNonFlip==this->numFacets)
1158        {                                       
1159                WerrorS ("Only non-flippable facets. Terminating...\n");
1160//              exit(-1);//Bit harsh maybe...
1161        }
1162                       
1163        /*
1164        Now we should have a linked list containing the facet normals of those facets that are
1165        -irredundant
1166        -flipable
1167        Adressing is done via *facetPtr
1168        */                     
1169        if (compIntPoint==TRUE)
1170        {
1171                intvec *iv = new intvec(this->numVars);
1172                dd_MatrixPtr posRestr=dd_CreateMatrix(this->numVars,this->numVars+1);
1173                int jj=1;
1174                for (int ii=0;ii<=this->numVars;ii++)
1175                {
1176                        dd_set_si(posRestr->matrix[ii][jj],1);
1177                        jj++;                                                   
1178                }
1179                dd_MatrixAppendTo(&ddineq,posRestr);
1180                interiorPoint(ddineq, *iv);     //NOTE ddineq contains non-flippable facets
1181                this->setIntPoint(iv);  //stores the interior point in gcone::ivIntPt
1182                delete iv;
1183                dd_FreeMatrix(posRestr);
1184        }       
1185        //Clean up but don't delete the return value!   
1186        dd_FreeMatrix(ddineq);
1187        set_free(ddredrows);
1188        set_free(ddlinset);
1189        free(ddnewpos);
1190#ifdef gfanp
1191        gettimeofday(&end, 0);
1192        time_getConeNormals += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
1193#endif
1194
1195}//gcone::getConeNormals(ideal I)
1196               
1197/** \brief Compute the (codim-2)-facets of a given cone
1198 * This method is used during noRevS
1199 * Additionally we check whether the codim2-facet normal is strictly positive. Otherwise
1200 * the facet is marked as non-flippable.
1201 */
1202void gcone::getCodim2Normals(const gcone &gc)
1203{
1204#ifdef gfanp
1205        timeval start, end;
1206        gettimeofday(&start, 0);
1207#endif
1208        //this->facetPtr->codim2Ptr = new facet(2);     //instantiate a (codim-2)-facet
1209        facet *fAct;
1210        fAct = this->facetPtr;         
1211        facet *codim2Act;
1212        //codim2Act = this->facetPtr->codim2Ptr;
1213        dd_MatrixPtr ddineq;//,P,ddakt;
1214        dd_ErrorType err;
1215        //ddineq = facets2Matrix(gc);   //get a matrix representation of the cone
1216        ddineq = dd_CopyMatrix(gc.ddFacets);
1217        /*Now set appropriate linearity*/
1218        for (int ii=0; ii<this->numFacets; ii++)                       
1219        {       
1220                dd_rowset impl_linset, redset;
1221                dd_rowindex newpos;
1222                dd_MatrixPtr ddakt;
1223                ddakt = dd_CopyMatrix(ddineq);
1224//              ddakt->representation=dd_Inequality;    //Not using this makes it faster. But why does the quick check below still work?
1225//              ddakt->representation=dd_Generator;
1226                set_addelem(ddakt->linset,ii+1);/*Now set appropriate linearity*/
1227#ifdef gfanp
1228                timeval t_ddMC_start, t_ddMC_end;
1229                gettimeofday(&t_ddMC_start,0);
1230#endif                         
1231                //dd_MatrixCanonicalize(&ddakt, &impl_linset, &redset, &newpos, &err);
1232                dd_PolyhedraPtr ddpolyh;
1233                ddpolyh=dd_DDMatrix2Poly(ddakt, &err);
1234//              ddpolyh=dd_DDMatrix2Poly2(ddakt, dd_MaxCutoff, &err);
1235                dd_MatrixPtr P;
1236                P=dd_CopyGenerators(ddpolyh);           
1237                dd_FreePolyhedra(ddpolyh);
1238                //TODO Call for one cone , normalize - check equalities - plus lineality -done
1239#ifdef gfanp
1240                gettimeofday(&t_ddMC_end,0);
1241                t_ddMC += (t_ddMC_end.tv_sec - t_ddMC_start.tv_sec + 1e-6*(t_ddMC_end.tv_usec - t_ddMC_start.tv_usec));
1242#endif 
1243                /* We loop through each row of P normalize it by making all
1244                * entries integer ones and add the resulting vector to the
1245                * int matrix facet::codim2Facets */
1246                for (int jj=1;jj<=/*ddakt*/P->rowsize;jj++)
1247                {                                       
1248                        fAct->numCodim2Facets++;
1249                        if(fAct->numCodim2Facets==1)                                   
1250                        {                                               
1251                                fAct->codim2Ptr = new facet(2);                                         
1252                                codim2Act = fAct->codim2Ptr;
1253                        }
1254                        else
1255                        {
1256                                codim2Act->next = new facet(2);
1257                                codim2Act = codim2Act->next;
1258                        }
1259                        intvec *n = new intvec(this->numVars);
1260#ifdef gfanp
1261                        timeval t_mI_start, t_mI_end;
1262                        gettimeofday(&t_mI_start,0);
1263#endif
1264                        makeInt(P,jj,*n);
1265                        /*for(int kk=0;kk<this->numVars;kk++)
1266                        {
1267                                int foo;
1268                                foo = (int)mpq_get_d(ddakt->matrix[ii][kk+1]);
1269                                (*n)[kk]=foo;
1270                        }*/
1271#ifdef gfanp
1272                        gettimeofday(&t_mI_end,0);
1273                        t_mI += (t_mI_end.tv_sec - t_mI_start.tv_sec + 1e-6*(t_mI_end.tv_usec - t_mI_start.tv_usec));
1274#endif
1275                        codim2Act->setFacetNormal(n);
1276                        delete n;                                       
1277                }               
1278                /*We check whether the facet spanned by the codim-2 facets
1279                * intersects with the positive orthant. Otherwise we define this
1280                * facet to be non-flippable. Works since we set the appropriate
1281                * linearity for ddakt above.
1282                */
1283                //TODO It might be faster to compute jus the implied equations instead of a relative interior point
1284//              intvec *iv_intPoint = new intvec(this->numVars);
1285//              dd_MatrixPtr shiftMatrix;
1286//              dd_MatrixPtr intPointMatrix;
1287//              shiftMatrix = dd_CreateMatrix(this->numVars,this->numVars+1);
1288//              for(int kk=0;kk<this->numVars;kk++)
1289//              {
1290//                      dd_set_si(shiftMatrix->matrix[kk][0],1);
1291//                      dd_set_si(shiftMatrix->matrix[kk][kk+1],1);
1292//              }
1293//              intPointMatrix=dd_MatrixAppend(ddakt,shiftMatrix);
1294// #ifdef gfanp
1295//              timeval t_iP_start, t_iP_end;
1296//              gettimeofday(&t_iP_start, 0);
1297// #endif               
1298//              interiorPoint(intPointMatrix,*iv_intPoint);
1299// //           dd_rowset impl_linste,lbasis;
1300// //           dd_LPSolutionPtr lps=NULL;
1301// //           dd_ErrorType err;
1302// //           dd_FindRelativeInterior(intPointMatrix, &impl_linset, &lbasis, &lps, &err);
1303// #ifdef gfanp
1304//              gettimeofday(&t_iP_end, 0);
1305//              t_iP += (t_iP_end.tv_sec - t_iP_start.tv_sec + 1e-6*(t_iP_end.tv_usec - t_iP_start.tv_usec));
1306// #endif
1307//              for(int ll=0;ll<this->numVars;ll++)
1308//              {
1309//                      if( (*iv_intPoint)[ll] < 0 )
1310//                      {
1311//                              fAct->isFlippable=FALSE;
1312//                              break;
1313//                      }
1314//              }
1315                /*End of check*/
1316                /*This test should be way less time consuming*/
1317#ifdef gfanp
1318                timeval t_iP_start, t_iP_end;
1319                gettimeofday(&t_iP_start, 0);
1320#endif
1321                bool containsStrictlyPosRay=TRUE;
1322                for(int ii=0;ii<ddakt->rowsize;ii++)
1323                {
1324                        containsStrictlyPosRay=TRUE;
1325                        for(int jj=1;jj<this->numVars;jj++)
1326                        {
1327                                if(ddakt->matrix[ii][jj]<=0)
1328                                {
1329                                        containsStrictlyPosRay=FALSE;
1330                                        break;
1331                                }
1332                        }
1333                        if(containsStrictlyPosRay==TRUE)
1334                                break;
1335                }
1336                if(containsStrictlyPosRay==FALSE)
1337                //TODO Not sufficient. Intersect with pos orthant for pos int
1338                        fAct->isFlippable=FALSE;
1339#ifdef gfanp
1340                gettimeofday(&t_iP_end, 0);
1341                t_iP += (t_iP_end.tv_sec - t_iP_start.tv_sec + 1e-6*(t_iP_end.tv_usec - t_iP_start.tv_usec));
1342#endif
1343                /**/
1344                fAct = fAct->next;     
1345                dd_FreeMatrix(ddakt);
1346                dd_FreeMatrix(P);
1347        }//for 
1348        dd_FreeMatrix(ddineq);
1349#ifdef gfanp
1350        gettimeofday(&end, 0);
1351        time_getCodim2Normals += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
1352#endif
1353}
1354               
1355/** Really extremal rays this time ;)
1356* Extremal rays are unique modulo the homogeneity space.
1357* Therefore we dd_MatrixAppend gc->ddFacets and gcone::dd_LinealitySpace
1358* into ddineq. Next we compute the extremal rays of the so given subspace.
1359* Figuring out whether a ray belongs to a given facet(normal) is done by
1360* checking whether the inner product of the ray with the normal is zero.
1361* We use ivAdd here which returns a new intvec. Therefore we need to avoid
1362* a memory leak which would be cause by the line
1363* iv=ivAdd(iv,b)
1364* So we keep pointer tmp to iv and delete(tmp), so there should not occur a
1365* memleak
1366* TODO normalization
1367*/
1368void gcone::getExtremalRays(const gcone &gc)
1369{
1370#ifdef gfanp
1371        timeval start, end;
1372        gettimeofday(&start, 0);
1373        timeval poly_start, poly_end;
1374        gettimeofday(&poly_start,0);
1375#endif
1376        //Add lineality space - dd_LinealitySpace
1377        dd_MatrixPtr ddineq;
1378        dd_ErrorType err;       
1379        if(dd_LinealitySpace->rowsize>0)//The linspace might be 0
1380                ddineq = dd_AppendMatrix(gc.ddFacets,gcone::dd_LinealitySpace);
1381        else
1382                ddineq = dd_CopyMatrix(gc.ddFacets);
1383        /* In case the input is non-homogeneous we add constrains for the positive orthant.
1384        * This is justified by the fact that for non-homog ideals we only consider the
1385        * restricted fan. This way we can be sure to find strictly positive interior points.
1386        * This in turn makes life easy when checking for flippability!
1387        * Drawback: Makes the LP larger so probably slows down computations a wee bit.
1388        */
1389        dd_MatrixPtr ddPosRestr;
1390        if(hasHomInput==FALSE)
1391        {
1392                dd_MatrixPtr tmp;
1393                ddPosRestr=dd_CreateMatrix(this->numVars,this->numVars+1);
1394                for(int ii=0;ii<this->numVars;ii++)
1395                        dd_set_si(ddPosRestr->matrix[ii][ii+1],1);
1396                dd_MatrixAppendTo(&ddineq,ddPosRestr);
1397                assert(ddineq);
1398                dd_FreeMatrix(ddPosRestr);
1399        }       
1400        dd_PolyhedraPtr ddPolyh;
1401        ddPolyh = dd_DDMatrix2Poly(ddineq, &err);
1402        dd_MatrixPtr P;
1403        P=dd_CopyGenerators(ddPolyh);
1404        dd_FreePolyhedra(ddPolyh);
1405        dd_FreeMatrix(ddineq);
1406#ifdef gfanp
1407        gettimeofday(&poly_end,0);
1408        t_ddPolyh += (poly_end.tv_sec - poly_start.tv_sec + 1e-6*(poly_end.tv_usec - poly_start.tv_usec));
1409#endif
1410        /* Compute interior point on the fly*/
1411        intvec *ivIntPointOfCone = new intvec(this->numVars);
1412        mpq_t *colSum = new mpq_t[this->numVars];
1413        int denom[this->numVars];//denominators of colSum
1414        //NOTE TODO need to gcd of rows and factor out! -> makeInt
1415        for(int jj=0;jj<this->numVars;jj++)
1416        {
1417                mpq_init(colSum[jj]);           
1418                for(int ii=0;ii<P->rowsize;ii++)
1419                {
1420                        mpq_t tmp; mpq_init(tmp);
1421                        mpq_t sum; mpq_init(sum);
1422                        mpq_set(sum,colSum[jj]);
1423                        mpq_add(tmp,sum,P->matrix[ii][jj+1]);
1424                        mpq_set(colSum[jj],tmp);
1425                        mpq_clear(tmp);
1426                        mpq_clear(sum);
1427                }
1428                mpz_t den; mpz_init(den);
1429                mpq_get_den(den,colSum[jj]);
1430                denom[jj]=(int)mpz_get_si(den);
1431                mpz_clear(den);
1432        }
1433        //Now compute lcm of denominators of colSum[jj]
1434        //NOTE gcd as well and normalise instantly?
1435        mpz_t kgV; mpz_init(kgV);
1436        mpz_set_str(kgV,"1",10);
1437        mpz_t den; mpz_init(den);
1438        mpz_t tmp; mpz_init(tmp);
1439        mpq_get_den(tmp,colSum[0]);
1440        for (int ii=0;ii<(this->numVars)-1;ii++)
1441        {
1442                mpq_get_den(den,colSum[ii+1]);
1443                mpz_lcm(kgV,tmp,den);
1444                mpz_set(tmp, kgV);
1445        }
1446        mpq_t qkgV;
1447        mpq_init(qkgV);
1448        mpq_set_z(qkgV,kgV);
1449        mpz_clear(kgV);
1450        mpz_clear(den);
1451        mpz_clear(tmp);
1452        int ggT=(*ivIntPointOfCone)[0];
1453        for (int ii=0;ii<(this->numVars);ii++)
1454        {
1455                mpq_t product;
1456                mpq_init(product);
1457                mpq_mul(product,qkgV,colSum[ii]);
1458                (*ivIntPointOfCone)[ii]=(int)mpz_get_d(mpq_numref(product));
1459                mpq_clear(product);
1460                //Compute intgcd
1461                ggT=intgcd(ggT,(*ivIntPointOfCone)[ii]);
1462        }
1463        //Divide out a common gcd > 1
1464        if(ggT>1)
1465        {
1466                for(int ii=0;ii<this->numVars;ii++)
1467                        (*ivIntPointOfCone)[ii] /= ggT;
1468        }
1469        mpq_clear(qkgV);
1470        delete [] colSum;
1471        /*For homogeneous input (like Det3,3,5) the int points may be negative. So add a suitable multiple of (1,_,1)*/
1472        if(hasHomInput==TRUE && iv64isStrictlyPositive(ivIntPointOfCone)==FALSE)
1473        {
1474                intvec *ivOne = new intvec(this->numVars);
1475                int maxNegEntry=0;
1476                for(int ii=0;ii<this->numVars;ii++)
1477                {
1478//                      (*ivOne)[ii]=1;
1479                        if ((*ivIntPointOfCone)[ii]<maxNegEntry) maxNegEntry=(*ivIntPointOfCone)[ii];
1480                }
1481                maxNegEntry *= -1;
1482                maxNegEntry++;//To be on the safe side
1483                for(int ii=0;ii<this->numVars;ii++)
1484                        (*ivOne)[ii]=maxNegEntry;
1485                intvec *tmp=ivIntPointOfCone;
1486                ivIntPointOfCone=ivAdd(ivIntPointOfCone,ivOne);
1487                delete(tmp);
1488//              while( !iv64isStrictlyPositive(ivIntPointOfCone) )
1489//              {
1490//                      intvec *tmp = ivIntPointOfCone;
1491//                      for(int jj=0;jj<this->numVars;jj++)
1492//                              (*ivOne)[jj] = (*ivOne)[jj] << 1; //times 2
1493//                      ivIntPointOfCone = ivAdd(ivIntPointOfCone,ivOne);
1494//                      delete tmp;                             
1495//              }
1496                delete ivOne;
1497                int ggT=(*ivIntPointOfCone)[0];
1498                for(int ii=0;ii<this->numVars;ii++)
1499                        ggT=intgcd( ggT, (*ivIntPointOfCone)[ii]);
1500                if(ggT>1)
1501                {
1502                        for(int jj=0;jj<this->numVars;jj++)
1503                                (*ivIntPointOfCone)[jj] /= ggT;
1504                }
1505        }
1506//      assert(iv64isStrictlyPositive(ivIntPointOfCone));
1507       
1508        this->setIntPoint(ivIntPointOfCone);
1509        delete(ivIntPointOfCone);
1510        /* end of interior point computation*/
1511       
1512        //Loop through the rows of P and check whether fNormal*row[i]=0 => row[i] belongs to fNormal
1513        int rows=P->rowsize;
1514        facet *fAct=gc.facetPtr;
1515        //Construct an array to hold the extremal rays of the cone
1516        this->gcRays = (intvec**)omAlloc0(sizeof(intvec*)*P->rowsize); 
1517        for(int ii=0;ii<P->rowsize;ii++)
1518        {
1519                intvec *rowvec = new intvec(this->numVars);
1520                makeInt(P,ii+1,*rowvec);//get an integer entry instead of rational, rowvec is primitve
1521                this->gcRays[ii] = ivCopy(rowvec);
1522                delete rowvec;
1523        }       
1524        this->numRays=P->rowsize;
1525        //Check which rays belong to which facet
1526        while(fAct!=NULL)
1527        {
1528                const intvec *fNormal;// = new intvec(this->numVars);
1529                fNormal = fAct->getRef2FacetNormal();//->getFacetNormal();
1530                intvec *ivIntPointOfFacet = new intvec(this->numVars);
1531                for(int ii=0;ii<rows;ii++)
1532                {                       
1533                        if(dotProduct(*fNormal,this->gcRays[ii])==0)
1534                        {
1535                                intvec *tmp = ivIntPointOfFacet;//Prevent memleak
1536                                fAct->numCodim2Facets++;
1537                                facet *codim2Act;
1538                                if(fAct->numCodim2Facets==1)                                   
1539                                {                                               
1540                                        fAct->codim2Ptr = new facet(2);                                         
1541                                        codim2Act = fAct->codim2Ptr;
1542                                }
1543                                else
1544                                {
1545                                        codim2Act->next = new facet(2);
1546                                        codim2Act = codim2Act->next;
1547                                }
1548                                //codim2Act->setFacetNormal(rowvec);
1549                                //Rather just let codim2Act point to the corresponding intvec of gcRays
1550                                codim2Act->fNormal=this->gcRays[ii];
1551                                fAct->numRays++;                                 
1552                                //Memleak avoided via tmp
1553                                ivIntPointOfFacet=ivAdd(ivIntPointOfFacet,this->gcRays[ii]);
1554                                //Now tmp still points to the OLD address of ivIntPointOfFacet
1555                                delete(tmp);
1556                                       
1557                        }
1558                }//For non-homog input ivIntPointOfFacet should already be >0 here
1559//              if(!hasHomInput) {assert(iv64isStrictlyPositive(ivIntPointOfFacet));}
1560                //if we have no strictly pos ray but the input is homogeneous
1561                //then add a suitable multiple of (1,...,1)
1562                if( !iv64isStrictlyPositive(ivIntPointOfFacet) && hasHomInput==TRUE)
1563                {
1564                        intvec *ivOne = new intvec(this->numVars);
1565                        for(int ii=0;ii<this->numVars;ii++)
1566                                (*ivOne)[ii]=1;
1567                        while( !iv64isStrictlyPositive(ivIntPointOfFacet) )
1568                        {
1569                                intvec *tmp = ivIntPointOfFacet;
1570                                for(int jj=0;jj<this->numVars;jj++)
1571                                {
1572                                        (*ivOne)[jj] = (*ivOne)[jj] << 1; //times 2
1573                                }
1574                                ivIntPointOfFacet = ivAdd(ivIntPointOfFacet/*diff*/,ivOne);
1575                                delete tmp;                             
1576                        }
1577                        delete ivOne;
1578                }
1579                int ggT=(*ivIntPointOfFacet)[0];
1580                for(int ii=0;ii<this->numVars;ii++)
1581                        ggT=intgcd(ggT,(*ivIntPointOfFacet)[ii]);
1582                if(ggT>1)
1583                {
1584                        for(int ii=0;ii<this->numVars;ii++)
1585                                (*ivIntPointOfFacet)[ii] /= ggT;
1586                }                       
1587                fAct->setInteriorPoint(ivIntPointOfFacet);
1588               
1589                delete(ivIntPointOfFacet);
1590                //Now (if we have at least 3 variables) do a bubblesort on the rays
1591                /*if(this->numVars>2)
1592                {
1593                        facet *A[fAct->numRays-1];
1594                        facet *f2Act=fAct->codim2Ptr;
1595                        for(unsigned ii=0;ii<fAct->numRays;ii++)
1596                        {
1597                                A[ii]=f2Act;
1598                                f2Act=f2Act->next;
1599                        }
1600                        bool exchanged=FALSE;
1601                        unsigned n=fAct->numRays-1;
1602                        do
1603                        {
1604                                exchanged=FALSE;//n=fAct->numRays-1;                           
1605                                for(unsigned ii=0;ii<=n-1;ii++)
1606                                {                                       
1607                                        if((A[ii]->fNormal)->compare((A[ii+1]->fNormal))==1)
1608                                        {
1609                                                //Swap rays
1610                                                cout << "Swapping ";
1611                                                A[ii]->fNormal->show(1,0); cout << " with "; A[ii+1]->fNormal->show(1,0); cout << endl;
1612                                                A[ii]->next=A[ii+1]->next;
1613                                                if(ii>0)
1614                                                        A[ii-1]->next=A[ii+1];
1615                                                A[ii+1]->next=A[ii];
1616                                                if(ii==0)
1617                                                        fAct->codim2Ptr=A[ii+1];
1618                                                //end swap
1619                                                facet *tmp=A[ii];//swap in list
1620                                                A[ii+1]=A[ii];
1621                                                A[ii]=tmp;
1622//                                              tmp=NULL;                       
1623                                        }                                       
1624                                }
1625                                n--;                   
1626                        }while(exchanged==TRUE && n>=0);
1627                }*///if pVariables>2
1628//              delete fNormal;         
1629                fAct = fAct->next;
1630        }//end of facet checking
1631        dd_FreeMatrix(P);
1632        //Now all extremal rays should be set w.r.t their respective fNormal
1633        //TODO Not sufficient -> vol2 II/125&127
1634        //NOTE Sufficient according to cddlibs doc. These ARE rays
1635        //What the hell... let's just take interior points
1636        if(gcone::hasHomInput==FALSE)
1637        {
1638                fAct=gc.facetPtr;
1639                while(fAct!=NULL)
1640                {
1641//                      bool containsStrictlyPosRay=FALSE;
1642//                      facet *codim2Act;
1643//                      codim2Act = fAct->codim2Ptr;
1644//                      while(codim2Act!=NULL)
1645//                      {
1646//                              intvec *rayvec;
1647//                              rayvec = codim2Act->getFacetNormal();//Mind this is no normal but a ray!
1648//                              //int negCtr=0;
1649//                              if(iv64isStrictlyPositive(rayvec))
1650//                              {
1651//                                      containsStrictlyPosRay=TRUE;
1652//                                      delete(rayvec);
1653//                                      break;
1654//                              }                               
1655//                              delete(rayvec);
1656//                              codim2Act = codim2Act->next;
1657//                      }
1658//                      if(containsStrictlyPosRay==FALSE)
1659//                              fAct->isFlippable=FALSE;
1660                        if(!iv64isStrictlyPositive(fAct->interiorPoint))
1661                                fAct->isFlippable=FALSE;
1662                        fAct = fAct->next;
1663                }
1664        }//hasHomInput?
1665#ifdef gfanp
1666        gettimeofday(&end, 0);
1667        t_getExtremalRays += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
1668#endif 
1669}               
1670       
1671inline bool gcone::iv64isStrictlyPositive(const intvec * iv64)
1672{
1673        bool res=TRUE;
1674        for(int ii=0;ii<iv64->length();ii++)
1675        {
1676                if((*iv64)[ii]<=0)
1677                {
1678                        res=FALSE;
1679                        break;
1680                }               
1681        }
1682        return res;
1683}
1684       
1685/** \brief Compute the Groebner Basis on the other side of a shared facet
1686 *
1687 * Implements algorithm 4.3.2 from Anders' thesis.
1688 * As shown there it is not necessary to compute an interior point. The knowledge of the facet normal
1689 * suffices. A term \f$ x^\gamma \f$ of \f$ g \f$ is in \f$  in_\omega(g) \f$ iff \f$ \gamma - leadexp(g)\f$
1690 * is parallel to \f$ leadexp(g) \f$
1691 * Parallelity is checked using basic linear algebra. See gcone::isParallel.
1692 * Other possibilities include computing the rank of the matrix consisting of the vectors in question and
1693 * computing an interior point of the facet and taking all terms having the same weight with respect
1694 * to this interior point.
1695 *\param ideal, facet
1696 * Input: a marked,reduced Groebner basis and a facet
1697 */
1698inline void gcone::flip(ideal gb, facet *f)             //Compute "the other side"
1699{       
1700#ifdef gfanp
1701        timeval start, end;
1702        gettimeofday(&start, 0);
1703#endif         
1704        intvec *fNormal;// = new intvec(this->numVars); //facet normal, check for parallelity                   
1705        fNormal = f->getFacetNormal();  //read this->fNormal;
1706#ifdef gfan_DEBUG
1707//      std::cout << "running gcone::flip" << std::endl;
1708        printf("flipping UCN %i over facet",this->getUCN());
1709        fNormal->show(1,0);
1710        printf(") with UCN %i\n",f->getUCN() ); 
1711#endif
1712        if(this->getUCN() != f->getUCN())
1713        {
1714                WerrorS("Uh oh... Trying to flip over facet with incompatible UCN");
1715                exit(-1);
1716        }
1717        /*1st step: Compute the initial ideal*/
1718        /*poly initialFormElement[IDELEMS(gb)];*/       //array of #polys in GB to store initial form
1719        ideal initialForm=idInit(IDELEMS(gb),this->gcBasis->rank);
1720       
1721        computeInv(gb,initialForm,*fNormal);
1722
1723#ifdef gfan_DEBUG
1724/*      cout << "Initial ideal is: " << endl;
1725        idShow(initialForm);
1726        //f->printFlipGB();*/
1727//      cout << "===" << endl;
1728#endif                 
1729        /*2nd step: lift initial ideal to a GB of the neighbouring cone using minus alpha as weight*/
1730        /*Substep 2.1
1731        compute $G_{-\alpha}(in_v(I))
1732        see journal p. 66
1733        NOTE Check for different rings. Prolly it will not always be necessary to add a weight, if the
1734        srcRing already has a weighted ordering
1735        */
1736        ring srcRing=currRing;
1737        ring tmpRing;
1738                       
1739        if( (srcRing->order[0]!=ringorder_a))
1740        {
1741                intvec *iv;// = new intvec(this->numVars);
1742                iv = ivNeg(fNormal);//ivNeg uses ivCopy -> new
1743//              tmpRing=rCopyAndAddWeight(srcRing,ivNeg(fNormal));
1744                tmpRing=rCopyAndAddWeight(srcRing,iv);
1745                delete iv;
1746        }
1747        else
1748        {
1749                tmpRing=rCopy0(srcRing);
1750                int length=fNormal->length();
1751                int *A=(int *)omAlloc0(length*sizeof(int));
1752                for(int jj=0;jj<length;jj++)
1753                {
1754                        A[jj]=-(*fNormal)[jj];
1755                }
1756                omFree(tmpRing->wvhdl[0]);
1757                tmpRing->wvhdl[0]=(int*)A;
1758                tmpRing->block1[0]=length;
1759                rComplete(tmpRing);
1760                //omFree(A);
1761        }
1762        delete fNormal; 
1763        rChangeCurrRing(tmpRing);       
1764                       
1765        ideal ina;                     
1766        ina=idrCopyR(initialForm,srcRing);
1767        idDelete(&initialForm);
1768        ideal H;
1769//      H=kStd(ina,NULL,isHomog,NULL);  //we know it is homogeneous
1770#ifdef gfanp
1771        timeval t_kStd_start, t_kStd_end;
1772        gettimeofday(&t_kStd_start,0);
1773#endif
1774        if(gcone::hasHomInput==TRUE)
1775                H=kStd(ina,NULL,isHomog,NULL/*,gcone::hilbertFunction*/);
1776        else
1777                H=kStd(ina,NULL,isNotHomog,NULL);       //This is \mathcal(G)_{>_-\alpha}(in_v(I))
1778#ifdef gfanp
1779        gettimeofday(&t_kStd_end, 0);
1780        t_kStd += (t_kStd_end.tv_sec - t_kStd_start.tv_sec + 1e-6*(t_kStd_end.tv_usec - t_kStd_start.tv_usec));
1781#endif
1782        idSkipZeroes(H);
1783        idDelete(&ina);
1784
1785        /*Substep 2.2
1786        do the lifting and mark according to H
1787        */
1788        rChangeCurrRing(srcRing);
1789        ideal srcRing_H;
1790        ideal srcRing_HH;                       
1791        srcRing_H=idrCopyR(H,tmpRing);
1792        //H is needed further below, so don't idDelete here
1793        srcRing_HH=ffG(srcRing_H,this->gcBasis);
1794        idDelete(&srcRing_H);
1795               
1796        /*Substep 2.2.1
1797         * Mark according to G_-\alpha
1798         * Here we have a minimal basis srcRing_HH. In order to turn this basis into a reduced basis
1799         * we have to compute an interior point of C(srcRing_HH). For this we need to know the cone
1800         * represented by srcRing_HH MARKED ACCORDING TO G_{-\alpha}
1801         * Thus we check whether the leading monomials of srcRing_HH and srcRing_H coincide. If not we
1802         * compute the difference accordingly
1803        */
1804#ifdef gfanp
1805        timeval t_markings_start, t_markings_end;
1806        gettimeofday(&t_markings_start, 0);
1807#endif         
1808        bool markingsAreCorrect=FALSE;
1809        dd_MatrixPtr intPointMatrix;
1810        int iPMatrixRows=0;
1811        dd_rowrange aktrow=0;                   
1812        for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
1813        {
1814                poly aktpoly=(poly)srcRing_HH->m[ii];//This is a pointer, so don't pDelete
1815                iPMatrixRows = iPMatrixRows+pLength(aktpoly);           
1816        }
1817        /* additionally one row for the standard-simplex and another for a row that becomes 0 during
1818         * construction of the differences
1819         */
1820        intPointMatrix = dd_CreateMatrix(iPMatrixRows+2,this->numVars+1); 
1821        intPointMatrix->numbtype=dd_Integer;    //NOTE: DO NOT REMOVE OR CHANGE TO dd_Rational
1822       
1823        for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
1824        {
1825                markingsAreCorrect=FALSE;       //crucial to initialise here
1826                poly aktpoly=srcRing_HH->m[ii]; //Only a pointer, so don't pDelete
1827                /*Comparison of leading monomials is done via exponent vectors*/
1828                for (int jj=0;jj<IDELEMS(H);jj++)
1829                {
1830                        int *src_ExpV = (int *)omAlloc((this->numVars+1)*sizeof(int));
1831                        int *dst_ExpV = (int *)omAlloc((this->numVars+1)*sizeof(int));
1832                        pGetExpV(aktpoly,src_ExpV);
1833                        rChangeCurrRing(tmpRing);       //this ring change is crucial!
1834                        pGetExpV(pCopy(H->m[ii]),dst_ExpV);
1835                        rChangeCurrRing(srcRing);
1836                        bool expVAreEqual=TRUE;
1837                        for (int kk=1;kk<=this->numVars;kk++)
1838                        {
1839#ifdef gfan_DEBUG
1840//                              cout << src_ExpV[kk] << "," << dst_ExpV[kk] << endl;
1841#endif
1842                                if (src_ExpV[kk]!=dst_ExpV[kk])
1843                                {
1844                                        expVAreEqual=FALSE;
1845                                }
1846                        }                                                               
1847                        if (expVAreEqual==TRUE)
1848                        {
1849                                markingsAreCorrect=TRUE; //everything is fine
1850#ifdef gfan_DEBUG
1851//                              cout << "correct markings" << endl;
1852#endif
1853                        }//if (pHead(aktpoly)==pHead(H->m[jj])
1854                        omFree(src_ExpV);
1855                        omFree(dst_ExpV);
1856                }//for (int jj=0;jj<IDELEMS(H);jj++)
1857               
1858                int *leadExpV=(int *)omAlloc((this->numVars+1)*sizeof(int));
1859                if (markingsAreCorrect==TRUE)
1860                {
1861                        pGetExpV(aktpoly,leadExpV);
1862                }
1863                else
1864                {
1865                        rChangeCurrRing(tmpRing);
1866                        pGetExpV(pHead(H->m[ii]),leadExpV); //We use H->m[ii] as leading monomial
1867                        rChangeCurrRing(srcRing);
1868                }
1869                /*compute differences of the expvects*/                         
1870                while (pNext(aktpoly)!=NULL)
1871                {
1872                        int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
1873                        /*The following if-else-block makes sure the first term (i.e. the wrongly marked term)
1874                        is not omitted when computing the differences*/
1875                        if(markingsAreCorrect==TRUE)
1876                        {
1877                                aktpoly=pNext(aktpoly);
1878                                pGetExpV(aktpoly,v);
1879                        }
1880                        else
1881                        {
1882                                pGetExpV(pHead(aktpoly),v);
1883                                markingsAreCorrect=TRUE;
1884                        }
1885                        int ctr=0;
1886                        for (int jj=0;jj<this->numVars;jj++)
1887                        {                               
1888                                /*Store into ddMatrix*/                         
1889                                if(leadExpV[jj+1]-v[jj+1])
1890                                        ctr++;
1891                                dd_set_si(intPointMatrix->matrix[aktrow][jj+1],leadExpV[jj+1]-v[jj+1]);
1892                        }
1893                        /*It ought to be more sensible to avoid 0-rows in the first place*/
1894//                      if(ctr==this->numVars)//We have a 0-row
1895//                              dd_MatrixRowRemove(&intPointMatrix,aktrow);
1896//                      else
1897                                aktrow +=1;
1898                        omFree(v);
1899                }
1900                omFree(leadExpV);
1901        }//for (int ii=0;ii<IDELEMS(srcRing_HH);ii++)
1902#ifdef gfanp
1903        gettimeofday(&t_markings_end, 0);
1904        t_markings += (t_markings_end.tv_sec - t_markings_start.tv_sec + 1e-6*(t_markings_end.tv_usec - t_markings_start.tv_usec));
1905#endif
1906        /*Now it is safe to idDelete(H)*/
1907        idDelete(&H);
1908        /*Preprocessing goes here since otherwise we would delete the constraint
1909        * for the standard simplex.
1910        */
1911        preprocessInequalities(intPointMatrix);
1912        /*Now we add the constraint for the standard simplex*/
1913//      dd_set_si(intPointMatrix->matrix[aktrow][0],-1);
1914//      for (int jj=1;jj<=this->numVars;jj++)
1915//      {
1916//              dd_set_si(intPointMatrix->matrix[aktrow][jj],1);
1917//      }
1918        //Let's make sure we compute interior points from the positive orthant
1919//      dd_MatrixPtr posRestr=dd_CreateMatrix(this->numVars,this->numVars+1);
1920//     
1921//      int jj=1;
1922//      for (int ii=0;ii<this->numVars;ii++)
1923//      {
1924//              dd_set_si(posRestr->matrix[ii][jj],1);
1925//              jj++;                                                   
1926//      }
1927        /*We create a matrix containing the standard simplex
1928        * and constraints to assure a strictly positive point
1929        * is computed */
1930        dd_MatrixPtr posRestr = dd_CreateMatrix(this->numVars+1, this->numVars+1);
1931        for(int ii=0;ii<posRestr->rowsize;ii++)
1932        {
1933                if(ii==0)
1934                {
1935                        dd_set_si(posRestr->matrix[ii][0],-1);
1936                        for(int jj=1;jj<=this->numVars;jj++)                   
1937                                dd_set_si(posRestr->matrix[ii][jj],1);                 
1938                }
1939                else
1940                {
1941                        /** Set all variables to \geq 1/10. YMMV but this choice is pretty equal*/
1942                        dd_set_si2(posRestr->matrix[ii][0],-1,2);
1943                        dd_set_si(posRestr->matrix[ii][ii],1);
1944                }
1945        }
1946        dd_MatrixAppendTo(&intPointMatrix,posRestr);
1947        dd_FreeMatrix(posRestr);
1948
1949        intvec *iv_weight = new intvec(this->numVars);
1950#ifdef gfanp
1951        timeval t_dd_start, t_dd_end;
1952        gettimeofday(&t_dd_start, 0);
1953#endif
1954        dd_ErrorType err;
1955        dd_rowset implLin, redrows;
1956        dd_rowindex newpos;
1957
1958        //NOTE Here we should remove interiorPoint and instead
1959        // create and ordering like (a(omega),a(fNormal),dp)
1960//      if(this->ivIntPt==NULL)
1961                interiorPoint(intPointMatrix, *iv_weight);      //iv_weight now contains the interior point
1962//      else
1963//              iv_weight=this->getIntPoint();
1964        dd_FreeMatrix(intPointMatrix);
1965        /*Crude attempt for interior point */
1966        /*dd_PolyhedraPtr ddpolyh;
1967        dd_ErrorType err;
1968        dd_rowset impl_linset,redset;
1969        dd_rowindex newpos;
1970        dd_MatrixCanonicalize(&intPointMatrix, &impl_linset, &redset, &newpos, &err);
1971        ddpolyh=dd_DDMatrix2Poly(intPointMatrix, &err);
1972        dd_MatrixPtr P;
1973        P=dd_CopyGenerators(ddpolyh);
1974        dd_FreePolyhedra(ddpolyh);
1975        for(int ii=0;ii<P->rowsize;ii++)
1976        {
1977                intvec *iv_row=new intvec(this->numVars);
1978                makeInt(P,ii+1,*iv_row);
1979                iv_weight =ivAdd(iv_weight, iv_row);
1980                delete iv_row;
1981        }
1982        dd_FreeMatrix(P);
1983        dd_FreeMatrix(intPointMatrix);*/
1984#ifdef gfanp
1985        gettimeofday(&t_dd_end, 0);
1986        t_dd += (t_dd_end.tv_sec - t_dd_start.tv_sec + 1e-6*(t_dd_end.tv_usec - t_dd_start.tv_usec));
1987#endif 
1988       
1989        /*Step 3
1990        * turn the minimal basis into a reduced one */                 
1991        // NOTE May assume that at this point srcRing already has 3 blocks of orderins, starting with a
1992        // Thus:
1993        //ring dstRing=rCopyAndChangeWeight(srcRing,iv_weight);
1994        ring dstRing=rCopy0(tmpRing);
1995        int length=iv_weight->length();
1996        int *A=(int *)omAlloc0(length*sizeof(int));
1997        for(int jj=0;jj<length;jj++)
1998        {
1999                A[jj]=(*iv_weight)[jj];
2000        }
2001        dstRing->wvhdl[0]=(int*)A;
2002        rComplete(dstRing);
2003        rChangeCurrRing(dstRing);
2004        rDelete(tmpRing);
2005        delete iv_weight;
2006
2007        ideal dstRing_I;                       
2008        dstRing_I=idrCopyR(srcRing_HH,srcRing);
2009        idDelete(&srcRing_HH); //Hmm.... causes trouble - no more
2010        //dstRing_I=idrCopyR(inputIdeal,srcRing);
2011        BITSET save=test;
2012        test|=Sy_bit(OPT_REDSB);
2013        test|=Sy_bit(OPT_REDTAIL);
2014#ifdef gfan_DEBUG
2015//      test|=Sy_bit(6);        //OPT_DEBUG
2016#endif
2017        ideal tmpI;
2018        //NOTE Any of the two variants of tmpI={idrCopy(),dstRing_I} does the trick
2019        //tmpI = idrCopyR(this->inputIdeal,this->baseRing);
2020        tmpI = dstRing_I;
2021#ifdef gfanp
2022        gettimeofday(&t_kStd_start,0);
2023#endif
2024        if(gcone::hasHomInput==TRUE)
2025                dstRing_I=kStd(tmpI,NULL,isHomog,NULL/*,gcone::hilbertFunction*/);
2026        else
2027                dstRing_I=kStd(tmpI,NULL,isNotHomog,NULL);
2028#ifdef gfanp
2029        gettimeofday(&t_kStd_end, 0);
2030        t_kStd += (t_kStd_end.tv_sec - t_kStd_start.tv_sec + 1e-6*(t_kStd_end.tv_usec - t_kStd_start.tv_usec));
2031#endif
2032        idDelete(&tmpI);
2033        idNorm(dstRing_I);                     
2034//      kInterRed(dstRing_I);
2035        idSkipZeroes(dstRing_I);
2036        test=save;
2037        /*End of step 3 - reduction*/
2038                       
2039        f->setFlipGB(dstRing_I);//store the flipped GB
2040//      idDelete(&dstRing_I);
2041        f->flipRing=rCopy(dstRing);     //store the ring on the other side
2042#ifdef gfan_DEBUG
2043        printf("Flipped GB is UCN %i:\n",counter+1);
2044        idDebugPrint(dstRing_I);
2045        printf("\n");
2046#endif 
2047        idDelete(&dstRing_I);   
2048        rChangeCurrRing(srcRing);       //return to the ring we started the computation of flipGB in
2049        rDelete(dstRing);
2050#ifdef gfanp
2051        gettimeofday(&end, 0);
2052        time_flip += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
2053#endif
2054}//void flip(ideal gb, facet *f)
2055
2056/** \brief A slightly different approach to flipping
2057* Here we use the fact that in_v(in_u(I))=in_(u+eps*v)(I). Therefore, we do no longer
2058* need to compute an interior point and run BBA on the minimal basis but we can rather
2059* use the ordering (a(omega),a(fNormal),dp)
2060* The second parameter facet *f must not be const since we need to store f->flipGB
2061* Problem: Assume we start in a cone with ordering (dp,C). Then \f$ in_\omega(I) \f$
2062* will be from a ring with (a(),dp,C) and our resulting cone from (a(),a(),dp,C). Hence a way
2063* must be found to circumvent the sequence of a()'s growing to a ridiculous size.
2064* Therefore: We use (a(),a(),dp,C) for the computation of the reduced basis. But then we
2065* do have an interior point of the cone by adding the extremal rays. So we replace
2066* the latter cone by a cone with (a(sum_of_rays),dp,C).
2067* Con: It's incredibly ugly
2068* Pro: No messing around with readConeFromFile()
2069* Is there a way to construct a vector from \f$ \omega \f$ and the facet normal?
2070*/
2071inline void gcone::flip2(const ideal &gb, facet *f)
2072{
2073#ifdef gfanp
2074        timeval start, end;
2075        gettimeofday(&start, 0);
2076#endif
2077        const intvec *fNormal;
2078        fNormal = f->getRef2FacetNormal();/*->getFacetNormal();*/       //read this->fNormal;
2079#ifdef gfan_DEBUG
2080        printf("flipping UCN %i over facet(",this->getUCN());
2081        fNormal->show(1,0);
2082        printf(") with UCN %i\n",f->getUCN()); 
2083#endif
2084        if(this->getUCN() != f->getUCN())
2085        {       printf("%i vs %i\n",this->getUCN(), f->getUCN() );
2086                WerrorS("Uh oh... Trying to flip over facet with incompatible UCN");
2087                exit(-1);
2088        }
2089        /*1st step: Compute the initial ideal*/
2090        ideal initialForm=idInit(IDELEMS(gb),this->gcBasis->rank);     
2091        computeInv( gb, initialForm, *fNormal );
2092        ring srcRing=currRing;
2093        ring tmpRing;
2094       
2095        const intvec *intPointOfFacet;
2096        intPointOfFacet=f->getInteriorPoint();
2097        //Now we need two blocks of ringorder_a!
2098        //May assume the same situation as in flip() here                       
2099        if( (srcRing->order[0]!=ringorder_a) && (srcRing->order[1]!=ringorder_a) )
2100        {
2101                intvec *iv = new intvec(this->numVars);//init with 1s, since we do not need a 2nd block here but later
2102//              intvec *iv_foo = new intvec(this->numVars,1);//placeholder
2103                intvec *ivw = ivNeg(fNormal);           
2104                tmpRing=rCopyAndAddWeight2(srcRing,ivw/*intPointOfFacet*/,iv);
2105                delete iv;delete ivw;
2106//              delete iv_foo;
2107        }
2108        else
2109        {
2110                intvec *iv=new intvec(this->numVars);
2111                intvec *ivw=ivNeg(fNormal);
2112                tmpRing=rCopyAndAddWeight2(srcRing,ivw,iv);
2113                delete iv; delete ivw;
2114                /*tmpRing=rCopy0(srcRing);
2115                int length=fNormal->length();
2116                int *A1=(int *)omAlloc0(length*sizeof(int));
2117                int *A2=(int *)omAlloc0(length*sizeof(int));
2118                for(int jj=0;jj<length;jj++)
2119                {
2120                        A1[jj] = -(*fNormal)[jj];
2121                        A2[jj] = 1;//-(*fNormal)[jj];//NOTE Do we need this here? This is only the facet ideal
2122                }
2123                omFree(tmpRing->wvhdl[0]);
2124                if(tmpRing->wvhdl[1]!=NULL)
2125                        omFree(tmpRing->wvhdl[1]);
2126                tmpRing->wvhdl[0]=(int*)A1;             
2127                tmpRing->block1[0]=length;
2128                tmpRing->wvhdl[1]=(int*)A2;             
2129                tmpRing->block1[1]=length;
2130                rComplete(tmpRing);*/
2131        }
2132//      delete fNormal; //NOTE Do not delete when using getRef2FacetNormal();
2133        rChangeCurrRing(tmpRing);       
2134        //Now currRing should have (a(),a(),dp,C)               
2135        ideal ina;                     
2136        ina=idrCopyR(initialForm,srcRing);
2137        idDelete(&initialForm);
2138        ideal H;
2139#ifdef gfanp
2140        timeval t_kStd_start, t_kStd_end;
2141        gettimeofday(&t_kStd_start,0);
2142#endif
2143        BITSET save=test;
2144        test|=Sy_bit(OPT_REDSB);
2145        test|=Sy_bit(OPT_REDTAIL);
2146//      if(gcone::hasHomInput==TRUE)
2147                H=kStd(ina,NULL,testHomog/*isHomog*/,NULL/*,gcone::hilbertFunction*/);
2148//      else
2149//              H=kStd(ina,NULL,isNotHomog,NULL);       //This is \mathcal(G)_{>_-\alpha}(in_v(I))
2150        test=save;
2151#ifdef gfanp
2152        gettimeofday(&t_kStd_end, 0);
2153        t_kStd += (t_kStd_end.tv_sec - t_kStd_start.tv_sec + 1e-6*(t_kStd_end.tv_usec - t_kStd_start.tv_usec));
2154#endif
2155        idSkipZeroes(H);
2156        idDelete(&ina);
2157       
2158        rChangeCurrRing(srcRing);
2159        ideal srcRing_H;
2160        ideal srcRing_HH;                       
2161        srcRing_H=idrCopyR(H,tmpRing);
2162        //H is needed further below, so don't idDelete here
2163        srcRing_HH=ffG(srcRing_H,this->gcBasis);
2164        idDelete(&srcRing_H);
2165        //Now BBA(srcRing_HH) with (a(),a(),dp)
2166        /* Evil modification of currRing */
2167        ring dstRing=rCopy0(tmpRing);
2168        int length=this->numVars;
2169        int *A1=(int *)omAlloc0(length*sizeof(int));
2170        int *A2=(int *)omAlloc0(length*sizeof(int));
2171        const intvec *ivw=f->getRef2FacetNormal();
2172        for(int jj=0;jj<length;jj++)
2173        {
2174                A1[jj] = (*intPointOfFacet)[jj];
2175                A2[jj] = -(*ivw)[jj];//TODO Or minus (*ivw)[ii] ??? NOTE minus
2176        }
2177        omFree(dstRing->wvhdl[0]);
2178        if(dstRing->wvhdl[1]!=NULL)
2179                omFree(dstRing->wvhdl[1]);
2180        dstRing->wvhdl[0]=(int*)A1;             
2181        dstRing->block1[0]=length;
2182        dstRing->wvhdl[1]=(int*)A2;             
2183        dstRing->block1[1]=length;
2184        rComplete(dstRing);
2185        rChangeCurrRing(dstRing);
2186        ideal dstRing_I;                       
2187        dstRing_I=idrCopyR(srcRing_HH,srcRing);
2188        idDelete(&srcRing_HH); //Hmm.... causes trouble - no more       
2189        save=test;
2190        test|=Sy_bit(OPT_REDSB);
2191        test|=Sy_bit(OPT_REDTAIL);
2192        ideal tmpI;
2193        tmpI = dstRing_I;
2194#ifdef gfanp
2195//      timeval t_kStd_start, t_kStd_end;
2196        gettimeofday(&t_kStd_start,0);
2197#endif
2198//      if(gcone::hasHomInput==TRUE)
2199//              dstRing_I=kStd(tmpI,NULL,isHomog,NULL/*,gcone::hilbertFunction*/);
2200//      else
2201                dstRing_I=kStd(tmpI,NULL,testHomog,NULL);
2202#ifdef gfanp
2203        gettimeofday(&t_kStd_end, 0);
2204        t_kStd += (t_kStd_end.tv_sec - t_kStd_start.tv_sec + 1e-6*(t_kStd_end.tv_usec - t_kStd_start.tv_usec));
2205#endif
2206        idDelete(&tmpI);
2207        idNorm(dstRing_I);                     
2208        idSkipZeroes(dstRing_I);
2209        test=save;
2210        /*End of step 3 - reduction*/
2211       
2212        f->setFlipGB(dstRing_I);
2213        f->flipRing=rCopy(dstRing);
2214        rDelete(tmpRing);
2215        rDelete(dstRing);
2216        //Now we should have dstRing with (a(),a(),dp,C)
2217        //This must be replaced with (a(),dp,C) BEFORE gcTmp is actually added to the list
2218        //of cones in noRevS
2219        rChangeCurrRing(srcRing);
2220#ifdef gfanp
2221        gettimeofday(&end, 0);
2222        time_flip2 += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
2223#endif
2224}//flip2
2225
2226/** \brief Compute initial ideal
2227 * Compute the initial ideal in_v(G) wrt a (possible) facet normal
2228 * used in gcone::getFacetNormal in order to preprocess possible facet normals
2229 * and in gcone::flip for obvious reasons.
2230*/
2231inline void gcone::computeInv(const ideal &gb, ideal &initialForm, const intvec &fNormal)
2232{
2233#ifdef gfanp
2234        timeval start, end;
2235        gettimeofday(&start, 0);
2236#endif
2237        for (int ii=0;ii<IDELEMS(gb);ii++)
2238        {
2239                poly initialFormElement;
2240                poly aktpoly = (poly)gb->m[ii];//Ptr, so don't pDelete(aktpoly)
2241                int *leadExpV=(int *)omAlloc((this->numVars+1)*sizeof(int));
2242                pGetExpV(aktpoly,leadExpV);     //find the leading exponent in leadExpV[1],...,leadExpV[n], use pNext(p)
2243                initialFormElement=pHead(aktpoly);
2244                while(pNext(aktpoly)!=NULL)     /*loop trough terms and check for parallelity*/
2245                {
2246                        intvec *check = new intvec(this->numVars);
2247                        aktpoly=pNext(aktpoly); //next term
2248//                      pSetm(aktpoly);
2249                        int *v=(int *)omAlloc((this->numVars+1)*sizeof(int));
2250                        pGetExpV(aktpoly,v);           
2251                        /* Convert (int)v into (intvec)check */                 
2252                        for (int jj=0;jj<this->numVars;jj++)
2253                        {
2254                                (*check)[jj]=v[jj+1]-leadExpV[jj+1];
2255                        }
2256                        if (isParallel(*check,fNormal)) //pass *check when
2257//                      if(isParallel((const intvec*)&check,(const intvec*)&fNormal))
2258//                      if(fNormal.compare(check)==0)
2259                        {
2260                                //Found a parallel vector. Add it
2261                                initialFormElement = pAdd((initialFormElement),(poly)pHead(aktpoly));
2262                        }
2263                        omFree(v);
2264                        delete check;
2265                }//while
2266#ifdef gfan_DEBUG
2267//              cout << "Initial Form=";                               
2268//              pWrite(initialFormElement[ii]);
2269//              cout << "---" << endl;
2270#endif
2271                /*Now initialFormElement must be added to (ideal)initialForm */
2272                initialForm->m[ii]=pCopy(initialFormElement);
2273                pDelete(&initialFormElement);
2274                omFree(leadExpV);
2275        }//for
2276#ifdef gfanp
2277        gettimeofday(&end, 0);
2278        time_computeInv += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
2279#endif
2280}
2281
2282/** \brief Compute the remainder of a polynomial by a given ideal
2283 *
2284 * Compute \f$ f^{\mathcal{G}} \f$
2285 * Algorithm is taken from Cox, Little, O'Shea, IVA 2nd Ed. p 62
2286 * However, since we are only interested in the remainder, there is no need to
2287 * compute the factors \f$ a_i \f$
2288 */
2289//NOTE: Should be replaced by kNF or kNF2
2290//NOTE: Done
2291//NOTE: removed with r12286
2292               
2293/** \brief Compute \f$ f-f^{\mathcal{G}} \f$
2294*/
2295//NOTE: use kNF or kNF2 instead of restOfDivision
2296inline ideal gcone::ffG(const ideal &H, const ideal &G)
2297{
2298        int size=IDELEMS(H);
2299        ideal res=idInit(size,1);
2300        for (int ii=0;ii<size;ii++)
2301        {
2302//              poly temp1;//=pInit();
2303//              poly temp2;//=pInit();
2304                poly temp3;//=pInit();//polys to temporarily store values for pSub
2305//              res->m[ii]=pCopy(kNF(G, NULL,H->m[ii],0,0));
2306//              temp1=pCopy(H->m[ii]);//TRY
2307//              temp2=pCopy(res->m[ii]);
2308                //NOTE if gfanHeuristic=0 (sic!) this results in dPolyErrors - mon from wrong ring
2309//              temp2=pCopy(kNF(G, NULL,H->m[ii],0,0));//TRY
2310//              temp3=pSub(temp1, temp2);//TRY
2311                temp3=pSub(pCopy(H->m[ii]),pCopy(kNF(G,NULL,H->m[ii],0,0)));//NOTRY
2312                res->m[ii]=pCopy(temp3);
2313                //res->m[ii]=pSub(temp1,temp2); //buggy         
2314                //cout << "res->m["<<ii<<"]=";pWrite(res->m[ii]);
2315//              pDelete(&temp1);//TRY
2316//              pDelete(&temp2);
2317                pDelete(&temp3);
2318        }
2319        return res;
2320}
2321       
2322/** \brief Preprocessing of inequlities
2323* Do some preprocessing on the matrix of inequalities
2324* 1) Replace several constraints on the pos. orthants by just one for each orthant
2325* 2) Remove duplicates of inequalities
2326* 3) Remove inequalities that arise as sums of other inequalities
2327*/
2328void gcone::preprocessInequalities(dd_MatrixPtr &ddineq)
2329{
2330/*      int *posRowsArray=NULL;
2331        int num_alloc=0;
2332        int num_elts=0;
2333        int offset=0;*/
2334        //Remove zeroes (and strictly pos rows?)
2335        for(int ii=0;ii<ddineq->rowsize;ii++)
2336        {
2337                intvec *iv = new intvec(this->numVars);
2338                intvec *ivNull = new intvec(this->numVars);//Needed for intvec64::compare(*intvec)
2339                int posCtr=0;
2340                for(int jj=0;jj<this->numVars;jj++)
2341                {
2342                        (*iv)[jj]=(int)mpq_get_d(ddineq->matrix[ii][jj+1]);
2343                        if((*iv)[jj]>0)//check for strictly pos rows
2344                                posCtr++;
2345                        //Behold! This will delete the row for the standard simplex!
2346                }
2347//              if( (iv->compare(0)==0) || (posCtr==iv->length()) )
2348                if( (posCtr==iv->length()) || (iv->compare(ivNull)==0) )               
2349                {
2350                        dd_MatrixRowRemove(&ddineq,ii+1);
2351                        ii--;//Yes. This is on purpose
2352                }
2353                delete iv;
2354                delete ivNull;
2355        }
2356        //Remove duplicates of rows
2357//      posRowsArray=NULL;
2358//      num_alloc=0;
2359//      num_elts=0;
2360//      offset=0;
2361//      int num_newRows = ddineq->rowsize;
2362//      for(int ii=0;ii<ddineq->rowsize-1;ii++)
2363//      for(int ii=0;ii<num_newRows-1;ii++)
2364//      {
2365//              intvec *iv = new intvec(this->numVars);//1st vector to check against
2366//              for(int jj=0;jj<this->numVars;jj++)
2367//                      (*iv)[jj]=(int)mpq_get_d(ddineq->matrix[ii][jj+1]);
2368//              for(int jj=ii+1;jj</*ddineq->rowsize*/num_newRows;jj++)
2369//              {
2370//                      intvec *ivCheck = new intvec(this->numVars);//Checked against iv
2371//                      for(int kk=0;kk<this->numVars;kk++)
2372//                              (*ivCheck)[kk]=(int)mpq_get_d(ddineq->matrix[jj][kk+1]);
2373//                      if (iv->compare(ivCheck)==0)
2374//                      {
2375// //                           cout << "=" << endl;
2376// //                           num_alloc++;
2377// //                           void *tmp=realloc(posRowsArray,(num_alloc*sizeof(int)));
2378// //                           if(!tmp)
2379// //                           {
2380// //                                   WerrorS("Woah dude! Couldn't realloc memory\n");
2381// //                                   exit(-1);
2382// //                           }
2383// //                           posRowsArray = (int*)tmp;
2384// //                           posRowsArray[num_elts]=jj;
2385// //                           num_elts++;
2386//                              dd_MatrixRowRemove(&ddineq,jj+1);
2387//                              num_newRows = ddineq->rowsize;
2388//                      }
2389//                      delete ivCheck;
2390//              }
2391//              delete iv;
2392//      }
2393//      for(int ii=0;ii<num_elts;ii++)
2394//      {
2395//              dd_MatrixRowRemove(&ddineq,posRowsArray[ii]+1-offset);
2396//              offset++;
2397//      }
2398//      free(posRowsArray);
2399        //Apply Thm 2.1 of JOTA Vol 53 No 1 April 1987*/       
2400}//preprocessInequalities
2401       
2402/** \brief Compute a Groebner Basis
2403 *
2404 * Computes the Groebner basis and stores the result in gcone::gcBasis
2405 *\param ideal
2406 *\return void
2407 */
2408inline void gcone::getGB(const ideal &inputIdeal)               
2409{
2410        BITSET save=test;
2411        test|=Sy_bit(OPT_REDSB);
2412        test|=Sy_bit(OPT_REDTAIL);
2413        ideal gb;
2414        gb=kStd(inputIdeal,NULL,testHomog,NULL);
2415        idNorm(gb);
2416        idSkipZeroes(gb);
2417        this->gcBasis=gb;       //write the GB into gcBasis
2418        test=save;
2419}//void getGB
2420               
2421/** \brief Compute the negative of a given intvec
2422        */             
2423static intvec* ivNeg(const intvec *iv)
2424{       //Hm, switching to intvec const intvec does no longer work
2425        intvec *res;// = new intvec(iv->length());
2426        res=ivCopy(iv);
2427        *res *= (int)-1;                                               
2428        return res;
2429}
2430
2431
2432/** \brief Compute the dot product of two intvecs
2433*
2434*/
2435static int dotProduct(const intvec &iva, const intvec &ivb)                             
2436{                       
2437        int res=0;     
2438        for (int i=0;i<pVariables;i++)
2439        {
2440// #ifndef NDEBUG
2441//      (const_cast<intvec*>(&iva))->show(1,0); (const_cast<intvec*>(&ivb))->show(1,0);
2442// #endif
2443                res = res+(iva[i]*ivb[i]);
2444        }
2445        return res;
2446}
2447/** \brief Check whether two intvecs are parallel
2448 *
2449 * \f$ \alpha\parallel\beta\Leftrightarrow\langle\alpha,\beta\rangle^2=\langle\alpha,\alpha\rangle\langle\beta,\beta\rangle \f$
2450 */
2451static bool isParallel(const intvec &a,const intvec &b)
2452{       
2453/*#ifdef gfanp 
2454        timeval start, end;
2455        gettimeofday(&start, 0);
2456#endif*/               
2457        int lhs,rhs;
2458        bool res;
2459        lhs=dotProduct(a,b)*dotProduct(a,b);
2460        rhs=dotProduct(a,a)*dotProduct(b,b);
2461                        //cout << "LHS="<<lhs<<", RHS="<<rhs<<endl;
2462        if (lhs==rhs)
2463        {
2464                res = TRUE;
2465        }
2466        else
2467        {
2468                res = FALSE;
2469        }
2470// #ifdef gfanp
2471//      gettimeofday(&end, 0);
2472//      t_isParallel += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
2473// #endif       
2474        return res;
2475}//bool isParallel
2476
2477/** \brief Compute an interior point of a given cone
2478 * Result will be written into intvec iv.
2479 * Any rational point is automatically converted into an integer.
2480 */
2481void gcone::interiorPoint( dd_MatrixPtr &M, intvec &iv) //no const &M here since we want to remove redundant rows
2482{
2483        dd_LPPtr lp,lpInt;
2484        dd_ErrorType err=dd_NoError;
2485        dd_LPSolverType solver=dd_DualSimplex;
2486        dd_LPSolutionPtr lpSol=NULL;
2487        dd_rowset ddlinset,ddredrows;   //needed for dd_FindRelativeInterior
2488        dd_rowindex ddnewpos;
2489        dd_NumberType numb;     
2490        //M->representation=dd_Inequality;
2491                       
2492        //NOTE: Make this n-dimensional!
2493        //dd_set_si(M->rowvec[0],1);dd_set_si(M->rowvec[1],1);dd_set_si(M->rowvec[2],1);
2494                                                                       
2495        /*NOTE: Leave the following line commented out!
2496        * Otherwise it will slow down computations a great deal
2497        * */
2498//      dd_MatrixCanonicalizeLinearity(&M, &ddlinset, &ddnewpos, &err);
2499        //if (err!=dd_NoError){cout << "Error during dd_MatrixCanonicalize" << endl;}
2500        dd_MatrixPtr posRestr=dd_CreateMatrix(this->numVars,this->numVars+1);
2501        int jj=1;
2502        for (int ii=0;ii<this->numVars;ii++)
2503        {
2504                dd_set_si(posRestr->matrix[ii][jj],1);
2505                jj++;                                                   
2506        }
2507        dd_MatrixAppendTo(&M,posRestr);
2508        dd_FreeMatrix(posRestr);
2509        lp=dd_Matrix2LP(M, &err);
2510        if (err!=dd_NoError){WerrorS("Error during dd_Matrix2LP in gcone::interiorPoint");}
2511        if (lp==NULL){WerrorS("LP is NULL");}
2512#ifdef gfan_DEBUG
2513//                      dd_WriteLP(stdout,lp);
2514#endif 
2515                                       
2516        lpInt=dd_MakeLPforInteriorFinding(lp);
2517        if (err!=dd_NoError){WerrorS("Error during dd_MakeLPForInteriorFinding in gcone::interiorPoint");}
2518#ifdef gfan_DEBUG
2519//                      dd_WriteLP(stdout,lpInt);
2520#endif                 
2521//      dd_FindRelativeInterior(M,&ddlinset,&ddredrows,&lpSol,&err);
2522        if (err!=dd_NoError)
2523        {
2524                WerrorS("Error during dd_FindRelativeInterior in gcone::interiorPoint");
2525                dd_WriteErrorMessages(stdout, err);
2526        }                       
2527        dd_LPSolve(lpInt,solver,&err);  //This will not result in a point from the relative interior
2528//      if (err!=dd_NoError){WerrorS("Error during dd_LPSolve");}                                                                       
2529        lpSol=dd_CopyLPSolution(lpInt);
2530//      if (err!=dd_NoError){WerrorS("Error during dd_CopyLPSolution");}
2531#ifdef gfan_DEBUG
2532        printf("Interior point: ");
2533        for (int ii=1; ii<(lpSol->d)-1;ii++)
2534        {
2535                dd_WriteNumber(stdout,lpSol->sol[ii]);
2536        }
2537        printf("\n");
2538#endif                 
2539        //NOTE The following strongly resembles parts of makeInt.
2540        //Maybe merge sometimes
2541        mpz_t kgV; mpz_init(kgV);
2542        mpz_set_str(kgV,"1",10);
2543        mpz_t den; mpz_init(den);
2544        mpz_t tmp; mpz_init(tmp);
2545        mpq_get_den(tmp,lpSol->sol[1]);
2546        for (int ii=1;ii<(lpSol->d)-1;ii++)
2547        {
2548                mpq_get_den(den,lpSol->sol[ii+1]);
2549                mpz_lcm(kgV,tmp,den);
2550                mpz_set(tmp, kgV);
2551        }
2552        mpq_t qkgV;
2553        mpq_init(qkgV);
2554        mpq_set_z(qkgV,kgV);
2555        for (int ii=1;ii<(lpSol->d)-1;ii++)
2556        {
2557                mpq_t product;
2558                mpq_init(product);
2559                mpq_mul(product,qkgV,lpSol->sol[ii]);
2560                iv[ii-1]=(int)mpz_get_d(mpq_numref(product));
2561                mpq_clear(product);
2562        }
2563#ifdef gfan_DEBUG
2564//                      iv.show();
2565//                      cout << endl;
2566#endif
2567        mpq_clear(qkgV);
2568        mpz_clear(tmp);
2569        mpz_clear(den);
2570        mpz_clear(kgV);                 
2571                       
2572        dd_FreeLPSolution(lpSol);
2573        dd_FreeLPData(lpInt);
2574        dd_FreeLPData(lp);
2575//      set_free(ddlinset);
2576//      set_free(ddredrows);   
2577                       
2578}//void interiorPoint(dd_MatrixPtr const &M)
2579
2580/** Computes an interior point of a cone by taking two interior points a,b from two different facets
2581* and then computing b+(a-b)/2
2582* Of course this only works for flippable facets
2583* Two cases may occur:
2584* 1st: There are only two facets who share the only strictly positive ray
2585* 2nd: There are at least two facets which have a distinct positive ray
2586* In the former case we use linear algebra to determine an interior point,
2587* in the latter case we simply add up the two rays
2588*
2589* Way too bad! The case may occur that the cone is spanned by three rays, of which only two are strictly
2590* positive => these lie in a plane and thus their sum is not from relative interior.
2591* So let's just sum up all rays, find one strictly positive and shift the point along that ray
2592*
2593* Used by noRevS
2594*NOTE no longer used nor maintained. MM Mar 9, 2010
2595*/
2596// void gcone::interiorPoint2()
2597// {//idPrint(this->gcBasis);
2598// #ifdef gfan_DEBUG
2599//      if(this->ivIntPt!=NULL)
2600//              WarnS("Interior point already exists - ovrewriting!");
2601// #endif
2602//      facet *f1 = this->facetPtr;
2603//      facet *f2 = NULL;
2604//      intvec *intF1=NULL;
2605//      while(f1!=NULL)
2606//      {
2607//              if(f1->isFlippable)
2608//              {
2609//                      facet *f1Ray = f1->codim2Ptr;
2610//                      while(f1Ray!=NULL)
2611//                      {
2612//                              const intvec *check=f1Ray->getRef2FacetNormal();
2613//                              if(iv64isStrictlyPositive(check))
2614//                              {
2615//                                      intF1=ivCopy(check);
2616//                                      break;
2617//                              }                               
2618//                              f1Ray=f1Ray->next;
2619//                      }
2620//              }
2621//              if(intF1!=NULL)
2622//                      break;
2623//              f1=f1->next;
2624//      }
2625//      if(f1!=NULL && f1->next!=NULL)//Choose another facet, different from f1
2626//              f2=f1->next;
2627//      else
2628//              f2=this->facetPtr;
2629//      if(intF1==NULL && hasHomInput==TRUE)
2630//      {
2631//              intF1 = new intvec(this->numVars);
2632//              for(int ii=0;ii<this->numVars;ii++)
2633//                      (*intF1)[ii]=1;
2634//      }
2635//      assert(f1); assert(f2);
2636//      intvec *intF2=f2->getInteriorPoint();
2637//      mpq_t *qPosRay = new mpq_t[this->numVars];//The positive ray from above
2638//      mpq_t *qIntPt = new mpq_t[this->numVars];//starting vector a+((b-a)/2)
2639//      mpq_t *qPosIntPt = new mpq_t[this->numVars];//This should be >0 eventually
2640//      for(int ii=0;ii<this->numVars;ii++)
2641//      {
2642//              mpq_init(qPosRay[ii]);
2643//              mpq_init(qIntPt[ii]);
2644//              mpq_init(qPosIntPt[ii]);
2645//      }       
2646//      //Compute a+((b-a)/2) && Convert intF1 to mpq
2647//      for(int ii=0;ii<this->numVars;ii++)
2648//      {
2649//              mpq_t a,b;
2650//              mpq_init(a); mpq_init(b);
2651//              mpq_set_si(a,(*intF1)[ii],1);
2652//              mpq_set_si(b,(*intF2)[ii],1);
2653//              mpq_t diff;
2654//              mpq_init(diff);
2655//              mpq_sub(diff,b,a);      //diff=b-a
2656//              mpq_t quot;
2657//              mpq_init(quot);
2658//              mpq_div_2exp(quot,diff,1);      //quot=diff/2=(b-a)/2
2659//              mpq_clear(diff);
2660//              //Don't be clever and reuse diff here
2661//              mpq_t sum; mpq_init(sum);
2662//              mpq_add(sum,b,quot);    //sum=b+quot=a+(b-a)/2
2663//              mpq_set(qIntPt[ii],sum);
2664//              mpq_clear(sum);
2665//              mpq_clear(quot);
2666//              mpq_clear(a); mpq_clear(b);
2667//              //Now for intF1
2668//              mpq_set_si(qPosRay[ii],(*intF1)[ii],1);
2669//      }
2670//      //Now add: qPosIntPt=qPosRay+qIntPt until qPosIntPt >0
2671//      while(TRUE)
2672//      {       
2673//              bool success=FALSE;
2674//              int posCtr=0;   
2675//              for(int ii=0;ii<this->numVars;ii++)
2676//              {
2677//                      mpq_t sum; mpq_init(sum);
2678//                      mpq_add(sum,qPosRay[ii],qIntPt[ii]);
2679//                      mpq_set(qPosIntPt[ii],sum);
2680//                      mpq_clear(sum);
2681//                      if(mpq_sgn(qPosIntPt[ii])==1)
2682//                              posCtr++;
2683//              }
2684//              if(posCtr==this->numVars)//qPosIntPt > 0
2685//                      break;
2686//              else
2687//              {
2688//                      mpq_t qTwo; mpq_init(qTwo);
2689//                      mpq_set_ui(qTwo,2,1);
2690//                      for(int jj=0;jj<this->numVars;jj++)
2691//                      {
2692//                              mpq_t tmp; mpq_init(tmp);
2693//                              mpq_mul(tmp,qPosRay[jj],qTwo);
2694//                              mpq_set( qPosRay[jj], tmp);
2695//                              mpq_clear(tmp);
2696//                      }
2697//                      mpq_clear(qTwo);
2698//              }
2699//      }//while
2700//      //Now qPosIntPt ought to be >0, so convert back to int :D
2701//      /*Compute lcm of the denominators*/
2702//      mpz_t *denom = new mpz_t[this->numVars];
2703//      mpz_t tmp,kgV;
2704//      mpz_init(tmp); mpz_init(kgV);
2705//      for (int ii=0;ii<this->numVars;ii++)
2706//      {
2707//              mpz_t z;
2708//              mpz_init(z);
2709//              mpq_get_den(z,qPosIntPt[ii]);
2710//              mpz_init(denom[ii]);
2711//              mpz_set( denom[ii], z);
2712//              mpz_clear(z);                           
2713//      }
2714//             
2715//      mpz_set(tmp,denom[0]);
2716//      for (int ii=0;ii<this->numVars;ii++)
2717//      {
2718//              mpz_lcm(kgV,tmp,denom[ii]);
2719//              mpz_set(tmp,kgV);                               
2720//      }
2721//      mpz_clear(tmp);
2722//      /*Multiply the nominators by kgV*/
2723//      mpq_t qkgV,res;
2724//      mpq_init(qkgV);
2725//      mpq_canonicalize(qkgV);         
2726//      mpq_init(res);
2727//      mpq_canonicalize(res);
2728//                             
2729//      mpq_set_num(qkgV,kgV);
2730//      intvec *n=new intvec(this->numVars);
2731//      for (int ii=0;ii<this->numVars;ii++)
2732//      {
2733//              mpq_canonicalize(qPosIntPt[ii]);
2734//              mpq_mul(res,qkgV,qPosIntPt[ii]);
2735//              (*n)[ii]=(int)mpz_get_d(mpq_numref(res));
2736//      }
2737//      this->setIntPoint(n);
2738//      delete n;
2739//      delete [] qPosIntPt;
2740//      delete [] denom;
2741//      delete [] qPosRay;
2742//      delete [] qIntPt;
2743//      mpz_clear(kgV);
2744//      mpq_clear(qkgV); mpq_clear(res);
2745// }
2746       
2747/** \brief Copy a ring and add a weighted ordering in first place
2748 *
2749 */
2750ring gcone::rCopyAndAddWeight(const ring &r, intvec *ivw)                               
2751{
2752        ring res=rCopy0(r);
2753        int jj;
2754                       
2755        omFree(res->order);
2756        res->order =(int *)omAlloc0(4*sizeof(int));
2757        omFree(res->block0);
2758        res->block0=(int *)omAlloc0(4*sizeof(int));
2759        omFree(res->block1);
2760        res->block1=(int *)omAlloc0(4*sizeof(int));
2761        omfree(res->wvhdl);
2762        res->wvhdl =(int **)omAlloc0(4*sizeof(int**));
2763                       
2764        res->order[0]=ringorder_a;
2765        res->block0[0]=1;
2766        res->block1[0]=res->N;;
2767        res->order[1]=ringorder_dp;     //basically useless, since that should never be used                   
2768        res->block0[1]=1;
2769        res->block1[1]=res->N;;
2770        res->order[2]=ringorder_C;
2771
2772        int length=ivw->length();
2773        int *A=(int *)omAlloc0(length*sizeof(int));
2774        for (jj=0;jj<length;jj++)
2775        {                               
2776                A[jj]=(*ivw)[jj];                               
2777        }                       
2778        res->wvhdl[0]=(int *)A;
2779        res->block1[0]=length;
2780                       
2781        rComplete(res);
2782        return res;
2783}//rCopyAndAdd
2784               
2785ring gcone::rCopyAndAddWeight2(const ring &r,const intvec *ivw, const intvec *fNormal)                         
2786{
2787        ring res=rCopy0(r);
2788                       
2789        omFree(res->order);
2790        res->order =(int *)omAlloc0(5*sizeof(int));
2791        omFree(res->block0);
2792        res->block0=(int *)omAlloc0(5*sizeof(int));
2793        omFree(res->block1);
2794        res->block1=(int *)omAlloc0(5*sizeof(int));
2795        omfree(res->wvhdl);
2796        res->wvhdl =(int **)omAlloc0(5*sizeof(int**));
2797                       
2798        res->order[0]=ringorder_a;
2799        res->block0[0]=1;
2800        res->block1[0]=res->N;
2801        res->order[1]=ringorder_a;
2802        res->block0[1]=1;
2803        res->block1[1]=res->N;
2804       
2805        res->order[2]=ringorder_dp;
2806        res->block0[2]=1;
2807        res->block1[2]=res->N;
2808       
2809        res->order[3]=ringorder_C;
2810
2811        int length=ivw->length();
2812        int *A1=(int *)omAlloc0(length*sizeof(int));
2813        int *A2=(int *)omAlloc0(length*sizeof(int));
2814        for (int jj=0;jj<length;jj++)
2815        {                               
2816                A1[jj]=(*ivw)[jj];
2817                A2[jj]=-(*fNormal)[jj];
2818        }                       
2819        res->wvhdl[0]=(int *)A1;
2820        res->block1[0]=length;
2821        res->wvhdl[1]=(int *)A2;
2822        res->block1[1]=length;
2823        rComplete(res);
2824        return res;
2825}
2826               
2827//NOTE not needed anywhere
2828// ring rCopyAndChangeWeight(ring const &r, intvec *ivw)
2829// {
2830//      ring res=rCopy0(currRing);
2831//      rComplete(res);
2832//      rSetWeightVec(res,(int64*)ivw);
2833//      //rChangeCurrRing(rnew);
2834//      return res;
2835// }
2836               
2837/** \brief Checks whether a given facet is a search facet
2838 * Determines whether a given facet of a cone is the search facet of a neighbouring cone
2839 * This is done in the following way:
2840 * We loop through all facets of the cone and find the "smallest" facet, i.e. the unique facet
2841 * that is first crossed during the generic walk.
2842 * We then check whether the fNormal of this facet is parallel to the fNormal of our testfacet.
2843 * If this is the case, then our facet is indeed a search facet and TRUE is retuned.
2844*/
2845//removed with r12286
2846               
2847/** \brief Check for equality of two intvecs
2848 */
2849static bool ivAreEqual(const intvec &a, const intvec &b)
2850{
2851        bool res=TRUE;
2852        for(int ii=0;ii<pVariables;ii++)
2853        {
2854                if(a[ii]!=b[ii])
2855                {
2856                        res=FALSE;
2857                        break;
2858                }
2859        }
2860        return res;
2861}
2862               
2863/** \brief The reverse search algorithm
2864 */
2865//removed with r12286
2866/** \brief Compute the lineality/homogeneity space
2867* It is the kernel of the inequality matrix Ax=0
2868* As a result gcone::dd_LinealitySpace is set
2869*/
2870dd_MatrixPtr gcone::computeLinealitySpace()
2871{
2872        dd_MatrixPtr res;
2873        dd_MatrixPtr ddineq;
2874        ddineq=dd_CopyMatrix(this->ddFacets);   
2875        //Add a row of 0s in 0th place
2876        dd_MatrixPtr ddAppendRowOfZeroes=dd_CreateMatrix(1,this->numVars+1);
2877        dd_MatrixPtr ddFoo=dd_AppendMatrix(ddAppendRowOfZeroes,ddineq);
2878        dd_FreeMatrix(ddAppendRowOfZeroes);
2879        dd_FreeMatrix(ddineq);
2880        ddineq=dd_CopyMatrix(ddFoo);
2881        dd_FreeMatrix(ddFoo);
2882        //Cohen starts here
2883        int dimKer=0;//Cohen calls this r
2884        int m=ddineq->rowsize;//Rows
2885        int n=ddineq->colsize;//Cols
2886        int c[m+1];
2887        int d[n+1];
2888        for(int ii=0;ii<m;ii++)
2889                c[ii]=0;
2890        for(int ii=0;ii<n;ii++)
2891                d[ii]=0;       
2892       
2893        for(int k=1;k<n;k++)
2894        {
2895                //Let's find a j s.t. m[j][k]!=0 && c[j]=0             
2896                int condCtr=0;//Check each row for zeroness
2897                for(int j=1;j<m;j++)
2898                {
2899                        if(mpq_sgn(ddineq->matrix[j][k])!=0 && c[j]==0)
2900                        {
2901                                mpq_t quot; mpq_init(quot);
2902                                mpq_t one; mpq_init(one); mpq_set_str(one,"-1",10);
2903                                mpq_t ratd; mpq_init(ratd);
2904                                if((int)mpq_get_d(ddineq->matrix[j][k])!=0)
2905                                        mpq_div(quot,one,ddineq->matrix[j][k]);
2906                                mpq_set(ratd,quot);
2907                                mpq_canonicalize(ratd);
2908               
2909                                mpq_set_str(ddineq->matrix[j][k],"-1",10);
2910                                for(int ss=k+1;ss<n;ss++)
2911                                {
2912                                        mpq_t prod; mpq_init(prod);
2913                                        mpq_mul(prod, ratd, ddineq->matrix[j][ss]);                             
2914                                        mpq_set(ddineq->matrix[j][ss],prod);
2915                                        mpq_canonicalize(ddineq->matrix[j][ss]);
2916                                        mpq_clear(prod);
2917                                }               
2918                                for(int ii=1;ii<m;ii++)
2919                                {
2920                                        if(ii!=j)
2921                                        {
2922                                                mpq_set(ratd,ddineq->matrix[ii][k]);
2923                                                mpq_set_str(ddineq->matrix[ii][k],"0",10);                     
2924                                                for(int ss=k+1;ss<n;ss++)
2925                                                {
2926                                                        mpq_t prod; mpq_init(prod);
2927                                                        mpq_mul(prod, ratd, ddineq->matrix[j][ss]);
2928                                                        mpq_t sum; mpq_init(sum);
2929                                                        mpq_add(sum, ddineq->matrix[ii][ss], prod);
2930                                                        mpq_set(ddineq->matrix[ii][ss], sum);
2931                                                        mpq_canonicalize(ddineq->matrix[ii][ss]);
2932                                                        mpq_clear(prod);
2933                                                        mpq_clear(sum);
2934                                                }
2935                                        }
2936                                }
2937                                c[j]=k;         
2938                                d[k]=j;
2939                                mpq_clear(quot); mpq_clear(ratd); mpq_clear(one);       
2940                        }
2941                        else
2942                                condCtr++;
2943                }                       
2944                if(condCtr==m-1)        //Why -1 ???
2945                {
2946                        dimKer++;
2947                        d[k]=0;
2948//                      break;//goto _4;
2949                }//else{
2950                /*Eliminate*/
2951        }//for(k
2952        /*Output kernel, i.e. set gcone::dd_LinealitySpace here*/       
2953//      gcone::dd_LinealitySpace = dd_CreateMatrix(dimKer,this->numVars+1);
2954        res = dd_CreateMatrix(dimKer,this->numVars+1);
2955        int row=-1;
2956        for(int kk=1;kk<n;kk++)
2957        {
2958                if(d[kk]==0)
2959                {
2960                        row++;
2961                        for(int ii=1;ii<n;ii++)
2962                        {
2963                                if(d[ii]>0)
2964                                        mpq_set(res->matrix[row][ii],ddineq->matrix[d[ii]][kk]);
2965                                else if(ii==kk)                         
2966                                        mpq_set_str(res->matrix[row][ii],"1",10);
2967                                mpq_canonicalize(res->matrix[row][ii]);
2968                        }
2969                }
2970        }
2971        dd_FreeMatrix(ddineq);
2972        return(res);
2973        //Better safe than sorry:
2974        //NOTE dd_LinealitySpace contains RATIONAL ENTRIES
2975        //Therefore if you need integer ones: CALL gcone::makeInt(...) method
2976}       
2977
2978
2979/** \brief The new method of Markwig and Jensen
2980 * Compute gcBasis and facets for the arbitrary starting cone. Store \f$(codim-1)\f$-facets as normals.
2981 * In order to represent a facet uniquely compute also the \f$(codim-2)\f$-facets and norm by the gcd of the components.
2982 * Keep a list of facets as a linked list containing an intvec and an integer matrix.
2983 * Since a \f$(codim-1)\f$-facet belongs to exactly two full dimensional cones, we remove a facet from the list as
2984 * soon as we compute this facet again. Comparison of facets is done by...
2985 */
2986void gcone::noRevS(gcone &gcRoot, bool usingIntPoint)
2987{       
2988        facet *SearchListRoot = new facet(); //The list containing ALL facets we come across
2989//      vector<facet> stlRoot;
2990        facet *SearchListAct;
2991        SearchListAct = NULL;
2992        //SearchListAct = SearchListRoot;
2993                       
2994        gcone *gcAct;
2995        gcAct = &gcRoot;
2996        gcone *gcPtr;   //Pointer to end of linked list of cones
2997        gcPtr = &gcRoot;
2998        gcone *gcNext;  //Pointer to next cone to be visited
2999        gcNext = &gcRoot;
3000        gcone *gcHead;
3001        gcHead = &gcRoot;
3002                       
3003        facet *fAct;
3004        fAct = gcAct->facetPtr;                 
3005                       
3006        ring rAct;
3007        rAct = currRing;
3008                                               
3009        int UCNcounter=gcAct->getUCN();
3010       
3011#ifdef gfan_DEBUG
3012        printf("NoRevs\n");
3013        printf("Facets are:\n");
3014        gcAct->showFacets();
3015#endif                 
3016        /*Compute lineality space here
3017        * Afterwards static dd_MatrixPtr gcone::dd_LinealitySpace is set*/
3018        if(dd_LinealitySpace==NULL)
3019                dd_LinealitySpace = gcAct->computeLinealitySpace();
3020        /*End of lineality space computation*/         
3021//      gcAct->getCodim2Normals(*gcAct);
3022        if(fAct->codim2Ptr==NULL)
3023                gcAct->getExtremalRays(*gcAct);
3024                               
3025        //Compute unique representation of Facets and rays, i.e. primitive vectors
3026//      gcAct->normalize();
3027                       
3028        /* Make a copy of the facet list of first cone
3029           Since the operations getCodim2Normals and normalize affect the facets
3030           we must not memcpy them before these ops! */ 
3031        /*facet *codim2Act; codim2Act = NULL;                   
3032        facet *sl2Root;
3033        facet *sl2Act;*/                       
3034        for(int ii=0;ii<this->numFacets;ii++)
3035        {
3036                //only copy flippable facets! NOTE: We do not need flipRing or any such information.
3037                if(fAct->isFlippable==TRUE)
3038                {
3039                        /*Using shallow copy here*/
3040#ifdef SHALLOW
3041                        if( ii==0 || (ii>0 && SearchListAct==NULL) ) //1st facet may be non-flippable
3042                        {
3043                                if(SearchListRoot!=NULL)
3044                                        delete(SearchListRoot);
3045                                SearchListRoot = fAct->shallowCopy(*fAct);
3046                                SearchListAct = SearchListRoot; //SearchListRoot is already 'new'ed at beginning of method!
3047                        }
3048                        else
3049                        {                       
3050                                SearchListAct->next = fAct->shallowCopy(*fAct);
3051                                SearchListAct = SearchListAct->next;                                           
3052                        }
3053                        fAct=fAct->next;
3054#else
3055                        /*End of shallow copy*/
3056                        intvec *fNormal;
3057                        fNormal = fAct->getFacetNormal();
3058                        if( ii==0 || (ii>0 && SearchListAct==NULL) ) //1st facet may be non-flippable
3059                        {                                               
3060                                SearchListAct = SearchListRoot; //SearchListRoot is already 'new'ed at beginning of method!
3061                        }
3062                        else
3063                        {                       
3064                                SearchListAct->next = new facet();
3065                                SearchListAct = SearchListAct->next;                                           
3066                        }
3067                        SearchListAct->setFacetNormal(fNormal);
3068                        SearchListAct->setUCN(this->getUCN());
3069                        SearchListAct->numCodim2Facets=fAct->numCodim2Facets;
3070                        SearchListAct->isFlippable=TRUE;
3071                        //Copy int point as well
3072                        intvec *ivIntPt;// = new intvec(this->numVars);
3073                        ivIntPt = fAct->getInteriorPoint();
3074                        SearchListAct->setInteriorPoint(ivIntPt);
3075                        delete(ivIntPt);
3076                        //Copy codim2-facets
3077                        facet *codim2Act;
3078                        codim2Act = NULL;                       
3079                        facet *sl2Root;
3080                        facet *sl2Act;                 
3081                        codim2Act=fAct->codim2Ptr;
3082                        SearchListAct->codim2Ptr = new facet(2);
3083                        sl2Root = SearchListAct->codim2Ptr;
3084                        sl2Act = sl2Root;
3085                                        //while(codim2Act!=NULL)
3086                        for(int jj=0;jj<fAct->numCodim2Facets;jj++)
3087//                      for(int jj=0;jj<fAct->numRays-1;jj++)
3088                        {
3089                                intvec *f2Normal;
3090                                f2Normal = codim2Act->getFacetNormal();
3091                                if(jj==0)
3092                                {                                               
3093                                        sl2Act = sl2Root;
3094                                        sl2Act->setFacetNormal(f2Normal);
3095                                }
3096                                else
3097                                {
3098                                        sl2Act->next = new facet(2);
3099                                        sl2Act = sl2Act->next;
3100                                        sl2Act->setFacetNormal(f2Normal);
3101                                }
3102                                delete f2Normal;                               
3103                                codim2Act = codim2Act->next;
3104                        }
3105                        fAct = fAct->next;
3106                        delete fNormal;
3107#endif
3108                }//if(fAct->isFlippable==TRUE)                 
3109                else {fAct = fAct->next;}
3110        }//End of copying facets into SLA
3111       
3112        SearchListAct = SearchListRoot; //Set to beginning of list
3113        /*Make SearchList doubly linked*/
3114#ifndef NDEBUG
3115  #if SIZEOF_LONG==8
3116        while(SearchListAct!=(facet*)0xfefefefefefefefe && SearchListAct!=NULL)
3117        {
3118                if(SearchListAct->next!=(facet*)0xfefefefefefefefe && SearchListAct->next!=NULL){
3119  #elif SIZEOF_LONG!=8
3120        while(SearchListAct!=(facet*)0xfefefefe)
3121        {
3122                if(SearchListAct->next!=(facet*)0xfefefefe){
3123  #endif
3124#else
3125        while(SearchListAct!=NULL)
3126        {
3127                if(SearchListAct->next!=NULL){
3128#endif
3129//              if(SearchListAct->next!=NULL)
3130//              {
3131                        SearchListAct->next->prev = SearchListAct;                                     
3132                }
3133                SearchListAct = SearchListAct->next;
3134        }
3135        SearchListAct = SearchListRoot; //Set to beginning of List
3136       
3137//      fAct = gcAct->facetPtr;//???
3138        gcAct->writeConeToFile(*gcAct);                 
3139        /*End of initialisation*/
3140       
3141        fAct = SearchListAct;
3142        /*2nd step
3143          Choose a facet from SearchList, flip it and forget the previous cone
3144          We always choose the first facet from SearchList as facet to be flipped
3145        */     
3146        while( (SearchListAct!=NULL))//&& counter<490)
3147        {//NOTE See to it that the cone is only changed after ALL facets have been flipped!                             
3148                fAct = SearchListAct;           
3149                while(fAct!=NULL)
3150//              while( (fAct->getUCN() == fAct->next->getUCN()) )               
3151                {       //Since SLA should only contain flippables there should be no need to check for that                   
3152                        gcAct->flip2(gcAct->gcBasis,fAct);
3153                        //NOTE rCopy needed?
3154                        ring rTmp=rCopy(fAct->flipRing);
3155//                      ring rTmp=fAct->flipRing; //segfaults
3156                        rComplete(rTmp);
3157                        rChangeCurrRing(rTmp);
3158                        gcone *gcTmp = new gcone::gcone(*gcAct,*fAct);//copy constructor!
3159                        /* Now gcTmp->gcBasis and gcTmp->baseRing are set from fAct->flipGB and fAct->flipRing.
3160                         * Since we come at most once across a given facet from gcAct->facetPtr we can delete them.
3161                         * NOTE: Can this cause trouble with the destructor?
3162                         * Answer: Yes it bloody well does!
3163                         * However I'd like to delete this data here, since if we have a cone with many many facets it
3164                         * should pay to get rid of the flipGB as soon as possible.
3165                         * Destructor must be equipped with necessary checks.
3166                        */
3167                        idDelete((ideal *)&fAct->flipGB);
3168                        rDelete(fAct->flipRing);
3169                       
3170                        gcTmp->getConeNormals(gcTmp->gcBasis/*, FALSE*/);       //TODO FALSE is default, so should not be needed here
3171//                      gcTmp->getCodim2Normals(*gcTmp);
3172                        gcTmp->getExtremalRays(*gcTmp);
3173                       
3174//                      //NOTE If flip2 is used we need to get an interior point of gcTmp
3175//                      // and replace gcTmp->baseRing with an appropriate ring with only
3176//                      // one weight
3177//                      gcTmp->interiorPoint2();
3178                        gcTmp->replaceDouble_ringorder_a_ByASingleOne();
3179                        //gcTmp->ddFacets should not be needed anymore, so
3180                        dd_FreeMatrix(gcTmp->ddFacets);
3181#ifdef gfan_DEBUG
3182//                      gcTmp->showFacets(1);
3183#endif
3184                        /*add facets to SLA here*/
3185#ifdef SHALLOW
3186//                      printf("fActUCN before enq2: %i\n",fAct->getUCN());
3187                        facet *tmp; tmp=gcTmp->enqueue2(SearchListRoot);
3188//                      printf("\nheadUCN=%i\n",tmp->getUCN());
3189//                      printf("fActUCN after enq2: %i\n",fAct->getUCN());                     
3190                        SearchListRoot=tmp;
3191//                      SearchListRoot=gcTmp->enqueue2/*NewFacets*/(SearchListRoot);
3192#else
3193                        SearchListRoot=gcTmp->enqueueNewFacets(SearchListRoot);
3194#endif
3195                        gcTmp->writeConeToFile(*gcTmp);
3196                        if(gfanHeuristic==1)
3197                        {
3198//                              gcTmp->writeConeToFile(*gcTmp);
3199                                idDelete((ideal*)&gcTmp->gcBasis);//Whonder why?
3200                                rDelete(gcTmp->baseRing);
3201                        }                       
3202#ifdef gfan_DEBUG
3203                        if(SearchListRoot!=NULL)
3204                                showSLA(*SearchListRoot);
3205#endif                 
3206                        rChangeCurrRing(gcAct->baseRing);
3207                        rDelete(rTmp);
3208                        //doubly linked for easier removal
3209                        gcTmp->prev = gcPtr;
3210                        gcPtr->next=gcTmp;
3211                        gcPtr=gcPtr->next;
3212                        //Cleverly disguised exit condition follows
3213                        if(fAct->getUCN() == fAct->next->getUCN())
3214                        {
3215                                printf("Switching UCN from %i to %i\n",fAct->getUCN(),fAct->next->getUCN());
3216                                fAct=fAct->next;                               
3217                        }
3218                        else
3219                        {
3220                                //rDelete(gcAct->baseRing);
3221//                              printf("break\n");
3222                                break;
3223                        }
3224//                      fAct=fAct->next;
3225                }//while( ( (fAct->next!=NULL) && (fAct->getUCN()==fAct->next->getUCN() ) ) );         
3226                //Search for cone with smallest UCN
3227#ifndef NDEBUG
3228  #if SIZEOF_LONG==8    //64 bit
3229                while(gcNext!=(gcone * const)0xfbfbfbfbfbfbfbfb && SearchListRoot!=NULL)
3230  #elif SIZEOF_LONG == 4
3231                while(gcNext!=(gcone * const)0xfbfbfbfb && SearchListRoot!=NULL)
3232  #endif
3233#endif
3234#ifdef NDEBUG
3235                while(gcNext!=NULL && SearchListRoot!=NULL)     
3236#endif
3237                {                       
3238                        if( gcNext->getUCN() == SearchListRoot->getUCN() )
3239                        {
3240                                if(gfanHeuristic==0)
3241                                {
3242                                        gcAct = gcNext;
3243                                        //Seems better to not to use rCopy here
3244//                                      rAct=rCopy(gcAct->baseRing);
3245                                        rAct=gcAct->baseRing;
3246                                        rComplete(rAct);
3247                                        rChangeCurrRing(rAct);                                         
3248                                        break;
3249                                }
3250                                else if(gfanHeuristic==1)
3251                                {
3252                                        gcone *gcDel;
3253                                        gcDel = gcAct;                                 
3254                                        gcAct = gcNext;
3255                                        //Read st00f from file &
3256                                        //implant the GB into gcAct
3257                                        readConeFromFile(gcAct->getUCN(), gcAct);
3258                                        //Kill the baseRing but ONLY if it is not the ring the computation started in!
3259//                                      if(gcDel->getUCN()!=1)//WTF!? This causes the Mandelbug in gcone::areEqual(facet, facet)
3260//                                              rDelete(gcDel->baseRing);
3261//                                      rAct=rCopy(gcAct->baseRing);
3262                                        /*The ring change occurs in readConeFromFile, so as to
3263                                        assure that gcAct->gcBasis belongs to the right ring*/
3264                                        rAct=gcAct->baseRing;
3265                                        rComplete(rAct);
3266                                        rChangeCurrRing(rAct);
3267                                        break;
3268                                }                               
3269                        }
3270                        else if(gcNext->getUCN() < SearchListRoot->getUCN() )
3271                        {
3272                                idDelete( (ideal*)&gcNext->gcBasis );                           
3273//                              rDelete(gcNext->baseRing);//TODO Why does this crash?
3274                        }
3275                        /*else
3276                        {
3277                                if(gfanHeuristic==1)
3278                                {
3279                                        gcone *gcDel;
3280                                        gcDel = gcNext;
3281                                        if(gcDel->getUCN()!=1)
3282                                                rDelete(gcDel->baseRing);
3283                                }                                       
3284                        }*/                     
3285                        gcNext = gcNext->next;
3286                }
3287                UCNcounter++;
3288                SearchListAct = SearchListRoot;         
3289        }
3290        printf("\nFound %i cones - terminating\n", counter);
3291}//void noRevS(gcone &gc)       
3292               
3293               
3294/** \brief Make a set of rational vectors into integers
3295 *
3296 * We compute the lcm of the denominators and multiply with this to get integer values.
3297 * If the gcd of the nominators > 1 we divide by the gcd => primitive vector.
3298 * Expects a new intvec as 3rd parameter
3299 * \param dd_MatrixPtr,intvec
3300 */
3301void gcone::makeInt(const dd_MatrixPtr &M, const int line, intvec &n)
3302{                       
3303//      mpz_t denom[this->numVars];
3304        mpz_t *denom = new mpz_t[this->numVars];
3305        for(int ii=0;ii<this->numVars;ii++)
3306        {
3307                mpz_init_set_str(denom[ii],"0",10);
3308        }
3309               
3310        mpz_t kgV,tmp;
3311        mpz_init(kgV);
3312        mpz_init(tmp);
3313                       
3314        for (int ii=0;ii<(M->colsize)-1;ii++)
3315        {
3316                mpz_t z;
3317                mpz_init(z);
3318                mpq_get_den(z,M->matrix[line-1][ii+1]);
3319                mpz_set( denom[ii], z);
3320                mpz_clear(z);                           
3321        }
3322                                               
3323        /*Compute lcm of the denominators*/
3324        mpz_set(tmp,denom[0]);
3325        for (int ii=0;ii<(M->colsize)-1;ii++)
3326        {
3327                mpz_lcm(kgV,tmp,denom[ii]);
3328                mpz_set(tmp,kgV);                               
3329        }
3330        mpz_clear(tmp); 
3331        /*Multiply the nominators by kgV*/
3332        mpq_t qkgV,res;
3333        mpq_init(qkgV);
3334        mpq_set_str(qkgV,"1",10);
3335        mpq_canonicalize(qkgV);
3336                       
3337        mpq_init(res);
3338        mpq_set_str(res,"1",10);
3339        mpq_canonicalize(res);
3340                       
3341        mpq_set_num(qkgV,kgV);
3342                       
3343//                      mpq_canonicalize(qkgV);
3344//      int ggT=1;
3345        for (int ii=0;ii<(M->colsize)-1;ii++)
3346        {
3347                mpq_mul(res,qkgV,M->matrix[line-1][ii+1]);
3348                n[ii]=(int)mpz_get_d(mpq_numref(res));
3349//              ggT=intgcd(ggT,n[ii]);
3350        }
3351        int ggT=n[0];
3352        for(int ii=0;ii<this->numVars;ii++)
3353                ggT=intgcd(ggT,n[ii]); 
3354        //Normalization
3355        if(ggT>1)
3356        {
3357                for(int ii=0;ii<this->numVars;ii++)
3358                        n[ii] /= ggT;
3359        }
3360        delete [] denom;
3361        mpz_clear(kgV);
3362        mpq_clear(qkgV); mpq_clear(res);                       
3363                       
3364}
3365/**
3366 * For all codim-2-facets we compute the gcd of the components of the facet normal and
3367 * divide it out. Thus we get a normalized representation of each
3368 * (codim-2)-facet normal, i.e. a primitive vector
3369 * Actually we now also normalize the facet normals.
3370 */
3371// void gcone::normalize()
3372// {
3373//      int *ggT = new int;
3374//              *ggT=1;
3375//      facet *fAct;
3376//      facet *codim2Act;
3377//      fAct = this->facetPtr;
3378//      codim2Act = fAct->codim2Ptr;
3379//      while(fAct!=NULL)
3380//      {
3381//              intvec *fNormal;
3382//              fNormal = fAct->getFacetNormal();
3383//              int *ggT = new int;
3384//              *ggT=1;
3385//              for(int ii=0;ii<this->numVars;ii++)
3386//              {
3387//                      *ggT=intgcd((*ggT),(*fNormal)[ii]);
3388//              }
3389//              if(*ggT>1)//We only need to do this if the ggT is non-trivial
3390//              {
3391// //                   intvec *fCopy = fAct->getFacetNormal();
3392//                      for(int ii=0;ii<this->numVars;ii++)
3393//                              (*fNormal)[ii] = ((*fNormal)[ii])/(*ggT);
3394//                      fAct->setFacetNormal(fNormal);
3395//              }               
3396//              delete fNormal;
3397//              delete ggT;
3398//              /*And now for the codim2*/
3399//              while(codim2Act!=NULL)
3400//              {                               
3401//                      intvec *n;
3402//                      n=codim2Act->getFacetNormal();
3403//                      int *ggT=new int;
3404//                      *ggT=1;
3405//                      for(int ii=0;ii<this->numVars;ii++)
3406//                      {
3407//                              *ggT = intgcd((*ggT),(*n)[ii]);
3408//                      }
3409//                      if(*ggT>1)
3410//                      {
3411//                              for(int ii=0;ii<this->numVars;ii++)
3412//                              {
3413//                                      (*n)[ii] = ((*n)[ii])/(*ggT);
3414//                              }
3415//                              codim2Act->setFacetNormal(n);
3416//                      }
3417//                      codim2Act = codim2Act->next;
3418//                      delete n;
3419//                      delete ggT;
3420//              }
3421//              fAct = fAct->next;
3422//      }
3423// }
3424
3425/** \brief Enqueue new facets into the searchlist
3426 * The searchlist (SLA for short) is implemented as a FIFO
3427 * Checks are done as follows:
3428 * 1) Check facet fAct against all facets in SLA for parallelity. If it is not parallel to any one add it.
3429 * 2) If it is parallel compare the codim2 facets. If they coincide the facets are equal and we delete the
3430 *      facet from SLA and do not add fAct.
3431 * It may very well happen, that SLA=\f$ \emptyset \f$ but we do not have checked all fActs yet. In this case we
3432 * can be sure, that none of the facets that are still there already were in SLA once, so we just dump them into SLA.
3433 * Takes ptr to search list root
3434 * Returns a pointer to new first element of Searchlist
3435 */
3436facet * gcone::enqueueNewFacets(facet *f)
3437{
3438#ifdef gfanp
3439        timeval start, end;
3440        gettimeofday(&start, 0);
3441#endif
3442        facet *slHead;
3443        slHead = f;
3444        facet *slAct;   //called with f=SearchListRoot
3445        slAct = f;
3446        facet *slEnd;   //Pointer to end of SLA
3447        slEnd = f;
3448//      facet *slEndStatic;     //marks the end before a new facet is added             
3449        facet *fAct;
3450        fAct = this->facetPtr;
3451        facet *codim2Act;
3452        codim2Act = this->facetPtr->codim2Ptr;
3453        facet *sl2Act;
3454        sl2Act = f->codim2Ptr;
3455        /** Pointer to a facet that will be deleted */
3456        volatile facet *deleteMarker;
3457        deleteMarker = NULL;
3458                       
3459        /** \brief  Flag to mark a facet that might be added
3460         * The following case may occur:
3461         * A facet fAct is found to be parallel but not equal to the current facet slAct from SLA.
3462         * This does however not mean that there does not exist a facet behind the current slAct that is actually equal
3463         * to fAct. In this case we set the boolean flag maybe to TRUE. If we encounter an equality lateron, it is reset to
3464         * FALSE and the according slAct is deleted.
3465         * If slAct->next==NULL AND maybe==TRUE we know, that fAct must be added
3466         */
3467//      volatile bool maybe=FALSE;
3468        /**A facet was removed, lengthOfSearchlist-- thus we must not rely on
3469         * if(notParallelCtr==lengthOfSearchList) but rather
3470         * if( (notParallelCtr==lengthOfSearchList && removalOccured==FALSE)
3471         */
3472        volatile bool removalOccured=FALSE;
3473//      int ctr=0;      //encountered equalities in SLA
3474//      int notParallelCtr=0;
3475//      gcone::lengthOfSearchList=1;
3476        while(slEnd->next!=NULL)
3477        {
3478                slEnd=slEnd->next;
3479//              gcone::lengthOfSearchList++;
3480        }
3481        /*1st step: compare facetNormals*/                     
3482        while(fAct!=NULL)
3483        {                                               
3484                if(fAct->isFlippable==TRUE)
3485                {
3486                        intvec *fNormal=NULL;
3487                        fNormal=fAct->getFacetNormal();                 
3488                        slAct = slHead;
3489                        //notParallelCtr=0;
3490                        /*If slAct==NULL and fAct!=NULL
3491                        we just copy all remaining facets into SLA*/
3492                        if(slAct==NULL)
3493                        {
3494                                facet *fCopy;
3495                                fCopy = fAct;
3496                                while(fCopy!=NULL)
3497                                {
3498                                        if(fCopy->isFlippable==TRUE)//We must assure fCopy is also flippable
3499                                        {
3500                                                if(slAct==NULL)
3501                                                {
3502                                                        slAct = new facet(*fCopy/*,TRUE*/);//copy constructor
3503                                                        slHead = slAct;                                                         
3504                                                }
3505                                                else
3506                                                {
3507                                                        slAct->next = new facet(*fCopy/*,TRUE*/);
3508                                                        slAct = slAct->next;
3509                                                }
3510                                        }
3511                                        fCopy = fCopy->next;
3512                                }
3513                                break;//Where does this lead to?
3514                        }
3515                        /*End of dumping into SLA*/
3516                        while(slAct!=NULL)
3517                        {
3518                                intvec *slNormal=NULL;
3519                                removalOccured=FALSE;
3520                                slNormal = slAct->getFacetNormal();
3521#ifdef gfan_DEBUG
3522                                printf("Checking facet (");fNormal->show(1,1);printf(") against (");slNormal->show(1,1);printf(")\n");
3523#endif                         
3524//                              if( (areEqual(fAct,slAct) && (!areEqual2(fAct,slAct)) ))
3525//                                      exit(-1);
3526                                if(areEqual2(fAct,slAct))
3527                                {                                       
3528                                        deleteMarker = slAct;
3529                                        if(slAct==slHead)
3530                                        {                                               
3531                                                slHead = slAct->next;                                           
3532                                                if(slHead!=NULL)
3533                                                        slHead->prev = NULL;
3534                                        }
3535                                        else if (slAct==slEnd)
3536                                        {
3537                                                slEnd=slEnd->prev;
3538                                                slEnd->next = NULL;
3539                                        }                                                               
3540                                        else
3541                                        {
3542                                                slAct->prev->next = slAct->next;
3543                                                slAct->next->prev = slAct->prev;
3544                                        }
3545                                        removalOccured=TRUE;
3546                                        gcone::lengthOfSearchList--;
3547                                        if(deleteMarker!=NULL)
3548                                        {
3549//                                              delete deleteMarker;
3550//                                              deleteMarker=NULL;
3551                                        }
3552#ifdef gfan_DEBUG
3553                                        printf("Removing (");fNormal->show(1,1);printf(") from list\n");
3554#endif
3555                                        delete slNormal;
3556                                        break;//leave the while loop, since we found fAct=slAct thus delete slAct and do not add fAct
3557                                }
3558                                slAct = slAct->next;
3559                                /* NOTE The following lines must not be here but rather called inside the if-block above.
3560                                Otherwise results get crappy. Unfortunately there are two slAct=slAct->next calls now,
3561                                (not nice!) but since they are in seperate branches of the if-statement there should not
3562                                be a way it gets called twice thus ommiting one facet:
3563                                slAct = slAct->next;*/
3564                                if(deleteMarker!=NULL)
3565                                {                                               
3566//                                      delete deleteMarker;
3567//                                      deleteMarker=NULL;
3568                                }
3569                                delete slNormal;
3570                                                //if slAct was marked as to be deleted, delete it here!
3571                        }//while(slAct!=NULL)
3572                        if(removalOccured==FALSE)
3573                        {
3574#ifdef gfan_DEBUG
3575//                              cout << "Adding facet (";fNormal->show(1,0);cout << ") to SLA " << endl;
3576#endif
3577                                //Add fAct to SLA
3578                                facet *marker;
3579                                marker = slEnd;
3580                                facet *f2Act;
3581                                f2Act = fAct->codim2Ptr;
3582
3583                                slEnd->next = new facet();
3584                                slEnd = slEnd->next;//Update slEnd
3585                                facet *slEndCodim2Root;
3586                                facet *slEndCodim2Act;
3587                                slEndCodim2Root = slEnd->codim2Ptr;
3588                                slEndCodim2Act = slEndCodim2Root;
3589                                                               
3590                                slEnd->setUCN(this->getUCN());
3591                                slEnd->isFlippable = TRUE;
3592                                slEnd->setFacetNormal(fNormal);
3593                                //NOTE Add interior point here
3594                                //This is ugly but needed for flip2
3595                                //Better: have slEnd->interiorPoint point to fAct->interiorPoint
3596                                //NOTE Only reference -> c.f. copy constructor
3597                                //slEnd->setInteriorPoint(fAct->getInteriorPoint());
3598                                slEnd->interiorPoint = fAct->interiorPoint;
3599                                slEnd->prev = marker;
3600                                //Copy codim2-facets
3601                                //intvec *f2Normal=new intvec(this->numVars);
3602                                while(f2Act!=NULL)
3603                                {
3604                                        intvec *f2Normal;
3605                                        f2Normal=f2Act->getFacetNormal();
3606                                        if(slEndCodim2Root==NULL)
3607                                        {
3608                                                slEndCodim2Root = new facet(2);
3609                                                slEnd->codim2Ptr = slEndCodim2Root;                     
3610                                                slEndCodim2Root->setFacetNormal(f2Normal);
3611                                                slEndCodim2Act = slEndCodim2Root;
3612                                        }
3613                                        else                                   
3614                                        {
3615                                                slEndCodim2Act->next = new facet(2);
3616                                                slEndCodim2Act = slEndCodim2Act->next;
3617                                                slEndCodim2Act->setFacetNormal(f2Normal);
3618                                        }
3619                                        f2Act = f2Act->next;
3620                                        delete f2Normal;
3621                                }
3622                                gcone::lengthOfSearchList++;                                                   
3623                        }//if( (notParallelCtr==lengthOfSearchList && removalOccured==FALSE) ||
3624                        fAct = fAct->next;
3625                        delete fNormal;
3626//                      delete slNormal;
3627                }//if(fAct->isFlippable==TRUE)
3628                else
3629                {
3630                        fAct = fAct->next;
3631                }
3632                if(gcone::maxSize<gcone::lengthOfSearchList)
3633                        gcone::maxSize= gcone::lengthOfSearchList;
3634        }//while(fAct!=NULL)
3635#ifdef gfanp
3636        gettimeofday(&end, 0);
3637        time_enqueue += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
3638#endif                                         
3639        return slHead;
3640}//addC2N
3641
3642/** Try using shallow copies*/
3643facet * gcone::enqueue2(facet *f)
3644{
3645        assert(f!=NULL);
3646#ifdef gfanp
3647        timeval start, end;
3648        gettimeofday(&start, 0);
3649#endif
3650        facet *slHead;
3651        slHead = f;
3652        facet *slAct;   //called with f=SearchListRoot
3653        slAct = f;
3654        static facet *slEnd;    //Pointer to end of SLA
3655        if(slEnd==NULL)
3656                slEnd = f;
3657       
3658        facet *fAct;
3659        fAct = this->facetPtr;//New facets to compare
3660        facet *codim2Act;
3661        codim2Act = this->facetPtr->codim2Ptr;
3662//      facet *sl2Act;
3663//      sl2Act = f->codim2Ptr;
3664        volatile bool removalOccured=FALSE;
3665        while(slEnd->next!=NULL)
3666        {
3667                slEnd=slEnd->next;
3668        }       
3669        while(fAct!=NULL)
3670        {
3671                if(fAct->isFlippable)
3672                {
3673                        facet *fDeleteMarker=NULL;
3674                        slAct = slHead;
3675                        if(slAct==NULL)
3676                        {
3677                                printf("Zero length SLA\n");
3678                                facet *fCopy;
3679                                fCopy = fAct;                           
3680                                while(fCopy!=NULL)
3681                                {
3682                                        if(fCopy->isFlippable==TRUE)//We must assure fCopy is also flippable
3683                                        {
3684                                                if(slAct==NULL)
3685                                                {
3686                                                        slAct = slAct->shallowCopy(*fCopy);//shallow copy constructor
3687                                                        slHead = slAct;                                                         
3688                                                }
3689                                                else
3690                                                {
3691                                                        slAct->next = slAct->shallowCopy(*fCopy);
3692                                                        slAct = slAct->next;
3693                                                }
3694                                        }
3695                                        fCopy = fCopy->next;
3696                                }
3697                                break; 
3698                        }
3699                        /*Comparison starts here*/
3700                        while(slAct!=NULL)
3701                        {
3702                                removalOccured=FALSE;
3703#ifdef gfan_DEBUG
3704        printf("Checking facet (");fAct->fNormal->show(1,1);printf(") against (");slAct->fNormal->show(1,1);printf(")\n");
3705#endif 
3706                                if(areEqual2(fAct,slAct))
3707                                {
3708                                        fDeleteMarker=slAct;
3709                                        if(slAct==slHead)
3710                                        {
3711//                                              fDeleteMarker=slHead;
3712//                                              printf("headUCN@enq=%i\n",slHead->getUCN());
3713                                                slHead = slAct->next;                                           
3714//                                              printf("headUCN@enq=%i\n",slHead->getUCN());
3715                                                if(slHead!=NULL)
3716                                                {
3717                                                        slHead->prev = NULL;
3718                                                }
3719                                                fDeleteMarker->shallowDelete();
3720//                                              delete fDeleteMarker;//NOTE this messes up fAct in noRevS!
3721//                                              printf("headUCN@enq=%i\n",slHead->getUCN());
3722                                        }
3723                                        else if (slAct==slEnd)
3724                                        {
3725                                                slEnd=slEnd->prev;
3726                                                slEnd->next = NULL;
3727                                                fDeleteMarker->shallowDelete();
3728//                                              delete(fDeleteMarker);
3729                                        }                                                               
3730                                        else
3731                                        {
3732                                                slAct->prev->next = slAct->next;
3733                                                slAct->next->prev = slAct->prev;
3734                                                fDeleteMarker->shallowDelete();
3735//                                              delete(fDeleteMarker);
3736                                        }
3737                                        removalOccured=TRUE;
3738                                        gcone::lengthOfSearchList--;
3739#ifdef gfan_DEBUG
3740printf("Removing (");fAct->fNormal->show(1,1);printf(") from list\n");
3741#endif
3742                                        /*fDeleteMarker->shallowDelete();*///Sets everything to NULL
3743//                                      delete(fDeleteMarker);
3744                                        break;//leave the while loop, since we found fAct=slAct thus delete slAct and do not add fAct
3745                                }
3746                                slAct = slAct->next;                           
3747                        }//while(slAct!=NULL)
3748                        if(removalOccured==FALSE)
3749                        {
3750                                facet *marker=slEnd;
3751                                slEnd->next = fAct->shallowCopy(*fAct);
3752                                slEnd = slEnd->next;
3753                                slEnd->prev=marker;
3754                                gcone::lengthOfSearchList++;
3755                        }
3756                        fAct = fAct->next;
3757//                      if(fDeleteMarker!=NULL)
3758//                      {
3759//                              fDeleteMarker->shallowDelete();
3760//                              delete(fDeleteMarker);
3761//                              fDeleteMarker=NULL;
3762//                      }
3763                }
3764                else
3765                        fAct = fAct->next;
3766        }//while(fAct!=NULL)
3767       
3768#ifdef gfanp
3769        gettimeofday(&end, 0);
3770        time_enqueue += (end.tv_sec - start.tv_sec + 1e-6*(end.tv_usec - start.tv_usec));
3771#endif 
3772//      printf("headUCN@enq=%i\n",slHead->getUCN());
3773        return slHead;
3774}
3775
3776/**
3777* During flip2 every gc->baseRing gets two ringorder_a
3778* To avoid having an awful lot of those in the end we endow
3779* gc->baseRing by a suitable ring with (a,dp,C) and copy all
3780* necessary stuff over
3781* But first we will try to just do an inplace exchange and copying only the
3782* gc->gcBasis
3783*/
3784void gcone::replaceDouble_ringorder_a_ByASingleOne()
3785{
3786        ring srcRing=currRing;
3787        ring replacementRing=rCopy0((ring)this->baseRing);
3788        /*We assume we have (a(),a(),dp) here*/
3789        omFree(replacementRing->order);
3790        replacementRing->order =(int *)omAlloc0(4*sizeof(int));
3791        omFree(replacementRing->block0);
3792        replacementRing->block0=(int *)omAlloc0(4*sizeof(int));
3793        omFree(replacementRing->block1);
3794        replacementRing->block1=(int *)omAlloc0(4*sizeof(int));
3795        omfree(replacementRing->wvhdl);
3796        replacementRing->wvhdl =(int **)omAlloc0(4*sizeof(int**));
3797                       
3798        replacementRing->order[0]=ringorder_a;
3799        replacementRing->block0[0]=1;
3800        replacementRing->block1[0]=replacementRing->N;
3801               
3802        replacementRing->order[1]=ringorder_dp;
3803        replacementRing->block0[1]=1;
3804        replacementRing->block1[1]=replacementRing->N;
3805       
3806        replacementRing->order[2]=ringorder_C;
3807
3808        intvec *ivw = this->getIntPoint();
3809//      assert(this->ivIntPt);
3810        int length=ivw->length();       
3811        int *A=(int *)omAlloc0(length*sizeof(int));
3812        for (int jj=0;jj<length;jj++)
3813                A[jj]=(*ivw)[jj];
3814        delete ivw;
3815        replacementRing->wvhdl[0]=(int *)A;
3816        replacementRing->block1[0]=length;
3817        /*Finish*/
3818        rComplete(replacementRing);
3819        rChangeCurrRing(replacementRing);
3820        ideal temporaryGroebnerBasis=idrCopyR(this->gcBasis,this->baseRing);
3821        rDelete(this->baseRing);
3822        this->baseRing=rCopy(replacementRing);
3823        this->gcBasis=idCopy(temporaryGroebnerBasis);
3824        //FIXME idDelete & rDelete!!! DONE!
3825        /*And back to where we came from*/
3826        rChangeCurrRing(srcRing);
3827        idDelete( (ideal*)&temporaryGroebnerBasis );
3828        rDelete(replacementRing);       
3829}
3830
3831/** \brief Compute the gcd of two ints
3832 */
3833static int intgcd(const int &a, const int &b)
3834{
3835        int r, p=a, q=b;
3836        if(p < 0)
3837                p = -p;
3838        if(q < 0)
3839                q = -q;
3840        while(q != 0)
3841        {
3842                r = p % q;
3843                p = q;
3844                q = r;
3845        }
3846        return p;
3847}               
3848               
3849/** \brief Construct a dd_MatrixPtr from a cone's list of facets
3850 * NO LONGER USED
3851 */
3852// inline dd_MatrixPtr gcone::facets2Matrix(const gcone &gc)
3853// {
3854//      facet *fAct;
3855//      fAct = gc.facetPtr;
3856//     
3857//      dd_MatrixPtr M;
3858//      dd_rowrange ddrows;
3859//      dd_colrange ddcols;
3860//      ddcols=(this->numVars)+1;
3861//      ddrows=this->numFacets;
3862//      dd_NumberType numb = dd_Integer;
3863//      M=dd_CreateMatrix(ddrows,ddcols);                       
3864//                     
3865//      int jj=0;
3866//     
3867//      while(fAct!=NULL)
3868//      {
3869//              intvec *comp;
3870//              comp = fAct->getFacetNormal();
3871//              for(int ii=0;ii<this->numVars;ii++)
3872//              {
3873//                      dd_set_si(M->matrix[jj][ii+1],(*comp)[ii]);
3874//              }
3875//              jj++;
3876//              delete comp;
3877//              fAct=fAct->next;                               
3878//      }                       
3879//      return M;
3880// }
3881               
3882/** \brief Write information about a cone into a file on disk
3883 *
3884 * This methods writes the information needed for the "second" method into a file.
3885 * The file's is divided in sections containing information on
3886 * 1) the ring
3887 * 2) the cone's Groebner Basis
3888 * 3) the cone's facets
3889 * Each line contains exactly one date
3890 * Each section starts with its name in CAPITALS
3891 */
3892void gcone::writeConeToFile(const gcone &gc, bool usingIntPoints)
3893{
3894        int UCN=gc.UCN;
3895        stringstream ss;
3896        ss << UCN;
3897        string UCNstr = ss.str();               
3898                       
3899        string prefix="/tmp/Singular/cone";
3900//      string prefix="./";     //crude hack -> run tests in separate directories
3901        string suffix=".sg";
3902        string filename;
3903        filename.append(prefix);
3904        filename.append(UCNstr);
3905        filename.append(suffix);
3906       
3907       
3908//      int thisPID = getpid();
3909//      ss << thisPID;
3910//      string strPID = ss.str();
3911//      string prefix="./";
3912                                               
3913        ofstream gcOutputFile(filename.c_str());
3914        assert(gcOutputFile);
3915        facet *fAct;
3916        fAct = gc.facetPtr;                     
3917        facet *f2Act;
3918        f2Act=fAct->codim2Ptr;
3919       
3920        char *ringString = rString(gc.baseRing);
3921                       
3922        if (!gcOutputFile)
3923        {
3924                WerrorS("Error opening file for writing in writeConeToFile\n");
3925        }
3926        else
3927        {       
3928                gcOutputFile << "UCN" << endl;
3929                gcOutputFile << this->UCN << endl;
3930                gcOutputFile << "RING" << endl; 
3931                gcOutputFile << ringString << endl;
3932                gcOutputFile << "GCBASISLENGTH" << endl;
3933                gcOutputFile << IDELEMS(gc.gcBasis) << endl;                   
3934                //Write this->gcBasis into file
3935                gcOutputFile << "GCBASIS" << endl;                             
3936                for (int ii=0;ii<IDELEMS(gc.gcBasis);ii++)
3937                {                                       
3938                        gcOutputFile << p_String((poly)gc.gcBasis->m[ii],gc.baseRing) << endl;
3939                }                               
3940                                       
3941                gcOutputFile << "FACETS" << endl;                                                               
3942               
3943                while(fAct!=NULL)
3944                {       
3945                        const intvec *iv;
3946                        iv=fAct->getRef2FacetNormal();//->getFacetNormal();
3947                        f2Act=fAct->codim2Ptr;
3948                        for (int ii=0;ii<iv->length();ii++)
3949                        {
3950                                if (ii<iv->length()-1)
3951                                {
3952                                        gcOutputFile << (*iv)[ii] << ",";
3953                                }
3954                                else
3955                                {
3956                                        gcOutputFile << (*iv)[ii] << " ";
3957                                }
3958                        }
3959//                      delete iv;
3960                        while(f2Act!=NULL)
3961                        {
3962                                const intvec *iv2;
3963                                iv2=f2Act->getRef2FacetNormal();//->getFacetNormal();   
3964                                for(int jj=0;jj<iv2->length();jj++)
3965                                {
3966                                        if (jj<iv2->length()-1)
3967                                        {
3968                                                gcOutputFile << (*iv2)[jj] << ",";
3969                                        }
3970                                        else
3971                                        {
3972                                                gcOutputFile << (*iv2)[jj] << " ";
3973                                        }
3974                                }
3975//                              delete iv2;
3976                                f2Act = f2Act->next;
3977                        }
3978                        gcOutputFile << endl;
3979                        fAct=fAct->next;
3980                }                       
3981        gcOutputFile.close();
3982        }
3983                       
3984}//writeConeToFile(gcone const &gc)
3985               
3986/** \brief Reads a cone from a file identified by its number
3987* ||depending on whether flip or flip2 is used, switch the flag flipFlag
3988* ||defaults to 0 => flip
3989* ||1 => flip2
3990*/
3991void gcone::readConeFromFile(int UCN, gcone *gc)
3992{
3993        //int UCN=gc.UCN;
3994        stringstream ss;
3995        ss << UCN;
3996        string UCNstr = ss.str();
3997        int gcBasisLength=0;
3998        size_t found;                   //used for find_first_(not)_of
3999
4000        string prefix="/tmp/Singular/cone";
4001        string suffix=".sg";
4002        string filename;
4003        filename.append(prefix);
4004        filename.append(UCNstr);
4005        filename.append(suffix);
4006                                       
4007        ifstream gcInputFile(filename.c_str(), ifstream::in);
4008       
4009        ring saveRing=currRing; 
4010        //Comment the following if you uncomment the if(line=="RING") part below
4011//      rChangeCurrRing(gc->baseRing);
4012       
4013        while( !gcInputFile.eof() )
4014        {
4015                string line;
4016                getline(gcInputFile,line);
4017                if(line=="RING")
4018                {
4019                        getline(gcInputFile,line);
4020                        found = line.find("a(");
4021                        line.erase(0,found+2);
4022                        string strweight;
4023                        strweight=line.substr(0,line.find_first_of(")"));
4024                                               
4025                        intvec *iv=new intvec(this->numVars);//                         
4026                        for(int ii=0;ii<this->numVars;ii++)
4027                        {
4028                                string weight;
4029                                weight=line.substr(0,line.find_first_of(",)"));                         
4030                                (*iv)[ii]=atol(weight.c_str());//Better to long. Weight bound in Singular:2147483647
4031                                line.erase(0,line.find_first_of(",)")+1);
4032                        }
4033                        found = line.find("a(");
4034                       
4035                        ring newRing;
4036                        if(currRing->order[0]!=ringorder_a)
4037                        {
4038                                        newRing=rCopyAndAddWeight(currRing,iv);
4039                        }
4040                        else
4041                        {       
4042                                        newRing=rCopy0(currRing);
4043                                        int length=this->numVars;
4044                                        int *A=(int *)omAlloc0(length*sizeof(int));
4045                                        for(int jj=0;jj<length;jj++)
4046                                        {
4047                                                A[jj]=(*iv)[jj];
4048                                        }
4049                                        omFree(newRing->wvhdl[0]);
4050                                        newRing->wvhdl[0]=(int*)A;
4051                                        newRing->block1[0]=length;
4052                        }
4053                        delete iv;
4054                        rComplete(newRing);
4055                        gc->baseRing=rCopy(newRing);
4056                        rDelete(newRing);
4057                        rComplete(gc->baseRing);
4058                        if(currRing!=gc->baseRing)
4059                                rChangeCurrRing(gc->baseRing);
4060                }
4061               
4062                if(line=="GCBASISLENGTH")
4063                {
4064                        string strGcBasisLength;
4065                        getline(gcInputFile, line);
4066                        strGcBasisLength = line;
4067                        int size=atoi(strGcBasisLength.c_str());
4068                        gcBasisLength=size;             
4069                        gc->gcBasis=idInit(size,1);
4070                }
4071                if(line=="GCBASIS")
4072                {
4073                        for(int jj=0;jj<gcBasisLength;jj++)
4074                        {
4075                                getline(gcInputFile,line);
4076                                //magically convert strings into polynomials
4077                                //polys.cc:p_Read
4078                                //check until first occurance of + or -
4079                                //data or c_str
4080//                              poly strPoly;//=pInit();//Ought to be inside the while loop, but that will eat your memory
4081                                poly resPoly=pInit();   //The poly to be read in               
4082                                while(!line.empty())
4083                                {
4084                                        poly strPoly;//=pInit();
4085                                        number nCoeff=nInit(1);
4086                                        number nCoeffNom=nInit(1);
4087                                        number nCoeffDenom=nInit(1);
4088                                        string strMonom, strCoeff, strCoeffNom, strCoeffDenom;
4089                                        bool hasCoeffInQ = FALSE;       //does the polynomial have rational coeff?
4090                                        bool hasNegCoeff = FALSE;       //or a negative one?
4091                                        found = line.find_first_of("+-");       //get the first monomial
4092                                        string tmp;
4093                                        tmp=line[found];
4094//                                      if(found!=0 && (tmp.compare("-")==0) )
4095//                                              hasNegCoeff = TRUE;     //We have a coeff < 0
4096                                        if(found==0)
4097                                        {
4098                                                if(tmp.compare("-")==0)
4099                                                        hasNegCoeff = TRUE;
4100                                                line.erase(0,1);        //remove leading + or -
4101                                                found = line.find_first_of("+-");       //adjust found
4102                                        }
4103                                        strMonom = line.substr(0,found);
4104                                        line.erase(0,found);
4105                                        found = strMonom.find_first_of("/");
4106                                        if(found!=string::npos) //i.e. "/" exists in strMonom
4107                                        {
4108                                                hasCoeffInQ = TRUE;
4109                                                strCoeffNom=strMonom.substr(0,found);                                           
4110                                                strCoeffDenom=strMonom.substr(found+1,strMonom.find_first_not_of("1234567890",found+1));
4111                                                strMonom.erase(0,found);
4112                                                strMonom.erase(0,strMonom.find_first_not_of("1234567890/"));                   
4113                                                nRead(strCoeffNom.c_str(), &nCoeffNom);
4114                                                nRead(strCoeffDenom.c_str(), &nCoeffDenom);
4115                                        }
4116                                        else
4117                                        {
4118                                                found = strMonom.find_first_not_of("1234567890");
4119                                                strCoeff = strMonom.substr(0,found);
4120                                                if(!strCoeff.empty())
4121                                                {
4122                                                        nRead(strCoeff.c_str(),&nCoeff);
4123                                                }
4124                                                else
4125                                                {
4126//                                                      intCoeff = 1;
4127                                                        nCoeff = nInit(1);
4128                                                }
4129                                                                                               
4130                                        }
4131                                        const char* monom = strMonom.c_str();                                   
4132                                               
4133                                        p_Read(monom,strPoly,currRing); //strPoly:=monom                               
4134                                        switch (hasCoeffInQ)
4135                                        {
4136                                                case TRUE:
4137                                                        if(hasNegCoeff)
4138                                                                nCoeffNom=nNeg(nCoeffNom);
4139                                                        pSetCoeff(strPoly, nDiv(nCoeffNom, nCoeffDenom));
4140                                                        break;
4141                                                case FALSE:
4142                                                        if(hasNegCoeff)
4143                                                                nCoeff=nNeg(nCoeff);                                                   
4144                                                        if(!nIsOne(nCoeff))
4145                                                        {
4146//                                                              if(hasNegCoeff)
4147//                                                                      intCoeff *= -1;
4148//                                                              pSetCoeff(strPoly,(number) intCoeff);
4149                                                                pSetCoeff(strPoly, nCoeff );
4150                                                        }
4151                                                        break;
4152                                                                                                       
4153                                        }
4154                                                //pSetCoeff(strPoly, (number) intCoeff);//Why is this set to zero instead of 1???
4155                                        if(pIsConstantComp(resPoly))
4156                                                resPoly=pCopy(strPoly);                                                 
4157                                        else
4158                                                resPoly=pAdd(resPoly,strPoly);//pAdd = p_Add_q, destroys args
4159//                                      nDelete(&nCoeff);
4160                                        nDelete(&nCoeffNom);
4161                                        nDelete(&nCoeffDenom);
4162//                                      pDelete(&strPoly);
4163                                }//while(!line.empty())                 
4164                                gc->gcBasis->m[jj]=pCopy(resPoly);
4165                                pDelete(&resPoly);      //reset
4166//                              pDelete(&strPoly);      //NOTE Crashes - already deleted by pAdd                               
4167                        }
4168//                      break;
4169                }//if(line=="GCBASIS") 
4170                if(line=="FACETS")
4171                {
4172                        facet *fAct=gc->facetPtr;
4173                        while(fAct!=NULL)
4174                        {
4175                                getline(gcInputFile,line);
4176                                found = line.find("\t");
4177                                string normalString=line.substr(0,found);
4178                                intvec *fN = new intvec(this->numVars);
4179                                for(int ii=0;ii<this->numVars;ii++)
4180                                {
4181                                        string component;
4182                                        found = normalString.find(",");
4183                                        component=normalString.substr(0,found);
4184                                        (*fN)[ii]=atol(component.c_str());
4185                                        normalString.erase(0,found+1);
4186                                }
4187                                /*Only the following line needs to be commented out if you decide not to delete fNormals*/
4188//                              fAct->setFacetNormal(fN);
4189                                delete(fN);
4190                                fAct = fAct->next;      //Booh, this is ugly
4191                        }                       
4192                        break; //NOTE Must always be in the last if-block!
4193                }
4194        }//while(!gcInputFile.eof())   
4195        gcInputFile.close();
4196        rChangeCurrRing(saveRing);
4197}
4198       
4199
4200/** \brief Sort the rays of a facet lexicographically
4201*/
4202// void gcone::sortRays(gcone *gc)
4203// {
4204//      facet *fAct;
4205//      fAct = this->facetPtr->codim2Ptr;
4206//      while(fAct->next!=NULL)
4207//      {
4208//              if(fAct->fNormal->compare(fAct->fNormal->next)==-1
4209//      }
4210// }
4211
4212/** \brief Gather the output
4213* List of lists
4214* If heuristic==1 readConeFromFile() is called once more on every cone. This may slow down the computation but it also
4215* allows us to rDelete(gcDel->baseRing) and the such in gcone::noRevS.
4216*\param *gc Pointer to gcone, preferably gcRoot ;-)
4217*\param n the number of cones as determined by gcRoot->getCounter()
4218*
4219*/
4220lists lprepareResult(gcone *gc, const int n)
4221{
4222        gcone *gcAct;
4223        gcAct = gc;     
4224        facet *fAct;
4225        fAct = gc->facetPtr;
4226       
4227        lists res=(lists)omAllocBin(slists_bin);
4228        res->Init(n);   //initialize to store n cones
4229        for(int ii=0;ii<n;ii++)
4230        {
4231                if(gfanHeuristic==1)// && gcAct->getUCN()>1)
4232                {
4233                        gcAct->readConeFromFile(gcAct->getUCN(),gcAct); 
4234//                      rChangeCurrRing(gcAct->getBaseRing());//NOTE memleak?
4235                }
4236                rChangeCurrRing(gcAct->getRef2BaseRing());     
4237                res->m[ii].rtyp=LIST_CMD;
4238                lists l=(lists)omAllocBin(slists_bin);
4239                l->Init(6);
4240                l->m[0].rtyp=INT_CMD;
4241                l->m[0].data=(void*)gcAct->getUCN();
4242                l->m[1].rtyp=IDEAL_CMD;
4243                /*The following is necessary for leaves in the tree of cones
4244                * Since we don't use them in the computation and gcBasis is
4245                * set to (poly)NULL in noRevS we need to get this back here.
4246                */
4247//              if(gcAct->gcBasis->m[0]==(poly)NULL)
4248//              if(gfanHeuristic==1 && gcAct->getUCN()>1)
4249//                      gcAct->readConeFromFile(gcAct->getUCN(),gcAct);
4250//              ring saveRing=currRing;
4251//              ring tmpRing=gcAct->getBaseRing;
4252//              rChangeCurrRing(tmpRing);
4253//              l->m[1].data=(void*)idrCopyR_NoSort(gcAct->gcBasis,gcAct->getBaseRing());
4254//              l->m[1].data=(void*)idrCopyR(gcAct->gcBasis,gcAct->getBaseRing());//NOTE memleak?
4255                l->m[1].data=(void*)idrCopyR(gcAct->gcBasis,gcAct->getRef2BaseRing());
4256//              rChangeCurrRing(saveRing);
4257
4258                l->m[2].rtyp=INTVEC_CMD;
4259                intvec iv=(gcAct->f2M(gcAct,gcAct->facetPtr));//NOTE memleak?
4260                l->m[2].data=(void*)ivCopy(&iv);
4261               
4262                l->m[3].rtyp=LIST_CMD;
4263                        lists lCodim2List = (lists)omAllocBin(slists_bin);
4264                        lCodim2List->Init(gcAct->numFacets); 
4265                        fAct = gcAct->facetPtr;//fAct->codim2Ptr;
4266                        int jj=0;
4267                        while(fAct!=NULL && jj<gcAct->numFacets)
4268                        {
4269                                lCodim2List->m[jj].rtyp=INTVEC_CMD;
4270                                intvec ivC2=(gcAct->f2M(gcAct,fAct,2));
4271                                lCodim2List->m[jj].data=(void*)ivCopy(&ivC2);
4272                                jj++;
4273                                fAct = fAct->next;
4274                        }               
4275                l->m[3].data=(void*)lCodim2List;               
4276                l->m[4].rtyp=INTVEC_CMD/*RING_CMD*/;
4277                l->m[4].data=(void*)(gcAct->getIntPoint/*BaseRing*/());                 
4278                l->m[5].rtyp=INT_CMD;
4279                l->m[5].data=(void*)gcAct->getPredUCN();
4280                res->m[ii].data=(void*)l;
4281                gcAct = gcAct->next;
4282        }       
4283        return res;
4284}
4285/** \brief Write facets of a cone into a matrix
4286* Takes a pointer to a facet as 2nd arg
4287* f should always point to gc->facetPtr
4288* param n is used to determine whether it operates in codim 1 or 2
4289* We have to cast the int64vecs to intvec due to issues with list structure
4290*/
4291inline intvec gcone::f2M(gcone *gc, facet *f, int n)
4292{
4293        facet *fAct;
4294        intvec *res;//=new intvec(this->numVars);       
4295//      int codim=n;
4296//      int bound;
4297//      if(f==gc->facetPtr)
4298        if(n==1)
4299        {
4300                intvec *m1Res=new intvec(gc->numFacets,gc->numVars,0);
4301                res = ivCopy(m1Res);
4302                fAct = gc->facetPtr;
4303                delete m1Res;
4304//              bound = gc->numFacets*(this->numVars);         
4305        }
4306        else
4307        {
4308                fAct = f->codim2Ptr;
4309                intvec *m2Res = new intvec(f->numCodim2Facets,gc->numVars,0);
4310                res = ivCopy(m2Res);
4311                delete m2Res;   
4312//              bound = fAct->numCodim2Facets*(this->numVars);
4313
4314        }
4315        int ii=0;
4316        while(fAct!=NULL )//&& ii < bound )
4317        {
4318                const intvec *fNormal;
4319                fNormal = fAct->getRef2FacetNormal();//->getFacetNormal();
4320                for(int jj=0;jj<this->numVars;jj++)
4321                {
4322                        (*res)[ii]=(int)(*fNormal)[jj];//This is ugly and prone to overflow
4323                        ii++;
4324                }
4325                fAct = fAct->next;
4326//              delete fNormal;
4327        }       
4328        return *res;
4329}
4330
4331int gcone::counter=0;
4332int gfanHeuristic;
4333int gcone::lengthOfSearchList;
4334int gcone::maxSize;
4335dd_MatrixPtr gcone::dd_LinealitySpace;
4336intvec *gcone::hilbertFunction;
4337#ifdef gfanp
4338// int gcone::lengthOfSearchList=0;
4339float gcone::time_getConeNormals;
4340float gcone::time_getCodim2Normals;
4341float gcone::t_getExtremalRays;
4342float gcone::t_ddPolyh;
4343float gcone::time_flip;
4344float gcone::time_flip2;
4345float gcone::t_areEqual;
4346float gcone::t_markings;
4347float gcone::t_dd;
4348float gcone::t_kStd=0;
4349float gcone::time_enqueue;
4350float gcone::time_computeInv;
4351float gcone::t_ddMC;
4352float gcone::t_mI;
4353float gcone::t_iP;
4354float gcone::t_isParallel;
4355unsigned gcone::parallelButNotEqual=0;
4356unsigned gcone::numberOfFacetChecks=0;
4357#endif
4358int gcone::numVars;
4359bool gcone::hasHomInput=FALSE;
4360intvec *gcone::ivZeroVector;
4361// ideal gfan(ideal inputIdeal, int h)
4362lists gfan(ideal inputIdeal, int h)
4363{
4364        lists lResList; //this is the object we return 
4365
4366        if(rHasGlobalOrdering(currRing))
4367        {       
4368//              int numvar = pVariables;
4369                gfanHeuristic = h;
4370               
4371                enum searchMethod {
4372                        reverseSearch,
4373                        noRevS
4374                };
4375       
4376                searchMethod method;
4377                method = noRevS;
4378       
4379                ring inputRing=currRing;        // The ring the user entered
4380//              ring rootRing;                  // The ring associated to the target ordering
4381
4382                dd_set_global_constants();
4383                if(method==noRevS)
4384                {
4385                        gcone *gcRoot = new gcone(currRing,inputIdeal);
4386                        gcone *gcAct;
4387                        gcAct = gcRoot;
4388                        gcone::numVars=pVariables;
4389//                      gcAct->numVars=pVariables;//NOTE is now static
4390                        gcAct->getGB(inputIdeal);
4391                        /*Check whether input is homogeneous
4392                        if TRUE each facet intersects the positive orthant, so we don't need the
4393                        flippability test in getConeNormals & getExtremalRays
4394                        */
4395                        if(idHomIdeal(gcAct->gcBasis,NULL))//disabled for tests
4396                        {
4397                                gcone::hasHomInput=TRUE;
4398                                gcone::hilbertFunction=hHstdSeries(inputIdeal,NULL,NULL,NULL,currRing);
4399                        }
4400                        else
4401                        {
4402                                gcone::ivZeroVector = new intvec(pVariables);
4403                                for(int ii=0;ii<pVariables;ii++)
4404                                        (*gcone::ivZeroVector)[ii]=0;
4405                        }
4406        #ifndef NDEBUG
4407        //              cout << "GB of input ideal is:" << endl;
4408        //              idShow(gcAct->gcBasis);
4409        #endif
4410                        if(isMonomial(gcAct->gcBasis))
4411                        {//FIXME
4412                                WerrorS("Monomial input - terminating");
4413                                dd_free_global_constants();
4414                                //This is filthy
4415                                goto pointOfNoReturn;
4416                                //return lResList;
4417                        }                       
4418                        gcAct->getConeNormals(gcAct->gcBasis);
4419                        gcone::dd_LinealitySpace = gcAct->computeLinealitySpace();
4420                        gcAct->getExtremalRays(*gcAct);
4421                        gcAct->noRevS(*gcAct);  //Here we go!
4422                        //Switch back to the ring the computation was started in
4423//                      rChangeCurrRing(inputRing);
4424                        //res=gcAct->gcBasis;
4425                        //Below is a workaround, since gcAct->gcBasis gets deleted in noRevS                   
4426                        lResList=lprepareResult(gcRoot,gcRoot->getCounter());
4427                        /*Cleanup*/
4428                        gcone *gcDel;   
4429                        gcDel = gcRoot;
4430                        gcAct = gcRoot;
4431                        while(gcAct!=NULL)
4432                        {
4433                                gcDel = gcAct;
4434                                gcAct = gcAct->next;
4435//                              delete gcDel;
4436                        }
4437                }//method==noRevS
4438                dd_FreeMatrix(gcone::dd_LinealitySpace);
4439                dd_free_global_constants();
4440        }//rHasGlobalOrdering
4441        else
4442        {
4443                //Simply return an empty list
4444                WerrorS("Ring has non-global ordering.\nThis function requires your current ring to be endowed with a global ordering.\n Now terminating!");
4445                gcone *gcRoot=new gcone();
4446                gcone *gcPtr = gcRoot;
4447                for(int ii=0;ii<10000;ii++)
4448                {
4449                        gcPtr->setBaseRing(currRing);
4450                        facet *fPtr=gcPtr->facetPtr=new facet();
4451                        for(int jj=0;jj<5;jj++)
4452                        {
4453                                intvec *iv=new intvec(pVariables);
4454                                fPtr->setFacetNormal(iv);                               
4455                                delete(iv);
4456                                fPtr->next=new facet();
4457                                fPtr=fPtr->next;
4458                        }
4459                        gcPtr->next=new gcone();
4460                        gcPtr->next->prev=gcPtr;
4461                        gcPtr=gcPtr->next;                     
4462                }
4463                gcPtr=gcRoot;
4464                while(gcPtr!=NULL)
4465                {
4466                        gcPtr=gcPtr->next;
4467//                      delete(gcPtr->prev);
4468                }
4469                goto pointOfNoReturn;
4470        }
4471        /*Return result*/
4472#ifdef gfanp
4473        cout << endl << "t_getConeNormals:" << gcone::time_getConeNormals << endl;
4474//      cout << "t_getCodim2Normals:" << gcone::time_getCodim2Normals << endl;
4475//      cout << "  t_ddMC:" << gcone::t_ddMC << endl;
4476//      cout << "  t_mI:" << gcone::t_mI << endl;
4477//      cout << "  t_iP:" << gcone::t_iP << endl;
4478        cout << "t_getExtremalRays:" << gcone::t_getExtremalRays << endl;
4479        cout << "  t_ddPolyh:" << gcone::t_ddPolyh << endl;
4480        cout << "t_Flip:" << gcone::time_flip << endl;
4481        cout << "  t_markings:" << gcone::t_markings << endl;
4482        cout << "  t_dd:" << gcone::t_dd << endl;
4483        cout << "  t_kStd:" << gcone::t_kStd << endl;
4484        cout << "t_Flip2:" << gcone::time_flip2 << endl;
4485        cout << "  t_dd:" << gcone::t_dd << endl;
4486        cout << "  t_kStd:" << gcone::t_kStd << endl;
4487        cout << "t_computeInv:" << gcone::time_computeInv << endl;
4488        cout << "t_enqueue:" << gcone::time_enqueue << endl;
4489        cout << "  t_areEqual:" <<gcone::t_areEqual << endl;
4490        cout << "t_isParallel:" <<gcone::t_isParallel << endl;
4491        cout << endl;
4492        cout << "Checked " << gcone::numberOfFacetChecks << " Facets" << endl;
4493        cout << " out of which there were " << gcone::parallelButNotEqual << " parallel but not equal." << endl;
4494#endif
4495        printf("Maximum lenght of list of facets: %i", gcone::maxSize);
4496pointOfNoReturn:
4497        return lResList;
4498}
4499
4500#endif
Note: See TracBrowser for help on using the repository browser.