passagemath-latte-4ti2 10.6.30__cp311-cp311-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-latte-4ti2 might be problematic. Click here for more details.

Files changed (81) hide show
  1. passagemath_latte_4ti2-10.6.30.dist-info/METADATA +156 -0
  2. passagemath_latte_4ti2-10.6.30.dist-info/RECORD +81 -0
  3. passagemath_latte_4ti2-10.6.30.dist-info/WHEEL +6 -0
  4. passagemath_latte_4ti2-10.6.30.dist-info/top_level.txt +2 -0
  5. passagemath_latte_4ti2.dylibs/lib4ti2common.0.dylib +0 -0
  6. passagemath_latte_4ti2.dylibs/lib4ti2gmp.0.dylib +0 -0
  7. passagemath_latte_4ti2.dylibs/lib4ti2int32.0.dylib +0 -0
  8. passagemath_latte_4ti2.dylibs/lib4ti2int64.0.dylib +0 -0
  9. passagemath_latte_4ti2.dylibs/lib4ti2util.0.dylib +0 -0
  10. passagemath_latte_4ti2.dylibs/libLiDIA.0.dylib +0 -0
  11. passagemath_latte_4ti2.dylibs/libcddgmp.0.dylib +0 -0
  12. passagemath_latte_4ti2.dylibs/libgf2x.3.dylib +0 -0
  13. passagemath_latte_4ti2.dylibs/libglpk.40.dylib +0 -0
  14. passagemath_latte_4ti2.dylibs/libgmp.10.dylib +0 -0
  15. passagemath_latte_4ti2.dylibs/libgmpxx.4.dylib +0 -0
  16. passagemath_latte_4ti2.dylibs/liblatte.0.dylib +0 -0
  17. passagemath_latte_4ti2.dylibs/libnormalize.0.dylib +0 -0
  18. passagemath_latte_4ti2.dylibs/libntl.44.dylib +0 -0
  19. passagemath_latte_4ti2.dylibs/libzsolve.0.dylib +0 -0
  20. sage/all__sagemath_latte_4ti2.py +4 -0
  21. sage/interfaces/all__sagemath_latte_4ti2.py +1 -0
  22. sage/interfaces/four_ti_2.py +531 -0
  23. sage/interfaces/latte.py +632 -0
  24. sage/libs/all__sagemath_latte_4ti2.py +1 -0
  25. sage/libs/latte_int.cpython-311-darwin.so +0 -0
  26. sage/libs/latte_int.pyx +1 -0
  27. sage_wheels/bin/4ti2gmp +0 -0
  28. sage_wheels/bin/4ti2int32 +0 -0
  29. sage_wheels/bin/4ti2int64 +0 -0
  30. sage_wheels/bin/ConvertCDDextToLatte +0 -0
  31. sage_wheels/bin/ConvertCDDextToLatte.bin +0 -0
  32. sage_wheels/bin/ConvertCDDineToLatte +0 -0
  33. sage_wheels/bin/ConvertCDDineToLatte.bin +0 -0
  34. sage_wheels/bin/circuits +64 -0
  35. sage_wheels/bin/count +0 -0
  36. sage_wheels/bin/count-linear-forms-from-polynomial +0 -0
  37. sage_wheels/bin/count-linear-forms-from-polynomial.bin +0 -0
  38. sage_wheels/bin/count.bin +0 -0
  39. sage_wheels/bin/ehrhart +0 -0
  40. sage_wheels/bin/ehrhart.bin +0 -0
  41. sage_wheels/bin/ehrhart3 +0 -0
  42. sage_wheels/bin/ehrhart3.bin +0 -0
  43. sage_wheels/bin/genmodel +0 -0
  44. sage_wheels/bin/gensymm +0 -0
  45. sage_wheels/bin/graver +17 -0
  46. sage_wheels/bin/groebner +64 -0
  47. sage_wheels/bin/hilbert +17 -0
  48. sage_wheels/bin/hilbert-from-rays +0 -0
  49. sage_wheels/bin/hilbert-from-rays-symm +0 -0
  50. sage_wheels/bin/hilbert-from-rays-symm.bin +0 -0
  51. sage_wheels/bin/hilbert-from-rays.bin +0 -0
  52. sage_wheels/bin/integrate +0 -0
  53. sage_wheels/bin/integrate.bin +0 -0
  54. sage_wheels/bin/latte-maximize +0 -0
  55. sage_wheels/bin/latte-maximize.bin +0 -0
  56. sage_wheels/bin/latte-minimize +0 -0
  57. sage_wheels/bin/latte-minimize.bin +0 -0
  58. sage_wheels/bin/latte2ext +0 -0
  59. sage_wheels/bin/latte2ext.bin +0 -0
  60. sage_wheels/bin/latte2ine +0 -0
  61. sage_wheels/bin/latte2ine.bin +0 -0
  62. sage_wheels/bin/markov +64 -0
  63. sage_wheels/bin/minimize +64 -0
  64. sage_wheels/bin/normalform +64 -0
  65. sage_wheels/bin/output +0 -0
  66. sage_wheels/bin/polyhedron-to-cones +0 -0
  67. sage_wheels/bin/polyhedron-to-cones.bin +0 -0
  68. sage_wheels/bin/ppi +0 -0
  69. sage_wheels/bin/qsolve +64 -0
  70. sage_wheels/bin/rays +64 -0
  71. sage_wheels/bin/top-ehrhart-knapsack +0 -0
  72. sage_wheels/bin/top-ehrhart-knapsack.bin +0 -0
  73. sage_wheels/bin/triangulate +0 -0
  74. sage_wheels/bin/triangulate.bin +0 -0
  75. sage_wheels/bin/walk +64 -0
  76. sage_wheels/bin/zbasis +64 -0
  77. sage_wheels/bin/zsolve +0 -0
  78. sage_wheels/share/latte-int/m-knapsack.mpl +1245 -0
  79. sage_wheels/share/latte-int/simplify.add +7 -0
  80. sage_wheels/share/latte-int/simplify2.add +9 -0
  81. sage_wheels/share/latte-int/simplify3.add +13 -0
