1 | #include <utility> |
---|
2 | #include <kernel/GBEngine/kstd1.h> |
---|
3 | #include <gfanlib/gfanlib_vector.h> |
---|
4 | #include <callgfanlib_conversion.h> |
---|
5 | #include <initial.h> |
---|
6 | #include <lift.h> |
---|
7 | #include <tropicalStrategy.h> |
---|
8 | |
---|
9 | |
---|
10 | static void deleteOrdering(ring r) |
---|
11 | { |
---|
12 | if (r->order != NULL) |
---|
13 | { |
---|
14 | int i=rBlocks(r); |
---|
15 | assume(r->block0 != NULL && r->block1 != NULL && r->wvhdl != NULL); |
---|
16 | /* delete order */ |
---|
17 | omFreeSize((ADDRESS)r->order,i*sizeof(int)); |
---|
18 | omFreeSize((ADDRESS)r->block0,i*sizeof(int)); |
---|
19 | omFreeSize((ADDRESS)r->block1,i*sizeof(int)); |
---|
20 | /* delete weights */ |
---|
21 | for (int j=0; j<i; j++) |
---|
22 | if (r->wvhdl[j]!=NULL) |
---|
23 | omFree(r->wvhdl[j]); |
---|
24 | omFreeSize((ADDRESS)r->wvhdl,i*sizeof(int *)); |
---|
25 | } |
---|
26 | else |
---|
27 | assume(r->block0 == NULL && r->block1 == NULL && r->wvhdl == NULL); |
---|
28 | return; |
---|
29 | } |
---|
30 | |
---|
31 | /*** |
---|
32 | * Given a Groebner basis I of an ideal in r, an interior Point |
---|
33 | * on a face of the maximal Groebner cone associated to the ordering on r, |
---|
34 | * and a vector pointing outwards from it, |
---|
35 | * returns a pair (Is,s) such that: |
---|
36 | * (1) s is the same mathematical ring as r, but with a new ordering such that |
---|
37 | * the interior point lies on the intersection of both maximal Groebner cones |
---|
38 | * (2) Is is a Groebner basis of the same ideal with respect to the ordering on s |
---|
39 | **/ |
---|
40 | std::pair<ideal,ring> flip(const ideal I, const ring r, |
---|
41 | const gfan::ZVector interiorPoint, |
---|
42 | const gfan::ZVector facetNormal, |
---|
43 | const gfan::ZVector adjustedInteriorPoint, |
---|
44 | const gfan::ZVector adjustedFacetNormal) |
---|
45 | { |
---|
46 | /* create a ring with weighted ordering */ |
---|
47 | bool ok; |
---|
48 | ring sAdjusted = rCopy0(r); |
---|
49 | int n = rVar(sAdjusted); |
---|
50 | deleteOrdering(sAdjusted); |
---|
51 | sAdjusted->order = (int*) omAlloc0(4*sizeof(int)); |
---|
52 | sAdjusted->block0 = (int*) omAlloc0(4*sizeof(int)); |
---|
53 | sAdjusted->block1 = (int*) omAlloc0(4*sizeof(int)); |
---|
54 | sAdjusted->wvhdl = (int**) omAlloc0(4*sizeof(int**)); |
---|
55 | sAdjusted->order[0] = ringorder_a; |
---|
56 | sAdjusted->block0[0] = 1; |
---|
57 | sAdjusted->block1[0] = n; |
---|
58 | sAdjusted->wvhdl[0] = ZVectorToIntStar(adjustedInteriorPoint,ok); |
---|
59 | sAdjusted->order[1] = ringorder_wp; |
---|
60 | sAdjusted->block0[1] = 1; |
---|
61 | sAdjusted->block1[1] = n; |
---|
62 | sAdjusted->wvhdl[1] = ZVectorToIntStar(adjustedFacetNormal,ok); |
---|
63 | sAdjusted->order[2] = ringorder_C; |
---|
64 | rComplete(sAdjusted); |
---|
65 | rTest(sAdjusted); |
---|
66 | nMapFunc identity = n_SetMap(r->cf,sAdjusted->cf); |
---|
67 | |
---|
68 | /* compute initial ideal and map it to the new ordering */ |
---|
69 | ideal inIr = initial(I,r,interiorPoint); |
---|
70 | int k = idSize(I); ideal inIsAdjusted = idInit(k); |
---|
71 | for (int i=0; i<k; i++) |
---|
72 | inIsAdjusted->m[i] = p_PermPoly(inIr->m[i],NULL,r,sAdjusted,identity,NULL,0); |
---|
73 | id_Delete(&inIr,r); |
---|
74 | |
---|
75 | /* compute Groebner basis of the initial ideal */ |
---|
76 | intvec* nullVector = NULL; |
---|
77 | ring origin = currRing; |
---|
78 | rChangeCurrRing(sAdjusted); |
---|
79 | ideal inIsAdjustedGB = kStd(inIsAdjusted,currRing->qideal,testHomog,&nullVector); |
---|
80 | ideal IsAdjustedGB = lift(I,r,inIsAdjustedGB,sAdjusted); |
---|
81 | id_Delete(&inIsAdjusted,sAdjusted); |
---|
82 | id_Delete(&inIsAdjustedGB,sAdjusted); |
---|
83 | |
---|
84 | ring s = rCopy0(r); |
---|
85 | n = rVar(s); |
---|
86 | deleteOrdering(s); |
---|
87 | s->order = (int*) omAlloc0(5*sizeof(int)); |
---|
88 | s->block0 = (int*) omAlloc0(5*sizeof(int)); |
---|
89 | s->block1 = (int*) omAlloc0(5*sizeof(int)); |
---|
90 | s->wvhdl = (int**) omAlloc0(5*sizeof(int**)); |
---|
91 | s->order[0] = ringorder_a; |
---|
92 | s->block0[0] = 1; |
---|
93 | s->block1[0] = n; |
---|
94 | s->wvhdl[0] = ZVectorToIntStar(interiorPoint,ok); |
---|
95 | s->order[1] = ringorder_a; |
---|
96 | s->block0[1] = 1; |
---|
97 | s->block1[1] = n; |
---|
98 | s->wvhdl[1] = ZVectorToIntStar(facetNormal,ok); |
---|
99 | s->order[2] = ringorder_dp; |
---|
100 | s->block0[2] = 1; |
---|
101 | s->block1[2] = n; |
---|
102 | s->order[3] = ringorder_C; |
---|
103 | rComplete(s); |
---|
104 | rTest(s); |
---|
105 | identity = n_SetMap(sAdjusted->cf,s->cf); |
---|
106 | k = idSize(IsAdjustedGB); ideal IsGB = idInit(k); |
---|
107 | for (int i=0; i<k; i++) |
---|
108 | IsGB->m[i] = p_PermPoly(IsAdjustedGB->m[i],NULL,sAdjusted,s,identity,NULL,0); |
---|
109 | id_Delete(&IsAdjustedGB,sAdjusted); |
---|
110 | rDelete(sAdjusted); |
---|
111 | rChangeCurrRing(origin); |
---|
112 | |
---|
113 | /* lift the Groebner basis of the initial ideal |
---|
114 | * to a Groebner basis of the original ideal, |
---|
115 | * the currRingChange is solely for sake of performance */ |
---|
116 | |
---|
117 | return std::make_pair(IsGB,s); |
---|
118 | } |
---|