source: git/kernel/gfan.cc @ bafaec0

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