@@ -0,0 +1,1245 @@
1
+ with(combinat):with(LinearAlgebra):with(linalg):with(numtheory):
2
+ # Outline
3
+ # Let A=[A_1,..,A_{N+1}] be a list of positive integers and t a variable.
4
+ # We compute the number of integral solutions for A_1x_1+..+A_{N+1}x_{N+1}=t.
5
+ # The output of this as a step polynomial function of t.
6
+ #
7
+ # This program is aimed at computing efficiently the highest k coefficients
8
+ # of this step polynomial.
9
+ #
10
+ #
11
+ #
12
+ # Main Functions
13
+ # 1. complete_knapsack(A,t,T). Computes the Ehrhart polynomial for the knapsack A1x1+..A_{N+1}x_{N+1}=t, t a variable or an integer. The output is a quasi polynomial function of t and T, expressed as a function of T^k and MOD(a*t, b). MOD(a*t,b) is the number in the half-open interval [0,b) that is equal to a*t mod n.
14
+ #
15
+ # 2. coeff_Nminusk_knapsack(A,t,T,k). Computes the N-k-degree term in the Ehrhart polynomial. The output is a periodic function of t and polynomial in T.
16
+ #
17
+ # 3. latteMod(a,b). Computes the number in the half-open interval [0,b) that is equal to a mod b.
18
+ #
19
+ # Note that in the Ehrhart polynomial, the periodic coefficients are functions of t, while the monomial terms use T. This is done so that you can use Maple's coeff() function if you wish. T and t should always be evaluated at the same point.
20
+ #
21
+ # Example usage
22
+ # L:=[1,2,3,4,5];
23
+ # coeff4minus0:=coeff_Nminusk_knapsack(L, t, T, 0); #find the T^4 term
24
+ # coeff4minus3:=coeff_Nminusk_knapsack(L, t, T, 3); #find the T^1 term
25
+ # eval(subs({T=10, t=10, MOD=latteMod}, coeff4minus3)); #evaluate the t^1 term at t=T=10.
26
+ #
27
+ # ehrhartPoly:=complete_knapsack(L,t,T);
28
+ # coeff(ehrhartPoly, T^4); #get the leading term's coefficient
29
+ # eval(subs({T=10, t=10, MOD=latteMod}, ehrhartPoly)); #number of solutions to x_1 + 2x_2 + 3x+3 + 4x_4 +5x_5 = 10, x_i >= 0...the answer is 30
30
+ #
31
+ # License
32
+ # This Maple script is part of the LattE integrale 1.7 package made available
33
+ # under the GNU General Public License at http://www.math.ucdavis.edu/~latte/.
34
+ #
35
+ # Testing
36
+ # Define this variable to have the code check self-tests (some are expensive)
37
+ # (this is for "make check", not for production code).
38
+ #CHECK_EXAMPLES := true:
39
+
40
+ # Enable checking ASSERTions
41
+ kernelopts(assertlevel=1):
42
+
43
+ ##################################
44
+ #Start example checking functinos#
45
+ ##################################
46
+
47
+ # Like ASSERT, but with better reporting (for automatic tests).
48
+ # Example usage: TEST_EQUAL("sqrt(4)", "2", "sqrt test #1");
49
+ TEST_EQUAL:=proc(a_expr, b_expr, message) local a, b;
50
+ printf("Checking %s\n", message);
51
+ a := eval(parse(a_expr));
52
+ b := eval(parse(b_expr));
53
+ if not (a = b) then
54
+ printf("FAIL: Results differ:\n Got: %a\n Should be: %a\n", a, b);
55
+ fi:
56
+ end:
57
+
58
+ # Find out whether we are to check examples.
59
+ # Uses the global CHECK_EXAMPLES
60
+ # Example usage
61
+ # if check_examples() then
62
+ # TEST_EQUAL("sqrt(4)", "2", "sqrt test #1");
63
+ # TEST_EQUAL("sqrt(0)", "0", "sqrt test #2");
64
+ # TEST_EQUAL("2^3", "8", "power test #1");
65
+ # fi;
66
+ check_examples:=proc()
67
+ type(CHECK_EXAMPLES, boolean) and CHECK_EXAMPLES;
68
+ end:
69
+
70
+
71
+
72
+ ############################
73
+ #Start of library functions#
74
+ ############################
75
+
76
+
77
+ #Global values:
78
+ USE_DUAL:=true: #uses dual cone decomposition if true
79
+ MAX_DET_part_f_of_knapsack:=0: #global variable that collects a statistic on the performance of the part_f_of_knapsack function
80
+
81
+
82
+
83
+ # Basic programs: primitive_vector, ortho_basis, ComplementList, random_vector
84
+ # PRIMITIVE VECTOR
85
+ # Input: A :a vector with rational coordinates.
86
+ # Output: A vector with integral coordinates:
87
+ # Math: the primitive vector on the half line R^+A;
88
+ # Example: #primitive_vector([0,-1/2])->[0,-1];
89
+ primitive_vector:=proc(A) local d,n,g;
90
+ d:=nops(A);
91
+ n:=ilcm(seq(denom(A[i]),i=1..d));
92
+ g:=igcd(seq(n*A[i],i=1..d));
93
+ if g<>0 then
94
+ [seq(n*A[i]/g,i=1..d)];
95
+ else [seq(n*A[i],i=1..d)];
96
+ fi;
97
+ end:
98
+ if check_examples() then
99
+ TEST_EQUAL("primitive_vector([2,2,2,8,16,100])", "[1, 1, 1, 4, 8, 50]", "test primitive_vector #1");
100
+ TEST_EQUAL("primitive_vector([1234/1345, 1234/122, 2457/3568, 4, -24/2457, -6])", "[219965080608, 2425024864080, 165097758735, 959004970560, -2341892480, -1438507455840]", "test primitive_vector #2");
101
+ fi;
102
+
103
+
104
+ #COMPLEMENT LIST
105
+ #The output is the Complement List, within the list [1,..,d]
106
+ ComplementList:=proc(K,d);
107
+ RETURN([seq (`if` (member(i,K)=false, i, op({})),i=1..d)]);
108
+ end:
109
+
110
+ random_vector:=proc(N,d) local R;
111
+ R:=rand(N);
112
+ [seq(R()+1,i=1..d)]:
113
+ end:
114
+
115
+ ortho_basis:=proc(d) local i,v;
116
+ for i from 1 to d do
117
+ v[i]:=[seq(0,j=1..i-1),1,seq(0,j=i+1..d)]
118
+ od;
119
+ [seq(v[j],j=1..d)];
120
+ end:
121
+
122
+ # Signed decomposition into unimodular cones
123
+ # A "simplicial cone" is a list of d linearly independent vectors in Z^d, sometimes assumed primitive.
124
+ # short_vector(A)
125
+ # # Input: A is a list of d linearly independent vectors.
126
+ # # Output: sho is a vector of dimension d.
127
+ short_vector:=proc(A) local n,base,i,sho;
128
+ n:=nops(A);
129
+ base:=IntegerRelations[LLL](A);
130
+ sho:=base[1];
131
+ i:=1;
132
+ while i<=n-1 do
133
+ if max(seq(abs(sho[j]),j=1..n))<=max(seq(abs(base[i+1][j]),j=1..n))
134
+ then sho:=sho; else sho:=base[i+1];
135
+ fi;
136
+ i:=i+1;
137
+ od;
138
+ sho;
139
+ end:
140
+ if check_examples() then
141
+ TEST_EQUAL("short_vector([[2200,2200],[2,100]])", "[2, 100]", "test short_vector #1");
142
+ TEST_EQUAL("short_vector([[-2200,-2200,-2346],[2,100,-565], [457,568,-2457]])", "[449, 168, -197]", "test short_vector #2");
143
+ fi;
144
+
145
+ # # sign_entries_vector(V)
146
+ # # Input : vector V of dimension d.
147
+ # # Output: L=[ Lplus,Lminus,Lzero] is a partition of [1..d] into three sublists,
148
+ # # according to the signs of the entries of the vector V.
149
+ sign_entries_vector:=proc(V) local d,i,Lplus,Lminus,Lzero;
150
+ d:=nops(V); Lplus:=[]; Lminus:=[];Lzero:=[];
151
+
152
+ for i from 1 to d do
153
+ if type(V[i],positive) then Lplus:=[op(Lplus),i];
154
+ elif type(V[i],negative) then Lminus:=[op(Lminus),i];
155
+ else Lzero:=[op(Lzero),i];
156
+ fi;
157
+ od;
158
+ [Lplus,Lminus,Lzero];
159
+ end:
160
+
161
+ # # good_vector(G)
162
+ # # Input G is a "simplicial cone"
163
+ # # Output consists of 2 elements:
164
+ # # V is a vector in Z^d.
165
+ # # L=[ Lplus,Lminus,Lzero] is a partition of [1..d] into three sublists,
166
+ # # according to the signs of the entries of the vector V. in the basis G.
167
+ good_vector:=proc(G) local n,A,Ainverse,B,sho,V,L;
168
+ n:=nops(G);
169
+ #A:=Transpose(Matrix(G));
170
+ Ainverse:=inverse(matrix(G));
171
+ B:=convert(Ainverse, listlist);
172
+ #B:=[seq(convert(Ainverse[i,1..n],list),i=1..n)];
173
+ sho:=short_vector(B);
174
+ V :=[seq(add(G[j][i]*sho[j],j=1..n),i=1..n)];
175
+ L:= sign_entries_vector(sho);
176
+ [V,L];
177
+ end:
178
+ if check_examples() then
179
+ TEST_EQUAL("good_vector([[2200,2129],[101,100]])", "[[31, 30], [[1, 2], [], []]]", "test good_vector #1");
180
+ fi;
181
+
182
+
183
+ # # signed_decomp(eps,G,v,L)
184
+ # # Input : eps = 1 or -1
185
+ # # G is a "simplicial cone"
186
+ # # V is a vector of dim d
187
+ # # L= [ Lplus,Lminus,Lzero] is a partition of [1..d] into three sublists,
188
+ # # Output : [Nonuni,Uni]
189
+ # # Nonuni and Uni are lists of terms [eps,detG,G], where
190
+ # # eps=1 or -1,
191
+ # # detG is an integer,
192
+ # # G is a list of d linearly independant primitive vectors in Z^d.
193
+ signed_decomp:=proc(eps,G,v,L) local Nonuni,Uni,Lplus,Lminus,Lzero,kplus,kminus,kzero,i,j, C,M, detC, Csigned ;
194
+ Nonuni:=[]; Uni:=[];
195
+ Lplus:=L[1]; Lminus:=L[2]; Lzero:=L[3];
196
+ kplus:=nops(Lplus); kminus:=nops(Lminus); kzero:=nops(Lzero);
197
+ if kplus>0 then
198
+ for i from 1 to kplus do
199
+ C:=[seq(G[Lplus[j]],j=1..i-1),seq(-G[Lplus[j]],j=i+1..kplus),v,seq(G[Lminus[j]],j=1..kminus),seq(G[Lzero[j]],j=1..kzero)];
200
+
201
+ detC := det(matrix(C));
202
+ Csigned:=[eps*(-1)^(i+kplus),detC,C];
203
+
204
+ if abs(detC)>1 then
205
+ Nonuni:=[op(Nonuni),Csigned] else Uni:=[op(Uni),Csigned];
206
+ fi;
207
+ od;
208
+ fi;
209
+
210
+ if kminus>0 then
211
+ for i from 1 to kminus do
212
+ C:=[seq(G[Lplus[j]],j=1..kplus),-v,seq(-G[Lminus[j]],j=1..i-1),seq(G[Lminus[j]],j=i+1..kminus),seq(G[Lzero[j]],j=1..kzero)];
213
+
214
+ detC := det(matrix(C));
215
+ Csigned:=[eps*(-1)^(i+1),detC,C];
216
+
217
+ if abs(detC)>1 then
218
+ Nonuni:=[op(Nonuni),Csigned] else Uni:=[op(Uni), Csigned];
219
+ fi;
220
+ od;
221
+ end if;
222
+ [Nonuni,Uni];
223
+ end:
224
+
225
+
226
+ # # good_cone_dec(eps,G)
227
+ # # Input: eps = 1 or -1
228
+ # # G is a simplicial cone
229
+ # # Output: two lists [Nonuni,Uni] as in procedure signed_decomp:
230
+ good_cone_dec:=proc(eps,G) local n,A,R,Output, det_A;
231
+ n:=nops(G); A:=matrix([seq(G[i],i=1..n)]);
232
+ det_A:=det(A);
233
+ if abs(det_A)=1 then
234
+ Output:=[[],[[eps,det_A,G]]];
235
+ else R:=good_vector(G);
236
+ Output:=signed_decomp(eps,G,R[1],R[2]);
237
+ fi;
238
+ end:
239
+ if check_examples() then
240
+ TEST_EQUAL("good_cone_dec(-1, [[2200,2129],[101,100]])", "[[[1, 70, [[-101, -100], [31, 30]]]], [[-1, 1, [[2200, 2129], [31, 30]]]]]", "test good_cone_dec #1");
241
+ TEST_EQUAL("good_cone_dec(-1, [[2200,2129,5675],[101,100,-4545], [45613,345,-135]])", " [[[-1, -10243805, [[1, 0, 0], [2200, 2129, 5675], [101, 100, -4545]]], [-1, -1554525, [[45613, 345, -135], [-1, 0, 0], [101, 100, -4545]]], [1, -2245290, [[45613, 345, -135], [-1, 0, 0], [-2200, -2129, -5675]]]], []]", "test good_cone_dec #2");
242
+ fi;
243
+
244
+
245
+ # # more_decomposition_in_cones(cones)
246
+ # # Input: cones =[cones[1],cones[2]] as in procedure signed_decomp
247
+ # # Output: [Newnonuni,Newuni] as in procedure signed_decomp
248
+ more_decomposition_in_cones:=proc(cones) local i,Newuni,Newnonuni,newcones:
249
+ Newnonuni:=[];
250
+ Newuni:=cones[2];
251
+ for i from 1 to nops(cones[1]) do
252
+ newcones:=good_cone_dec(cones[1][i][1],cones[1][i][3]);
253
+ Newnonuni:=[op(Newnonuni),op(newcones[1])];
254
+ Newuni:=[op(Newuni),op(newcones[2])];
255
+ od;
256
+ [Newnonuni,Newuni];
257
+ end:
258
+ ###############################
259
+
260
+ # # cone_dec(G)
261
+ # # Input: G is a "simplicial cone"
262
+ # # Output: A list of terms [eps,detG,G] where
263
+ # # eps =1 or -1,
264
+ # # detG is an integer ( hopefully 1 or -1),
265
+ # # G is a "simplicial cone", (hopefully unimodular)
266
+ cone_dec:=proc(G) local seed, i,ok;
267
+ if G=[] then
268
+ RETURN([[1,1,[]]]);
269
+ fi:
270
+ seed:=good_cone_dec(1,G);
271
+ ok:=0;
272
+ i:=1;
273
+ while ok=0 do
274
+ seed:=more_decomposition_in_cones(seed);
275
+ if seed[1]=[] then
276
+ ok:=1;else ok:=0;i:=i+1;
277
+ fi;
278
+ od;
279
+ RETURN(seed[2]);
280
+ end:
281
+ if check_examples() then
282
+ TEST_EQUAL("cone_dec([[2200,2129],[101,100]])", "[[1, 1, [[2200, 2129], [31, 30]]], [-1, 1, [[-1, -1], [31, 30]]], [1, 1, [[-1, -1], [101, 100]]]]", "test cone_dec #1");
283
+ TEST_EQUAL("cone_dec([[7,12,3],[101,0,0], [7,5,-5]])", "[[-1, 1, [[3, 4, 0], [-7, -12, -3], [7, 5, -5]]], [1, 1, [[3, 4, 0], [-7, -12, -3], [0, 1, 1]]], [1, 1, [[0, 1, 1], [1, 1, 0], [-1, 0, 0]]], [1, 1, [[-2, -2, 1], [7, 5, -5], [0, 1, 1]]], [1, 1, [[-1, -1, 1], [2, 2, -1], [0, 1, 1]]], [-1, 1, [[0, -1, -1], [0, 1, 0], [1, 0, 0]]], [1, 1, [[1, 1, -1], [0, 1, 0], [1, 0, 0]]], [1, 1, [[1, 1, -1], [0, 1, 1], [0, -1, 0]]], [1, 1, [[5, 4, -3], [0, -1, -1], [7, 5, -5]]], [-1, 1, [[5, 4, -3], [-3, -4, 0], [7, 5, -5]]], [1, 1, [[5, 4, -3], [-3, -4, 0], [0, 1, 1]]], [1, -1, [[1, 0, 0], [2, 4, 1], [1, 1, 0]]], [-1, -1, [[7, 12, 3], [2, 4, 1], [1, 1, 0]]], [-1, 1, [[0, 1, 1], [1, 1, 0], [3, 5, 1]]], [1, 1, [[7, 12, 3], [1, 1, 0], [3, 5, 1]]], [-1, 1, [[7, 12, 3], [0, -1, -1], [3, 5, 1]]], [-1, -1, [[-4, -3, 3], [-7, -5, 5], [2, 2, -1]]], [1, -1, [[-4, -3, 3], [1, 1, -1], [2, 2, -1]]]]", "test cone_dec #2");
284
+ fi;
285
+
286
+ # new Cone dec via polar
287
+
288
+ # Signed decomposition into unimodular cones via polar dec
289
+ # A "simplicial cone" is a list of d linearly independent vectors in Z^d, sometimes assumed primitive.
290
+ # short_vector(A)
291
+ # # Input: A is a list of d linearly independent vectors.
292
+ # # Output: sho is a vector of dimension d.
293
+ new_short_vector:=proc(A) local n,base,i,sho;
294
+ n:=nops(A);
295
+ base:=IntegerRelations[LLL](A);
296
+ sho:=base[1];
297
+ i:=1;
298
+ while i<=n-1 do
299
+ if max(seq(abs(sho[j]),j=1..n))<=max(seq(abs(base[i+1][j]),j=1..n))
300
+ then sho:=sho; else sho:=base[i+1];
301
+ fi;
302
+ i:=i+1;
303
+ od;
304
+ sho;
305
+ end:
306
+ if check_examples() then
307
+ TEST_EQUAL("new_short_vector([[2200,2200],[2,100]])", "[2, 100]", "test new_short_vector #1");
308
+ TEST_EQUAL("new_short_vector([[-2200,-2200,-2346],[2,100,-565], [457,568,-2457]])", "[449, 168, -197]", "test new_short_vector #2");
309
+ fi;
310
+
311
+
312
+ # # good_vector(G)
313
+ # # Input G is a "simplicial cone"
314
+ # # Output is a vector V in Z^d.
315
+ # #
316
+
317
+ polar_good_vector:=proc(G) local n,A,Ainverse,B,sho,V,L,newV,VV,ok,i,out;
318
+ n:=nops(G);
319
+ A:=Transpose(Matrix(G));
320
+ Ainverse:=MatrixInverse(A);
321
+ B:=[seq(convert(Ainverse[1..n,i],list),i=1..n)]; #print("B",B);
322
+ sho:=new_short_vector(B);
323
+ V :=[seq(add(G[j][i]*sho[j],j=1..n),i=1..n)];
324
+ newV:=LinearSolve(A,Vector(V));
325
+ VV:=convert(newV,list);
326
+ ok:=0;i:=1;
327
+ while i<= nops(VV) and ok=0 do
328
+ if VV[i]<=0 then i:=i+1;
329
+ else ok:=1; i:=nops(VV)+1;
330
+ fi;
331
+ od:
332
+ if ok=1 then
333
+ out:=V;
334
+ else
335
+ out:=[seq(-V[i],i=1..nops(V))];
336
+ fi;
337
+ out;
338
+ end:
339
+ if check_examples() then
340
+ TEST_EQUAL("polar_good_vector([[2200,2129],[101,100]])", "[31, 30]", "test polar_good_vector #1");
341
+ fi;
342
+
343
+ # # signed_decomp(G,v)
344
+ # # Input : signum = 1 or -1
345
+ # # G is a "simplicial cone"
346
+ # # v is a vector of dim d
347
+ # # Output : [Nonuni,Uni]
348
+ # # Nonuni and Uni are lists of terms [eps,G], where
349
+ # # eps=1 or -1,
350
+ # # G is a list of d linearly independant primitive vectors in Z^d.
351
+ polar_signed_decomp:=proc(signum,G,v) local eps,Nonuni,Uni,Lplus,Lminus,Lzero,kplus,kminus,kzero,i,j, C,M, detC, Csigned ;
352
+ Nonuni:=[]; Uni:=[];
353
+
354
+ eps:=sign(Determinant(Matrix(G)));
355
+ for i from 1 to nops(G) do
356
+ C:=[seq(G[j],j=1..i-1),v,seq(G[j],j=i+1..nops(G))];
357
+ detC := Determinant(Matrix(C));
358
+ Csigned:=[signum*eps*sign(detC),C];
359
+ if detC<>0then
360
+ if abs(detC)>1 then
361
+ Nonuni:=[op(Nonuni),Csigned]
362
+ else
363
+ Uni:=[op(Uni),Csigned];
364
+ fi;
365
+ else fi;
366
+ od;
367
+ [Nonuni,Uni];
368
+ end:
369
+ if check_examples() then
370
+ TEST_EQUAL("polar_signed_decomp(1, [[101,2],[7,5]], [7,6])", "[[[-1, [[7, 6], [7, 5]]], [1, [[101, 2], [7, 6]]]], []]", "test polar_signed_decomp #1");
371
+ fi;
372
+
373
+
374
+ # # polar_good_cone_dec(signum,G)
375
+ # # Input: signum = 1 or -1
376
+ # # G is a simplicial cone
377
+ # # Output: two lists [Nonuni,Uni] as in procedure polar_signed_decomp:
378
+ polar_good_cone_dec:=proc(signum,G) local eps,n,A,R,Output, det_A;
379
+ n:=nops(G); A:=Matrix([seq(G[i],i=1..n)]);
380
+ det_A:=Determinant(A); eps:=sign(det_A);
381
+ #print("G",det_A);
382
+ if abs(det_A)=1 then #print(itisuni);
383
+ Output:=[[],[[1,G]]];
384
+
385
+ else R:=polar_good_vector(G);#print("goodvector",R,G);
386
+ Output:=polar_signed_decomp(signum,G,R);
387
+ fi;
388
+ end:
389
+ if check_examples() then
390
+ TEST_EQUAL("polar_good_cone_dec(-1, [[2200,2129],[101,100]])", "[[[-1, [[31, 30], [101, 100]]]], [[-1, [[2200, 2129], [31, 30]]]]]", "test polar_good_cone_dec #1");
391
+ fi;
392
+
393
+
394
+
395
+ # # polar_more_decomposition_in_cones(cones)
396
+ # # Input: cones =[cones[1],cones[2]] as in procedure polar_signed_decomp
397
+ # # Output: [Newnonuni,Newuni] as in procedure signed_decomp
398
+ polar_more_decomposition_in_cones:=proc(cones) local i,Newuni,Newnonuni,newcones:
399
+ Newnonuni:=[]; #print("cones",cones);
400
+ Newuni:=cones[2];
401
+ for i from 1 to nops(cones[1]) do
402
+ newcones:=polar_good_cone_dec(cones[1][i][1],cones[1][i][2]);
403
+
404
+ Newnonuni:=[op(Newnonuni),op(newcones[1])];
405
+ Newuni:=[op(Newuni),op(newcones[2])];
406
+ od;
407
+ [Newnonuni,Newuni];
408
+ end:
409
+
410
+ ###############################
411
+
412
+ # # polar_cone_dec(G)
413
+ # # Input: G is a "simplicial cone"
414
+ # # Output: A list of terms [eps,G] where
415
+ # # eps =1 or -1,
416
+ # # detG is an integer ( hopefully 1 or -1),
417
+ # # G is a "simplicial cone", (hopefully unimodular)
418
+ polar_cone_dec:=proc(G) local A,eps,seed, i,ok;
419
+ if G=[] then
420
+ RETURN([[1,[]]]);
421
+ fi: A:=Matrix([seq(G[i],i=1..nops(G))]);
422
+ eps:=sign(Determinant(A));#print("DET",eps);
423
+ if abs(Determinant(A))=1 then
424
+ #seed:=polar_good_cone_dec(G);#print(absol=1,seed);
425
+ RETURN([[1,G]]);
426
+ else
427
+ seed:=polar_good_cone_dec(1,G);fi;
428
+ #print("start",seed);
429
+ ok:=0;
430
+ i:=1;
431
+ while ok=0 do
432
+ seed:=polar_more_decomposition_in_cones(seed); #print("i,SEED",i,seed);
433
+ if seed[1]=[] then
434
+ ok:=1;else ok:=0;i:=i+1;
435
+ fi;
436
+ od;
437
+ RETURN(seed[2]);
438
+ end:
439
+ if check_examples() then
440
+ TEST_EQUAL("polar_cone_dec([[2200,2129],[101,100]])", "[[1, [[2200, 2129], [31, 30]]], [-1, [[1, 1], [101, 100]]], [1, [[31, 30], [1, 1]]]]", "test polar_cone_dec #1");
441
+ TEST_EQUAL("polar_cone_dec([[7,12,3],[11,0,0], [7,5,-5]])", "[[1, [[7, 12, 3], [3, 4, 0], [7, 5, -5]]], [-1, [[1, 1, 0], [1, 0, 0], [-1, -1, 1]]], [-1, [[2, 1, -2], [1, 1, 0], [7, 5, -5]]], [-1, [[3, 4, 0], [2, 1, -2], [7, 5, -5]]], [1, [[3, 5, 1], [1, 1, 0], [3, 4, 0]]], [-1, [[7, 12, 3], [3, 5, 1], [3, 4, 0]]], [1, [[7, 12, 3], [1, 1, 0], [3, 5, 1]]], [1, [[2, 4, 1], [1, 0, 0], [1, 1, 0]]], [-1, [[7, 12, 3], [2, 4, 1], [1, 1, 0]]], [-1, [[1, 1, 0], [4, 3, -3], [7, 5, -5]]], [1, [[1, 1, 0], [-1, -1, 1], [4, 3, -3]]], [1, [[3, 3, -1], [1, 1, 0], [2, 1, -2]]], [1, [[3, 4, 0], [3, 3, -1], [2, 1, -2]]], [1, [[3, 4, 0], [1, 1, 0], [3, 3, -1]]]]", "test polar_cone_dec #2");
442
+ fi;
443
+
444
+
445
+
446
+ # Cone decomposition via polar cone
447
+ primitive_vector:=proc(A) local d,n,g;
448
+ d:=nops(A);
449
+ n:=ilcm(seq(denom(A[i]),i=1..d));
450
+ g:=igcd(seq(n*A[i],i=1..d));if g<>0 then
451
+ [seq(n*A[i]/g,i=1..d)];else [seq(n*A[i],i=1..d)];fi;
452
+ end:
453
+ if check_examples() then
454
+ TEST_EQUAL("primitive_vector([2200,2120,2340,240])", "[110, 106, 117, 12]", "test primitive_vector #1");
455
+ fi;
456
+
457
+
458
+ #The polar cone.
459
+ polarcone:=proc(A) local n,B,Ainverse,out;
460
+ n:=nops(A);
461
+ #MatrixInverse(Transpose(Matrix(A)));
462
+ B:=Matrix(A); #print("B",Matrix(A),B);
463
+ Ainverse:=MatrixInverse(B);#print(Ainverse);
464
+ out:=[seq(convert(Transpose(Column(Ainverse,i)),list),i=1..n)];
465
+ end:
466
+ if check_examples() then
467
+ TEST_EQUAL("polarcone([[2200,2129],[101,100]])", " [[100/4971, -101/4971], [-2129/4971, 2200/4971]]", "test polarcone #1");
468
+ TEST_EQUAL("polarcone([[1,0],[0,-1]])", "[[1,0],[0,-1]]", "test polarcone #2");
469
+ fi;
470
+
471
+
472
+ #polarcone([[1,0],[1,1]]);
473
+ #Compute the cone decomposition going to polar cone and back
474
+ new_dual_dec_cone:=proc(G)
475
+ local out,dual_cone,L,dec,i;
476
+ out:=[];
477
+ dual_cone:=polarcone(G);#print("dual",dual_cone);
478
+ L:=[seq(primitive_vector(dual_cone[m]),m=1..nops(dual_cone))];#print("L",L);
479
+ dec:=polar_cone_dec(L);#print("decpolar",dec,L);
480
+ #print("enteringpolarcone",dec);
481
+ for i from 1 to nops(dec) do
482
+ out:=[op(out),[dec[i][1],polarcone(dec[i][2])]];
483
+ od:
484
+ out:
485
+ end:
486
+ if check_examples() then
487
+ TEST_EQUAL("new_dual_dec_cone([[1,0],[1,10]])", "[[1, [[1, 0], [0, 1]]], [1, [[0, -1], [1, 10]]]]", "test new_dual_dec_cone #1");
488
+ fi;
489
+
490
+
491
+ # HERE STARTS BACK TO KNAPSACK;
492
+ # Let W be a cone basis w_i in R^k. Lambda a lattice with base alpha_i in R^k, s=[s_1..s_k] symbolic in R^k.
493
+ # Compute coordinates and change of coordinates: cone_in_basis_Lambda; Basis_Lattice, the_vertex.
494
+ # INPUT : W:=a list of p-vectors w_i of lenght r (with rational entries), Lambda a list of p-vectors alpha_i of lenght r (with rational entries).
495
+ # OUTPUT: a list of r numvectors with integral coordinates.
496
+ # MATH: we look for the primitive vectors of the cone W generated by w_i in the basis of alpha_i
497
+ # EXAMPLE: Lambda:=[[2/3,-5/2],[3/7,-8/5]];W:=[[1,0],[1,1]];cone_in_basis_Lambda(W,Lambda):=[[-16, 25], [-426, 665]];Then -426*Lambda[1]+665*Lambda[2]=[1,1]=w[2]
498
+ cone_in_basis_Lambda:=proc(W,Lambda)
499
+ local M,MM,newW,i;
500
+ newW:=[];
501
+ M:=Transpose(Matrix([seq(Lambda[i],i=1..nops(Lambda))])):
502
+ #print("M", M);
503
+ MM:=MatrixInverse(M);
504
+ #print("MM", MM);
505
+ for i from 1 to nops(W) do
506
+ newW:=[op(newW),primitive_vector(convert(Transpose(Multiply(MM,Vector(W[i]))),list))];
507
+ od;
508
+ newW;
509
+ end:
510
+ if check_examples() then
511
+ TEST_EQUAL("cone_in_basis_Lambda([[1,0],[1,10]], [[1,0],[1,-10]])", "[[1, 0], [2, -1]]", "test cone_in_basis_Lambda #1");
512
+ fi;
513
+
514
+ # INPUT: Small :=[a1,a2,...,ar] a list of positive integers, f an integer.
515
+ # OUTPUT: a list of r lists. Each of the list is a list of integers.
516
+ # MATH: we compute a basis of the lattice Lambda, consisting of the elements
517
+ # [k1,k2,...,kr] such that k1*a1+k2*a2+...kr*ar is a multiple of f
518
+ # Example: Basis_Lattice([1,2,2],2):=[[2, 0, 0], [-2, 1, 0], [-2, 0, 1]];
519
+ Basis_Lattice:=proc(Small,f) local P,H,U,Lambda,hh,newf;
520
+ P:=matrix([[seq(Small[i],i=1..nops(Small))]]);
521
+ H:=ihermite(transpose(P),u);
522
+ hh:=row(H,1)[1];
523
+ U:=eval(u):
524
+ #print("U", U);
525
+ newf:=f/igcd(hh,f);
526
+ Lambda:=[[seq(newf*convert(row(U,1),list)[i],i=1..nops(Small))],seq([seq(convert(row(U,i),list)[k],k=1..nops(Small))],i=2..nops(Small))];
527
+ Lambda;
528
+ end:
529
+ if check_examples() then
530
+ TEST_EQUAL("Basis_Lattice([23,43,21,43,3,1,3], 5234)", "[[0, 0, 0, 0, 0, 5234, 0], [1, 0, 0, 0, 0, -23, 0], [0, 1, 0, 0, 0, -43, 0], [0, 0, 1, 0, 0, -21, 0], [0, 0, 0, 1, 0, -43, 0], [0, 0, 0, 0, 1, -3, 0], [0, 0, 0, 0, 0, -3, 1]]", "test Basis_Lattice #1");
531
+ fi;
532
+
533
+ # INPUT: Small :=[a1,a2,...,ar] a list of positive integers, f an integer.
534
+ # OUTPUT: a list of r integers.
535
+ # MATH: We compute s1,....sr,s0 such that a1s1+a2s2+..arsr+s0f=1. we output only [s1..sr].
536
+ # Example: the_vertex([1,2,2],2):=[1, 0, 0];
537
+ the_vertex:=proc(Small,f) local P,H,out,u;
538
+ P:=matrix([[seq(Small[i],i=1..nops(Small)),f]]);
539
+ H:=ihermite(transpose(P),u);
540
+ out:=[seq(convert(row(u,1),list)[i],i=1..nops(Small))];
541
+ out;
542
+ end:
543
+
544
+ # Some tools: B_and_S; F_k;
545
+ # INPUT : A:=a list of positive integers, f a positive integer.
546
+ # OUTPUT: a list of two lists: [B,S].
547
+ # MATH: B is the list of elements in A consising of the elements A[i] such that f divides A[i]. S is the complement list
548
+ # Example: B_and_S([2,2,2,3,4,5],2):=[[2, 2, 2, 4], [3, 5]];
549
+ #
550
+ B_and_S:=proc(A,f) local j,B,S;
551
+ B:=[];
552
+ S:=[];
553
+ for j from 1 to nops(A) do
554
+ if modp(A[j],f)=0 then
555
+ B:=[op(B),A[j]];
556
+ S:=S;
557
+ else
558
+ B:=B; S:=[op(S),A[j]];
559
+ fi;
560
+ od;
561
+ [B,S];
562
+ end:
563
+ if check_examples() then
564
+ TEST_EQUAL("B_and_S([2,2,2,3,4,5],2)", "[[2, 2, 2, 4], [3, 5]]", "test B_and_S #1");
565
+ fi;
566
+
567
+ # find all k subsets of a list of objects
568
+ # @parm inputList: a list. ex [x, y, z, w]
569
+ # @parm k: the subset size
570
+ myChoose:=proc(inputList, k)
571
+ local n, L;
572
+ local i;
573
+ local counter;
574
+ local limit;
575
+ local outputList:=[];
576
+ local newSubset;
577
+ local numDiff;
578
+
579
+ #use the maple choose funciton if there are not many unique numbers.
580
+ sortedInputList = sort(inputList);
581
+ numDiff := 0;
582
+ for i from 1 to nops(sortedInputList)-1 do
583
+ if sortedInputList[i] <> sortedInputList[i+1] then
584
+ numDiff := numDiff + 1;
585
+ end;
586
+ end;
587
+
588
+ if numDiff = 2 then
589
+ return choose(inputList, k);
590
+ end;
591
+
592
+
593
+ #L is going to be a list of index values to add to the output list.
594
+ #L starts off as [n-k, ..., 3, 2, 1].
595
+ #We keep adding values to L[1] and if L[i] > n - i +1 we add 1 to the next element
596
+ #Hence the last element added is [n, n-1, n-2, ..., n-k+1]
597
+
598
+ n:=nops(inputList);
599
+ L:=[seq(0, i=1..k)];
600
+ for i from 1 to k do
601
+ L[i]:=k-i+1;
602
+ end;
603
+
604
+ limit:= binomial(n,k);
605
+ counter:=1;
606
+ while counter < limit do
607
+
608
+ #add a subset of inputList to outputList indexed by L
609
+ #print(counter, L);
610
+ newSubset:=[seq(0,i=1..k)];
611
+ for i from 1 to k do
612
+ newSubset[i]:=inputList[L[k-i+1]];
613
+ end;
614
+ outputList:=[op(outputList), newSubset];
615
+
616
+ L[1]:=L[1]+1;
617
+
618
+ i:=1;
619
+ while L[i] > (n - i + 1) do
620
+ L[i+1]:=L[i+1]+1;
621
+ i:=i+1;
622
+ end;
623
+
624
+ while i > 1 do
625
+ L[i-1]:=L[i]+1;
626
+ i:=i-1;
627
+ end;
628
+ counter:=counter+1;
629
+ end;
630
+
631
+ #add the last element to the output list.
632
+ #print(counter, L);
633
+ newSubset:=[seq(0,i=1..k)];
634
+ for i from 1 to k do
635
+ newSubset[i]:=inputList[L[k-i+1]];
636
+ end;
637
+ outputList:=[op(outputList), newSubset];
638
+ end:
639
+ if check_examples() then
640
+ TEST_EQUAL("myChoose([2,2,2,3,4,5],2)", "[[2, 2], [2, 2], [2, 3], [2, 4], [2, 5], [2, 2], [2, 3], [2, 4], [2, 5], [2, 3], [2, 4], [2, 5], [3, 4], [3, 5], [4, 5]]", "test myChoose #1");
641
+ fi;
642
+
643
+
644
+
645
+
646
+ # Input:= a list A of positive integers, an integer k, 0<=k<=nops(A)
647
+ # Output:= a list
648
+ # Math: We compute S_k (Poles>=N+1-k); in the application k is big
649
+ # F_k([2,3,3,55],2):=[1,3]; F_k([2,3,3,55],3):=[1, 2, 3, 55];
650
+ F_k:=proc(A,k) local N,g,C,i,out,a;
651
+ out:={};
652
+ N:=nops(A)-1;
653
+ for a from 0 to k do
654
+ C:=myChoose(A,N+1-a);
655
+ for i from 1 to nops(C) do
656
+ g:= igcd(op(C[i]));out:={op(out),g};
657
+ od:
658
+ od:
659
+ out:=[op(out)];
660
+ end:
661
+ if check_examples() then
662
+ TEST_EQUAL("F_k([2,3,3,55],3)", "[1, 2, 3, 55]", "test F_k #1");
663
+ TEST_EQUAL("F_k([2,3,3,55],2)", "[1, 3]", "test F_k #2");
664
+ fi;
665
+
666
+
667
+ # The coefficient of t^h in the function E(A,f)(t):
668
+ fract:=proc(a,n) local out,p,q,newa,t;
669
+ if a=0 then out:=0;
670
+ elif type(simplify(a),integer)=true then out:=0;
671
+ else
672
+ p:=numer(a); q:=denom(a);
673
+ newa:=modp(p,q);
674
+ t:=MOD(newa/q*n,1);
675
+ fi;
676
+ end:
677
+ if check_examples() then
678
+ TEST_EQUAL("fract(2/3,-1)", "MOD(-2/3,1)", "test fract #1");
679
+ TEST_EQUAL("fract(3/4,2)", "MOD(3/2,1)", "test fract #2");
680
+ fi;
681
+
682
+
683
+ smallstep:=proc(a,n); fract(-a,n); end:
684
+
685
+ Todd:=proc(x,order):
686
+ -add(1/j!*bernoulli(j,0)*x^j,j=0..order):
687
+ end:
688
+ if check_examples() then
689
+ TEST_EQUAL("Todd(t,7)", "-1+1/2*t-1/12*t^2+1/720*t^4-1/30240*t^6", "test Todd #1");
690
+ fi;
691
+
692
+
693
+ # Input: U is a cone, Lambda is a lattice,
694
+ # Here: U is given in coordinates with respect to the lattice basis,
695
+ # s is a pvector (with symbolic entries);
696
+ # xi is a dvector (with symbolic entries), order a positive integer.
697
+ # Output: a list of a nonnegative integer and a function of s,xi, with entries formal functions rest().
698
+ # Math: we compute the function e^<(smallstep(-T*s)),xi> prod_{i=1}^r 1/(1-e^(xi,g_j)), taking the Laurent series up to order and an nonnegative integer.
699
+ # Here the g_j are the p-vectors generators of the cone U, it will be unimodular in the application.
700
+ # Later we evaluate it at xi=[(a1+epsilon reg_1)*x,(a2+epsilon reg_2)x]...compute the Laurent series in x up to some length (later to be N+2-h);
701
+ # and we take the coefficient in epsilon=0. In view of this applicatiuon we evaluate the the nonnegative integer which is the order of the pole in the variable epsilon
702
+ # s is written as sum_i x_i g_i and rest(s) is the p vector sum_i (ceil(x_i)-x_i)
703
+ # We also will use the formal functions rest(s)=ceil(s)-s;
704
+ # Example:=Function_M_uni_expanded([T*s1,T*s2],[[1,2],[1,3]],[[1,0],[0,1]],[2,-1],[xi1,xi2],3):=[1, (1+xi1*(Smallstep((-3*s1+s2)*T)+Smallstep((2*s1-s2)*T))+xi2*(2*Smallstep((-3*s1+s2)*T)+3*Smallstep((2*s1-s2)*T))+(1/2)*(xi1*(Smallstep((-3*s1+s2)*T)+Smallstep((2*s1-s2)*T))+xi2*(2*Smallstep((-3*s1+s2)*T)+3*Smallstep((2*s1-s2)*T)))^2+(1/6)*(xi1*(Smallstep((-3*s1+s2)*T)+Smallstep((2*s1-s2)*T))+xi2*(2*Smallstep((-3*s1+s2)*T)+3*Smallstep((2*s1-s2)*T)))^3)*(-1+(1/2)*xi1+xi2-(1/12)*(xi1+2*xi2)^2)*(-1+(1/2)*xi1+(3/2)*xi2-(1/12)*(xi1+3*xi2)^2)/((xi1+2*xi2)*(xi1+3*xi2))];
705
+ Function_M_uni_expanded:=proc(T,s,U,Lambda,Small,xi,order) local r, M1,M2,M,pro,QQ,Rests,i,a,news,b,FM,Eb,pole,coex:
706
+ pro:=1;
707
+ r:=nops(U);
708
+ M1:=Transpose(Matrix([seq(Lambda[i],i=1..nops(Lambda))]));
709
+ M2:=Transpose(Matrix([seq(U[i],i=1..nops(Lambda))]));
710
+ M:=Multiply(M1,M2);
711
+ QQ:=[seq(convert(col(M,k),list),k=1..r)];##print("QQ",QQ);
712
+ news:=convert(Multiply(MatrixInverse(M),Vector(s)),list); #small_step:=[seq(smallmove(-news[j],T),j=1..nops(news))]
713
+ #Rests:=[seq(smallstep(news[j]),j=1..nops(news))];pole:=0;
714
+ Rests:=[seq(smallstep(-news[j],T),j=1..nops(news))];pole:=0;
715
+ for i from 1 to nops(U) do
716
+ coex:=add(Small[j]*QQ[i][j],j=1..nops(QQ[i]));
717
+ if coex=0 then
718
+ pole:=pole+1;
719
+ fi;
720
+ a:=add(xi[j]*QQ[i][j],j=1..nops(QQ[i]));
721
+ pro:=pro*1/a*Todd(a,order): ##print(i,pro);
722
+ od;
723
+ b:=add(xi[i]*(add(Rests[k]*QQ[k][i],k=1..nops(QQ))),i=1..r);
724
+ Eb:=add(b^m/m!,m=0..order); ##print('Eb',Eb);
725
+ [pole,Eb*pro];
726
+ end:
727
+
728
+
729
+
730
+ # Input: AA list of positive integers ; f a positive integer,
731
+ # x a variable; T a symbolic variable, f a nonnegative integer, f<>1;
732
+ # Output; a function of x,T;
733
+ # Math: the coefficient of the function H(AA,f)(T,x) in x^(-h-1), that is wecompute the coefficient of t^h of E(A,f)(t).
734
+ # Example:=part_f_of_knapsack([2,2,3,3],T,3,1):=17/48+(1/6)*Smallstep((1/3)*T)-(1/2)*Smallstep((1/3)*T)^2;
735
+
736
+ part_f_of_knapsack:=proc(AA,T,f,h)
737
+ local N,BB,Small,LAMBDA,fB,i,WW,newW,uni_cones,Tvertex,out,xxi,reg,FF,FM,FMfB,pole,newWmatrix,veryNewWmatrix,tempLambda,t1,j;
738
+ global USE_DUAL;
739
+ global MAX_DET_part_f_of_knapsack;
740
+ N:=nops(AA)-1;
741
+ BB:=B_and_S(AA,f)[1];
742
+ Small:=B_and_S(AA,f)[2];
743
+ reg:=random_vector(500,nops(Small));
744
+ fB:=1:
745
+ for i from 1 to nops(BB) do #print(i,nops (BB),Todd(BB[i]*x,N-h));
746
+ fB:=fB*1/(BB[i]*x)*Todd(BB[i]*x,N-h);
747
+ od; ##print(aqui);
748
+ LAMBDA:=Basis_Lattice(Small,f);
749
+ WW:=ortho_basis(nops(Small));
750
+ #print("WW=", WW);
751
+ newW:=cone_in_basis_Lambda(WW,LAMBDA); #print("thecone",newW);
752
+
753
+ #start of new ideas for the dual cone computation
754
+ newWmatrix:=Matrix(newW); #convert the list to a matrix.
755
+ veryNewWmatrix:=MatrixInverse(newWmatrix); #this matrix will hold the dual cone rays.
756
+
757
+ #find scaling for the new matrix
758
+ for i from 1 to nops(newW) do
759
+ tempLambda:=ilcm(seq(denom(veryNewWmatrix[j, i]),j=1..nops(newW)));
760
+
761
+ for j from 1 to nops(newW) do
762
+ veryNewWmatrix[j,i]:=veryNewWmatrix[j,i]*tempLambda;
763
+ od;# for jth row.
764
+ od; #for ith col
765
+
766
+ #print("org. matrix", Transpose(newWmatrix));
767
+ #print("org. det= ", Determinant(newWmatrix));
768
+ #print("new matrix", veryNewWmatrix);
769
+ #print("new det=", Determinant(veryNewWmatrix));
770
+ #print("f=",f);
771
+ if USE_DUAL = false then
772
+ MAX_DET_part_f_of_knapsack:=max( MAX_DET_part_f_of_knapsack, abs(Determinant(newWmatrix)));
773
+ else
774
+ MAX_DET_part_f_of_knapsack:=max( MAX_DET_part_f_of_knapsack, abs(Determinant(veryNewWmatrix)));
775
+ fi;
776
+
777
+
778
+ #end of new ideas
779
+
780
+ #Tvertex:=[seq(the_vertex(-T*Small,f)[i],i=1..nops(Small))];
781
+ Tvertex:=[seq(the_vertex(Small,f)[i],i=1..nops(Small))];
782
+ ##print(aqui,Tvertex);
783
+
784
+ t1:=time();
785
+
786
+ #here, branch on if we are using the dual cones or not.
787
+ if USE_DUAL = false then
788
+ #print("using primal cones");
789
+ uni_cones:=cone_dec(newW); #
790
+ else
791
+ #print("using dual cones");
792
+ #print("dual cone computation is not correct");
793
+ #todo: we have to dualize back.
794
+ #uni_cones:=cone_dec(convert(Transpose(veryNewWmatrix), listlist));
795
+ uni_cones:=new_dual_dec_cone(newW);
796
+ fi;
797
+
798
+ #print("total time in uni_cones ", time() -t1);
799
+ #print(nopsunicones,nops(uni_cones),uni_cones);
800
+ out:=0;
801
+ xxi:=[seq((Small[z]+epsilon*reg[z])*x,z=1..nops(Small))];
802
+ for i from 1 to nops(uni_cones) do
803
+ #####print(datas,Tvertex,uni_cones[i][3],LAMBDA,xxi);
804
+ if USE_DUAL = false then
805
+ FF:=Function_M_uni_expanded(T,Tvertex,uni_cones[i][3],LAMBDA,Small,xxi,N-h);
806
+ else
807
+ FF:=Function_M_uni_expanded(T,Tvertex,uni_cones[i][2],LAMBDA,Small,xxi,N-h);
808
+ fi;
809
+ FM:=FF[2];
810
+ FMfB:=FM*fB;;
811
+ pole:=FF[1]; ##print(polex,pole);
812
+
813
+ if pole=0 then
814
+ FM:=subs(epsilon=0,FM);
815
+ FMfB:=coeff(FMfB,x,-h-1);
816
+ else
817
+ FMfB:=simplify(coeff(FMfB,x,-h-1));
818
+ fi;
819
+ FMfB:=coeff(convert(series(FMfB,epsilon=0,nops(Small)),polynom),epsilon,0);
820
+ out:=out+uni_cones[i][1]*FMfB;
821
+ od;
822
+ #print("total time in uni_cones+the rest",time()-t1);
823
+
824
+ simplify(-f*out*(-1)^h/h!);
825
+ end:
826
+
827
+ # Input: AA list of positive integers ; h a nonnegative integer
828
+ # x a variable;
829
+ # Output; a function of x,
830
+ # Math: the coefficient of the function H(AA,f)(T,x) in x^(-h-1), when f=1, that is we compute the coefficient of t^h of E(A,1)(t).
831
+ # part_one_of_knapsack([1,4,9,10],3):=1/2160;
832
+ part_one_of_knapsack:=proc(AA,h) local fB,i,N,HH,HHH;
833
+
834
+ fB:=1: N:=nops(AA)-1;
835
+ for i from 1 to nops(AA) do ;
836
+ fB:=fB*1/(AA[i]*x)*Todd(AA[i]*x,N-h);
837
+ od; ##print(aqui);
838
+ HHH:=-coeff(fB,x,-h-1)*(-1)^h/h!;
839
+ end:
840
+
841
+ # The knapsack the straight way: to test some values
842
+ XXX:=proc(n);[seq(seq(seq([i,j,k],i=0..n),j=0..n),k=0..n)];end:
843
+ XXXX:=proc(n);[seq(seq(seq(seq([i,j,k,ell],i=0..n),j=0..n),k=0..n),ell=0..n)];end:
844
+
845
+ XXXXX:=proc(n);[seq(seq(seq(seq(seq([i,j,k,ell,p],i=0..n),j=0..n),k=0..n),ell=0..n),p=0..n)];end:
846
+ valueknapsackXXX:=proc(AAA,t) local test,u,R,s; test:=XXX(t);s:=0;
847
+ for u from 1 to nops(test) do R:=add(AAA[i]*test[u][i],i=1..3);
848
+ if R=t then s:=s+1;fi; od; s;end:
849
+
850
+ valueknapsackXXXX:=proc(AAAA,t) local test,u,R,s; test:=XXXX(t);s:=0;
851
+ for u from 1 to nops(test) do R:=add(AAAA[i]*test[u][i],i=1..4);
852
+ if R=t then s:=s+1;fi; od; s;end:
853
+
854
+ #printlevel:=0;valueknapsackXXX(A123,3);
855
+
856
+ valueknapsackXXXXX:=proc(AAAAA,t) local test,u,R,s; test:=XXXXX(t);s:=0;
857
+ for u from 1 to nops(test) do R:=add(AAAAA[i]*test[u][i],i=1..5);
858
+ if R=t then s:=s+1;fi; od; s;end:
859
+ # Patch Function
860
+ #
861
+ # INPUT: a list of positive integers L and a positive integer i
862
+ # OUTPUT: a list
863
+ # Math: we compute the elements in L that are divided by i. If i is not a member of L then we return the empty list
864
+ # Example:is_divisor([2,4,3,7,12],5):=[]; is_divisor([2,4,3,7,12],4):=[4,12]
865
+ #
866
+ is_divisor:=proc(L,i) local t,LL,newi,j,newL;
867
+ LL:=sort(L);newL:=[];
868
+ if member(i,LL,'t')=true then
869
+ newi:=LL[t];
870
+ for j from t to nops(LL) do
871
+ if modp(LL[j],newi)=0 then newL:=[op(newL),LL[j]];
872
+ else newL:=newL;
873
+ fi:
874
+ od:
875
+ fi;
876
+ newL;
877
+ end:
878
+ if check_examples() then
879
+ TEST_EQUAL("is_divisor([2,4,3,7,-12],5)", "[]", "test is_divisor #1");
880
+ TEST_EQUAL("is_divisor([2,4,3,7,12],4)", "[4, 12]", "test is_divisor #2");
881
+ fi;
882
+
883
+
884
+ # INPUT: a list of positive integers L and a positive integer i
885
+ # OUTPUT: a number
886
+ # Math: we compute the elements in L that divide i. If i is not a member of L then we return the empty list
887
+ # Example:is_divided([2,4,3,7,12],12):=[2, 3, 4, 12];;
888
+ is_divided:=proc(L,i) local t,LL,newL,newi,j;
889
+ LL:=sort(L);newL:=[];
890
+ if member(i,LL,'t')=true then
891
+ newi:=LL[t];
892
+ for j from 1 to t do
893
+ if modp(newi,LL[j])=0 then newL:=[op(newL),LL[j]];
894
+ else newL:=newL;
895
+ fi:
896
+ od:
897
+ fi;
898
+ newL;
899
+ end:
900
+ if check_examples() then
901
+ TEST_EQUAL("is_divided([2,4,3,7,12],12)", "[2, 3, 4, 12]", "test is_divided #1");
902
+ TEST_EQUAL("is_divided([2,4,3,7,-12],17)", "[]", "test is_divided #2");
903
+ fi;
904
+
905
+
906
+ # Input: a list of positive integers L, i and j two elements of L with i<=j
907
+ # Output: an integer
908
+ # Math: we compute mu(i,j) following the patch formula
909
+ # Example: mmu([2,4,3,7,12],3,12);=-1; mmu([2,4,3,7,12],3,7):=0;mmu([2,4,3,7,12],12,12):=1
910
+ mmu:=proc(L,i,j) local out,L1,L2,indexi,newL,indexj;#L is a list of common divisor
911
+ if i=j then out:=1;
912
+ elif modp(j,i)<>0 #that is L[i] doesn't divide L[j]
913
+ then out:=0;
914
+ else
915
+ L1:=is_divisor(L,i);
916
+ newL:=is_divided(L1,j);
917
+ newL:=subsop(1=NULL,newL);
918
+ if member(j,newL,'s')=true then indexj:=s;fi;
919
+ out:=-add(mmu(newL,newL[k],newL[indexj]),k=1..nops(newL));
920
+ fi;
921
+ out;
922
+ end:
923
+ if check_examples() then
924
+ TEST_EQUAL("mmu([2,4,3,7,12],2,12)", "0", "test mmu #1");
925
+ TEST_EQUAL("mmu([2,4,3,7,12],12,12)", "1", "test mmu #2");
926
+ TEST_EQUAL("mmu([2,4,3,7,12],4,7)", "0", "test mmu #3");
927
+ fi;
928
+
929
+
930
+
931
+ # Input: a list of positive integers L, i an element of L
932
+ # Output: an integer
933
+ # Math: we compute rho(i) following the patch formula
934
+ # Example: rho_i([2,3,4,6,8,7],2):= -1;
935
+ rho_i:=proc(L,i) local L1,k,rho;
936
+ L1:=is_divisor(L,i):
937
+ rho:=add(mmu(L,i,L1[k]),k=1..nops(L1));###print(seq(mmu1(L,i,k),k=1..nops(L1));
938
+ rho;
939
+ end:
940
+ if check_examples() then
941
+ TEST_EQUAL("rho_i([2,4,3,7,12],2)", "0", "test rho_i #1");
942
+ TEST_EQUAL("rho_i([2,4,3,7,12],12)", "1", "test rho_i #2");
943
+ TEST_EQUAL("rho_i([2,4,3,7,12],2)", "0", "test rho_i #3");
944
+ fi;
945
+
946
+
947
+ # Input: a list of positive integers L
948
+ # Output: a linear combination of G(i), i in L
949
+ # Math: we compute ϱ following the patch formula.
950
+ # Example :rho_knap([1,2,3]):=-G(1)+G(2)+G(3);
951
+ rho_knap:=proc(L) local out2,co,i,L1,rho_i,x ;
952
+ out2:=0;co:=0;
953
+ for i from 1 to nops(L) do
954
+ L1:=is_divisor(L,L[i]):
955
+ rho_i:=add(mmu(L,L[i],L1[k]),k=1..nops(L1));
956
+ out2:=out2+rho_i*G(L[i]);co:=co+rho_i;
957
+ od;
958
+ x:=co-1;
959
+ out2:=out2-x*G(1);
960
+ end:
961
+ if check_examples() then
962
+ TEST_EQUAL("rho_knap([2,4,3,7,12])", "G(7)+G(12)-G(1)", "test rho_knap #1");
963
+ TEST_EQUAL("rho_knap([345,234,6245,3457,4526,3126,2457,235,1,1,2,3,45,456,12,43,67,2,46,2])", "G(345)+G(234)+G(6245)+G(3457)+G(4526)+G(3126)+G(2457)+G(235)-G(1)-6*G(2)-5*G(3)+G(45)+G(456)+G(43)+G(67)+G(46)", "test rho_knap #2");
964
+ fi;
965
+
966
+ #####################################
967
+ #Next 3 are main interface functions#
968
+ #####################################
969
+
970
+ # The Complete knapsack and one coeff.
971
+ # Input: t a variable, A a list of nonnegative integers
972
+ # Math: We compute the knapsack for A and t: that is the whole Ehrhart polynomial
973
+ # Example:=complete_knapsack([1,2,3],17)=403/12+Smallstep(-17/2)^2-Smallstep(-17/2)+(3/2)*Smallstep(-17/3)^2-(3/2)*Smallstep(-17/3);
974
+ complete_knapsack:=proc(A,t,T) local h,out,F,p,i,f,c,N;
975
+ out:=0;
976
+ N:=nops(A)-1;
977
+ F:=F_k(A,N):##print("F",F);
978
+ p:=rho_knap(F): #print(p);
979
+ for i from 1 to nops(F) do
980
+ f:=F[i];
981
+ c:=coeff(p,G(f));
982
+ if f=1 then
983
+ out:=out+c*add(part_one_of_knapsack(A,h)*T^h,h=0..N);
984
+ else
985
+ out:=out+c*add(part_f_of_knapsack(A,t,f,h)*T^h,h=0..N);fi ;
986
+ od;
987
+ #eval(subs(T=t,simplify(out)));
988
+ eval(simplify(out));
989
+ end:
990
+ if check_examples() then
991
+ TEST_EQUAL("complete_knapsack([2,4,3],t,T)", "1-3/2*MOD(1/3*t,1)+3/2*MOD(1/3*t,1)^2-3/2*MOD(1/2*t,1)+1/32*(4*MOD(3/4*t,1)+4*MOD(1/2*t,1))^2-3/2*MOD(3/4*t,1)^2+(1/4-1/4*MOD(1/2*t,1))*T+1/48*T^2", "test complete_knapsack #1");
992
+ TEST_EQUAL("complete_knapsack([1,6,6,6,6],t,T)", "1-25/12*MOD(1/6*t,1)+35/24*MOD(1/6*t,1)^2-5/12*MOD(1/6*t,1)^3+1/24*MOD(1/6*t,1)^4+(25/72-35/72*MOD(1/6*t,1)+5/24*MOD(1/6*t,1)^2-1/36*MOD(1/6*t,1)^3)*T+(35/864-5/144*MOD(1/6*t,1)+1/144*MOD(1/6*t,1)^2)*T^2+(5/2592-1/1296*MOD(1/6*t,1))*T^3+1/31104*T^4", "test complete_knapsack #2");
993
+ fi;
994
+
995
+
996
+ #Compute the Ehrhart coefficient of t^(N-k)
997
+ coeff_Nminusk_knapsack:=proc(A,t,T, k) local out,N,F,i,c,p,f,noError,Tseries;
998
+ out:=0;
999
+ N:=nops(A)-1;
1000
+ F:=F_k(A,k):##print(rootsk,F);
1001
+ #print("F=", F);
1002
+ p:=rho_knap(F):
1003
+ #print("p=", p);
1004
+ for i from 1 to nops(F) do
1005
+ f:=F[i];
1006
+ c:=coeff(p,G(f));
1007
+ #print("i=",i,"c=", c);
1008
+ if c = 0 then
1009
+ next;
1010
+ fi;
1011
+
1012
+ noError := 0;
1013
+ Tseries:=0;
1014
+ while noError = 0 do
1015
+ try
1016
+ if f=1 then
1017
+ Tseries:=part_one_of_knapsack(A,N-k)*T^(N-k);
1018
+ else
1019
+ Tseries:=part_f_of_knapsack(A,t,f,N-k)*T^(N-k);
1020
+ fi;
1021
+ noError := 1;
1022
+ catch:
1023
+ fprintf("Error. trying again\n");
1024
+ end;
1025
+ od;
1026
+
1027
+ out:=out+c*Tseries;
1028
+
1029
+ od;
1030
+ #eval(subs(T=t,simplify(out)));
1031
+ eval(simplify(out));
1032
+ end:
1033
+ if check_examples() then
1034
+ TEST_EQUAL("coeff_Nminusk_knapsack([2,4,3],t,T,0)", "1/48*T^2", "test coeff_Nminusk_knapsack #1");
1035
+ TEST_EQUAL("coeff_Nminusk_knapsack([2,4,3],t,T,1)", "-1/4*(-1+MOD(1/2*t,1))*T", "test coeff_Nminusk_knapsack #2");
1036
+ TEST_EQUAL("coeff_Nminusk_knapsack([2,4,3],t,T,2)", "1-3/2*MOD(1/3*t,1)+3/2*MOD(1/3*t,1)^2-3/2*MOD(1/2*t,1)+1/32*(4*MOD(3/4*t,1)+4*MOD(1/2*t,1))^2-3/2*MOD(3/4*t,1)^2", "test coeff_Nminusk_knapsack #3");
1037
+ TEST_EQUAL("coeff_Nminusk_knapsack([1,6,6,6,6],t,T,0)", "1/31104*T^4", "test coeff_Nminusk_knapsack #4");
1038
+ TEST_EQUAL("coeff_Nminusk_knapsack([1,6,6,6,6],t,T,1)", "-1/2592*(-5+2*MOD(1/6*t,1))*T^3", "test coeff_Nminusk_knapsack #5");
1039
+ TEST_EQUAL("coeff_Nminusk_knapsack([1,6,6,6,6],t,T,2)", "1/864*(35-30*MOD(1/6*t,1)+6*MOD(1/6*t,1)^2)*T^2", "test coeff_Nminusk_knapsack #6");
1040
+ TEST_EQUAL("coeff_Nminusk_knapsack([1,6,6,6,6],t,T,3)", " -1/72*(2*MOD(1/6*t,1)^3-15*MOD(1/6*t,1)^2+35*MOD(1/6*t,1)-25)*T", "test coeff_Nminusk_knapsack #7");
1041
+ TEST_EQUAL("coeff_Nminusk_knapsack([1,6,6,6,6],t,T,4)", "1-25/12*MOD(1/6*t,1)+35/24*MOD(1/6*t,1)^2-5/12*MOD(1/6*t,1)^3+1/24*MOD(1/6*t,1)^4", "test coeff_Nminusk_knapsack #8");
1042
+ fi;
1043
+
1044
+
1045
+ #Computes the top k+1 terms: T^N, T^{N-1}, ..., T_{N-k}
1046
+ knapsackKTerms:=proc(A, t, T, k)
1047
+ local ans, i;
1048
+ ans:=0;
1049
+ for i from 0 to k do
1050
+ ans:=ans + coeff_Nminusk_knapsack(A, t, T, i);
1051
+ end;
1052
+
1053
+ return ans;
1054
+ end:
1055
+ if check_examples() then
1056
+ TEST_EQUAL("knapsackKTerms([2,4,3],t,T,1)", "1/48*T^2-1/4*(-1+MOD(1/2*t,1))*T", "test knapsackKTerms #1");
1057
+ TEST_EQUAL("knapsackKTerms([2,4,3],t,T,2)", "1/48*T^2-1/4*(-1+MOD(1/2*t,1))*T+1-3/2*MOD(1/3*t,1)+3/2*MOD(1/3*t,1)^2-3/2*MOD(1/2*t,1)+1/32*(4*MOD(3/4*t,1)+4*MOD(1/2*t,1))^2-3/2*MOD(3/4*t,1)^2", "test knapsackKTerms #2");
1058
+ fi;
1059
+
1060
+
1061
+
1062
+ SMALLSTEP:=proc(T);
1063
+ ceil(T)-T;
1064
+ end:
1065
+ if check_examples() then
1066
+ TEST_EQUAL("SMALLSTEP(2/3)", "1/3", "test SMALLSTEP #1");
1067
+ TEST_EQUAL("SMALLSTEP(3+2/3)", "1/3", "test SMALLSTEP #2");
1068
+ TEST_EQUAL("SMALLSTEP(-3-1/3)", "1/3", "test SMALLSTEP #3");
1069
+ TEST_EQUAL("SMALLSTEP(-4/5)", "4/5", "test SMALLSTEP #4");
1070
+ TEST_EQUAL("SMALLSTEP(5/4)", "3/4", "test SMALLSTEP #5");
1071
+ TEST_EQUAL("SMALLSTEP(5)", "0", "test SMALLSTEP #6");
1072
+ fi;
1073
+
1074
+
1075
+ numeric_knapsack:=proc(A,value);
1076
+ eval(subs(T=value,t=value,subs(Smallstep=SMALLSTEP,complete_knapsack(A,t,T))));
1077
+ end:
1078
+ if check_examples() then
1079
+ TEST_EQUAL("numeric_knapsack([1,1,1],30)", "496", "test numeric_knapsack #1");
1080
+ fi;
1081
+
1082
+ # SOME EXPERIMENTS;
1083
+ ASou:=proc(dimension) local n; n:=dimension;
1084
+ [1,seq(n!/i,i=1..n)];
1085
+ end:
1086
+
1087
+ random_list:=proc(bound,dimension) local R;
1088
+ R:=rand(bound);
1089
+ [1,seq(R()+1,i=1..dimension)]:
1090
+ end:
1091
+
1092
+ testTopknapsackASou:=proc(dimension,k) local start1,finish; start1:=time();
1093
+ print(coeff_Nminusk_knapsack(ASou(dimension),t,k));finish:=time()-start1;
1094
+ end:
1095
+
1096
+ testTopknapsackrandom:=proc(dimension,k) local start1,AA,n;
1097
+ n:=dimension;
1098
+ AA:=random_list(100,n); print(AA);
1099
+ start1:=time();print(coeff_Nminusk_knapsack(AA,t,k));time()-start1;
1100
+ end:
1101
+
1102
+ smallstep3 := proc (s) eval(ceil(s)-s) end proc:
1103
+
1104
+
1105
+ #This function computes the top k+1 coefficients
1106
+ #and returns the numerical answer. So this
1107
+ #function is best called with a numeric t
1108
+ #(but a symbolic t would work too)
1109
+
1110
+ topk_numeric_polynomial:=proc(A,t,k) local poly, i, onlyOneTerm;
1111
+ poly:=0;
1112
+ for i from 0 to k do
1113
+ onlyOneTerm:=coeff_Nminusk_knapsack(A, t, i);
1114
+ poly:=poly + onlyOneTerm;
1115
+ print("sum of first ", i, "=", evalf(eval(subs(Smallstep=smallstep3, poly))));
1116
+ print("only the term ",i,evalf(eval(subs(Smallstep=smallstep3,onlyOneTerm))));
1117
+
1118
+ end;
1119
+ return evalf(subs(Smallstep=smallstep3, poly));
1120
+ end:
1121
+
1122
+
1123
+ #
1124
+
1125
+ #makes a list [1, 2, 3, ..., k]
1126
+ makePartitionEquation:=proc(k)
1127
+ local i, L;
1128
+ L:=[];
1129
+ for i from 1 to k do
1130
+ L:=[op(L), i];
1131
+ end; #for i
1132
+ return L;
1133
+ end:
1134
+
1135
+
1136
+ #print the function myceil(x) in latex ceil
1137
+ `latex/myceil`:=proc(x)
1138
+ return cat("\\ceil{",convert(x, string),"}");
1139
+ end:
1140
+
1141
+ #print the function Smallstep as {{-x}} in latex
1142
+ `latex/Smallstep`:=proc(x)
1143
+ local y;
1144
+ y:=-1*x;
1145
+ return cat("\\{", convert(y,string),"\\}");
1146
+ end:
1147
+
1148
+
1149
+
1150
+
1151
+
1152
+ #make a table of the e.coefficients for the
1153
+ #partition knapsacks.
1154
+
1155
+ runPartitionTable:=proc()
1156
+ local fptr, m, k, c;
1157
+ local fileName;
1158
+
1159
+ for m from 5 to 5 do
1160
+ fileName:="ToughTable"||".m"||m||".tex";
1161
+
1162
+ for k from ceil(m/2) to ceil(m/2) do
1163
+ printf("Starting partition %d, coefficient k=%d\n",m, k);
1164
+ # writeto("/dev/null");
1165
+ #don't print anything from coeff_Nminusk_knapsack
1166
+ c:=coeff_Nminusk_knapsack(makePartitionEquation(m),t,k);
1167
+ #c:=eval(subs(Smallstep=smallstep3, c));
1168
+ #c:=simplify(eval(subs(ceil=myceil,c)));
1169
+ print("c=",c);
1170
+ interface(screenwidth=9999);
1171
+ #print("latex");
1172
+ appendto(fileName);
1173
+ printf("& $");
1174
+ latex(c); printf("$");
1175
+ interface(screenwidth=79);
1176
+ writeto(terminal);
1177
+ od; #for k
1178
+ od; #for m
1179
+ end: writeto(terminal):
1180
+
1181
+
1182
+
1183
+ #will find the Ehrhart polynomial for some knapsacks and print the resutls to a file.
1184
+
1185
+ printPartitionPolynomial:=proc()
1186
+ local fptr, m, k, c;
1187
+ local fileName;
1188
+ fileName:="partitionTable3.mpl";
1189
+ fptr:=fopen(fileName, WRITE, TEXT);
1190
+ for m from 2 to 5 do
1191
+ fprintf(fptr, "polynomial%d:= \\;", m);
1192
+ for k from 0 to (m-1) do
1193
+ #for k from 0 to (5-1) do
1194
+ printf("Starting partition %d, coefficient k=%d\n",m, k);
1195
+ writeto("/dev/null");
1196
+ c:=coeff_Nminusk_knapsack(makePartitionEquation(m),t,k);
1197
+ #c:=coeff_Nminusk_knapsack([1, 20, 7, 70, 400],t,k);
1198
+ writeto(terminal);
1199
+ fprintf(fptr, "\n+ %a \\", c);
1200
+ od; #for k
1201
+ fprintf(fptr, ";\n\n");
1202
+ od; #for m
1203
+ fclose(fptr);
1204
+ end:
1205
+
1206
+ writeto(terminal);
1207
+
1208
+ fractionalpart:=proc(s) local our,T;
1209
+ if type(s,rational) then our:=s-floor(s);
1210
+ else our:={-s};
1211
+ fi;
1212
+ RETURN(our);
1213
+ end:
1214
+ if check_examples() then
1215
+ TEST_EQUAL("fractionalpart(2/3)", "2/3", "test fractionalpart #1");
1216
+ TEST_EQUAL("fractionalpart(3+2/3)", "2/3", "test fractionalpart #2");
1217
+ TEST_EQUAL("fractionalpart(-3-1/3)", "2/3", "test fractionalpart #3");
1218
+ TEST_EQUAL("fractionalpart(-4/5)", "1/5", "test fractionalpart #4");
1219
+ TEST_EQUAL("fractionalpart(5/4)", "1/4", "test fractionalpart #5");
1220
+ TEST_EQUAL("fractionalpart(5)", "0", "test fractionalpart #6");
1221
+ fi;
1222
+
1223
+ #### LATTE INTERFACE FUNCTION:
1224
+ #
1225
+ # Function to be substituted for the formal MOD function to get
1226
+ # results.
1227
+ # (can as well just use value().)
1228
+ #
1229
+ # input:
1230
+ # a: any rational number or symbolic expression.
1231
+ # n: any rational number.
1232
+ # return the number in the half-open interval [0,n) that is equal to a mod n
1233
+ latteMod:=proc(x, n)
1234
+ ASSERT(n > 0);
1235
+ ### Note `floor' works fine for symbolics, if `Digits'
1236
+ ### is large enough. --mkoeppe
1237
+ x - floor(x/n)*n;
1238
+ end:
1239
+ if check_examples() then
1240
+ TEST_EQUAL("latteMod(5+1/3, 2)", "4/3", "test latteMod #1");
1241
+ TEST_EQUAL("latteMod(-1/3, 1)", "2/3", "test latteMod #2");
1242
+ TEST_EQUAL("latteMod(sqrt(2), 1)", "sqrt(2) - 1", "test latteMod #3"); # Note the difference to what we output in fractionalpart!
1243
+
1244
+ fi;
1245
+