source: git/kernel/gfan.cc @ 5be7db

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