passagemath-giac 10.5.33__cp311-cp311-musllinux_1_2_aarch64.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.
- passagemath_giac-10.5.33.dist-info/METADATA +153 -0
- passagemath_giac-10.5.33.dist-info/RECORD +34 -0
- passagemath_giac-10.5.33.dist-info/WHEEL +5 -0
- passagemath_giac-10.5.33.dist-info/top_level.txt +2 -0
- passagemath_giac.libs/libcrypto-79ca7c2e.so.3 +0 -0
- passagemath_giac.libs/libcurl-16a78e59.so.4.8.0 +0 -0
- passagemath_giac.libs/libgcc_s-69c45f16.so.1 +0 -0
- passagemath_giac.libs/libgfortran-db0b6589.so.5.0.0 +0 -0
- passagemath_giac.libs/libgiac-6d0de4c7.so.0.0.0 +0 -0
- passagemath_giac.libs/libglpk-aec1f3c8.so.40.3.1 +0 -0
- passagemath_giac.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
- passagemath_giac.libs/libgsl-75bb3fcc.so.28.0.0 +0 -0
- passagemath_giac.libs/libgslcblas-e0debfeb.so.0.0.0 +0 -0
- passagemath_giac.libs/libintl-3f4788bb.so.8.4.0 +0 -0
- passagemath_giac.libs/libmpfi-8dd9bae1.so.0.0.0 +0 -0
- passagemath_giac.libs/libmpfr-5ff10580.so.6.2.1 +0 -0
- passagemath_giac.libs/libncursesw-13f4e49c.so.6.5 +0 -0
- passagemath_giac.libs/libopenblas_neoversen2p-r0-05b86cab.3.28.so +0 -0
- passagemath_giac.libs/libpari-gmp-tls-e657f88e.so.2.15.5 +0 -0
- passagemath_giac.libs/libreadline-ae76ac25.so.8.2 +0 -0
- passagemath_giac.libs/libssl-7d993165.so.3 +0 -0
- passagemath_giac.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
- sage/all__sagemath_giac.py +10 -0
- sage/interfaces/all__sagemath_giac.py +1 -0
- sage/interfaces/giac.py +1264 -0
- sage/libs/all__sagemath_giac.py +7 -0
- sage/libs/giac/__init__.py +356 -0
- sage/libs/giac/auto-methods.pxi +16982 -0
- sage/libs/giac/giac.cpython-311-aarch64-linux-musl.so +0 -0
- sage/libs/giac/giac.pxd +205 -0
- sage/libs/giac/giac.pyx +2074 -0
- sage/libs/giac/keywords.pxi +10 -0
- sage/libs/giac/misc.h +117 -0
- sage_wheels/bin/giac +0 -0
@@ -0,0 +1,356 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-giac
|
2
|
+
# sage.doctest: needs sage.libs.giac
|
3
|
+
"""
|
4
|
+
Wrappers for Giac functions
|
5
|
+
|
6
|
+
We provide a python function to compute and convert to sage a Groebner
|
7
|
+
basis using the ``giacpy_sage`` module.
|
8
|
+
|
9
|
+
AUTHORS:
|
10
|
+
|
11
|
+
- Martin Albrecht (2015-07-01): initial version
|
12
|
+
- Han Frederic (2015-07-01): initial version
|
13
|
+
|
14
|
+
EXAMPLES::
|
15
|
+
|
16
|
+
sage: # needs sage.libs.singular
|
17
|
+
sage: from sage.libs.giac import groebner_basis as gb_giac # random
|
18
|
+
sage: P = PolynomialRing(QQ, 6, 'x')
|
19
|
+
sage: I = sage.rings.ideal.Cyclic(P)
|
20
|
+
sage: B = gb_giac(I.gens()) # random
|
21
|
+
sage: B
|
22
|
+
Polynomial Sequence with 45 Polynomials in 6 Variables
|
23
|
+
"""
|
24
|
+
|
25
|
+
# *****************************************************************************
|
26
|
+
# Copyright (C) 2013 Frederic Han <frederic.han@imj-prg.fr>
|
27
|
+
#
|
28
|
+
# This program is free software: you can redistribute it and/or modify
|
29
|
+
# it under the terms of the GNU General Public License as published by
|
30
|
+
# the Free Software Foundation, either version 2 of the License, or
|
31
|
+
# (at your option) any later version.
|
32
|
+
# https://www.gnu.org/licenses/
|
33
|
+
# *****************************************************************************
|
34
|
+
|
35
|
+
from sage.structure.proof.all import polynomial as proof_polynomial
|
36
|
+
from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
|
37
|
+
from .giac import giacsettings, libgiac
|
38
|
+
|
39
|
+
# Remarks for doctests:
|
40
|
+
# 1) The first time that the c++ library giac is loaded a message appears.
|
41
|
+
# This message is version and arch dependent.
|
42
|
+
# 2) When proba_epsilon is too bad (>1e-6?) setting it to a better value
|
43
|
+
# will give an additional message like the following one:
|
44
|
+
# Restoring proba epsilon to 1e-6 from 1e-12
|
45
|
+
# (it looks like in internal giac changes this also to not work with a too bad probability)
|
46
|
+
|
47
|
+
|
48
|
+
class GiacSettingsDefaultContext:
|
49
|
+
"""
|
50
|
+
Context preserve libgiac settings.
|
51
|
+
"""
|
52
|
+
|
53
|
+
def __enter__(self):
|
54
|
+
"""
|
55
|
+
EXAMPLES::
|
56
|
+
|
57
|
+
sage: from sage.libs.giac import GiacSettingsDefaultContext
|
58
|
+
sage: from sage.libs.giac.giac import giacsettings
|
59
|
+
sage: giacsettings.proba_epsilon = 1e-16
|
60
|
+
sage: with GiacSettingsDefaultContext(): giacsettings.proba_epsilon = 1e-12
|
61
|
+
sage: giacsettings.proba_epsilon < 1e-14
|
62
|
+
True
|
63
|
+
"""
|
64
|
+
self.proba_epsilon = giacsettings.proba_epsilon
|
65
|
+
self.threads = giacsettings.threads
|
66
|
+
# Change the debug level at the end to not have messages at each modification
|
67
|
+
self.debuginfolevel = libgiac('debug_infolevel()')
|
68
|
+
|
69
|
+
def __exit__(self, typ, value, tb):
|
70
|
+
"""
|
71
|
+
EXAMPLES::
|
72
|
+
|
73
|
+
sage: from sage.libs.giac import GiacSettingsDefaultContext
|
74
|
+
sage: from sage.libs.giac.giac import giacsettings
|
75
|
+
sage: giacsettings.proba_epsilon = 1e-16
|
76
|
+
sage: with GiacSettingsDefaultContext(): giacsettings.proba_epsilon = 1e-30
|
77
|
+
sage: giacsettings.proba_epsilon < 1e-20
|
78
|
+
False
|
79
|
+
"""
|
80
|
+
# Restore the debug level first to not have messages at each modification
|
81
|
+
libgiac('debug_infolevel')(self.debuginfolevel)
|
82
|
+
# NB: giacsettings.epsilon has a different meaning that giacsettings.proba_epsilon.
|
83
|
+
giacsettings.proba_epsilon = self.proba_epsilon
|
84
|
+
giacsettings.threads = self.threads
|
85
|
+
|
86
|
+
|
87
|
+
def local_giacsettings(func):
|
88
|
+
"""
|
89
|
+
Decorator to preserve Giac's proba_epsilon and threads settings.
|
90
|
+
|
91
|
+
EXAMPLES::
|
92
|
+
|
93
|
+
sage: def testf(a, b):
|
94
|
+
....: giacsettings.proba_epsilon = a/100
|
95
|
+
....: giacsettings.threads = b+2
|
96
|
+
....: return (giacsettings.proba_epsilon, giacsettings.threads)
|
97
|
+
|
98
|
+
sage: from sage.libs.giac.giac import giacsettings
|
99
|
+
sage: from sage.libs.giac import local_giacsettings
|
100
|
+
sage: gporig, gtorig = (giacsettings.proba_epsilon,giacsettings.threads)
|
101
|
+
sage: gp, gt = local_giacsettings(testf)(giacsettings.proba_epsilon,giacsettings.threads)
|
102
|
+
sage: gporig == giacsettings.proba_epsilon
|
103
|
+
True
|
104
|
+
sage: gtorig == giacsettings.threads
|
105
|
+
True
|
106
|
+
sage: gp<gporig, gt-gtorig
|
107
|
+
(True, 2)
|
108
|
+
"""
|
109
|
+
from sage.misc.decorators import sage_wraps
|
110
|
+
|
111
|
+
@sage_wraps(func)
|
112
|
+
def wrapper(*args, **kwds):
|
113
|
+
"""
|
114
|
+
Execute function in ``GiacSettingsDefaultContext``.
|
115
|
+
"""
|
116
|
+
with GiacSettingsDefaultContext():
|
117
|
+
return func(*args, **kwds)
|
118
|
+
|
119
|
+
return wrapper
|
120
|
+
|
121
|
+
|
122
|
+
@local_giacsettings
|
123
|
+
def groebner_basis(gens, proba_epsilon=None, threads=None, prot=False,
|
124
|
+
elim_variables=None, *args, **kwds):
|
125
|
+
r"""
|
126
|
+
Compute a Groebner Basis of an ideal using ``giacpy_sage``. The result is
|
127
|
+
automatically converted to sage.
|
128
|
+
|
129
|
+
Supported term orders of the underlying polynomial ring are ``lex``,
|
130
|
+
``deglex``, ``degrevlex`` and block orders with 2 ``degrevlex`` blocks.
|
131
|
+
|
132
|
+
INPUT:
|
133
|
+
|
134
|
+
- ``gens`` -- an ideal (or a list) of polynomials over a prime field
|
135
|
+
of characteristic 0 or `p<2^31`
|
136
|
+
|
137
|
+
- ``proba_epsilon`` -- (default: ``None``) majoration of the probability
|
138
|
+
of a wrong answer when probabilistic algorithms are allowed
|
139
|
+
|
140
|
+
* if ``proba_epsilon`` is None, the value of
|
141
|
+
``sage.structure.proof.all.polynomial()`` is taken. If it is
|
142
|
+
false then the global ``giacpy_sage.giacsettings.proba_epsilon`` is
|
143
|
+
used.
|
144
|
+
|
145
|
+
* if ``proba_epsilon`` is 0, probabilistic algorithms are
|
146
|
+
disabled.
|
147
|
+
|
148
|
+
- ``threads`` -- (default: ``None``) maximal number of threads allowed
|
149
|
+
for giac. If ``None``, the global ``giacpy_sage.giacsettings.threads`` is
|
150
|
+
considered.
|
151
|
+
|
152
|
+
- ``prot`` -- boolean (default: ``False``); if ``True`` print detailed information
|
153
|
+
|
154
|
+
- ``elim_variables`` -- (default: ``None``) a list of variables to eliminate
|
155
|
+
from the ideal
|
156
|
+
|
157
|
+
* if ``elim_variables`` is None, a Groebner basis with respect to the
|
158
|
+
term ordering of the parent polynomial ring of the polynomials
|
159
|
+
``gens`` is computed.
|
160
|
+
|
161
|
+
* if ``elim_variables`` is a list of variables, a Groebner basis of the
|
162
|
+
elimination ideal with respect to a ``degrevlex`` term order is
|
163
|
+
computed, regardless of the term order of the polynomial ring.
|
164
|
+
|
165
|
+
OUTPUT: polynomial sequence of the reduced Groebner basis
|
166
|
+
|
167
|
+
EXAMPLES::
|
168
|
+
|
169
|
+
sage: from sage.libs.giac import groebner_basis as gb_giac
|
170
|
+
|
171
|
+
sage: # needs sage.libs.singular sage.rings.finite_rings
|
172
|
+
sage: P = PolynomialRing(GF(previous_prime(2**31)), 6, 'x')
|
173
|
+
sage: I = sage.rings.ideal.Cyclic(P)
|
174
|
+
sage: B = gb_giac(I.gens())
|
175
|
+
...
|
176
|
+
sage: B
|
177
|
+
Polynomial Sequence with 45 Polynomials in 6 Variables
|
178
|
+
sage: B.is_groebner()
|
179
|
+
True
|
180
|
+
|
181
|
+
Elimination ideals can be computed by passing ``elim_variables``::
|
182
|
+
|
183
|
+
sage: # needs sage.libs.singular sage.rings.finite_rings
|
184
|
+
sage: P = PolynomialRing(GF(previous_prime(2**31)), 5, 'x')
|
185
|
+
sage: I = sage.rings.ideal.Cyclic(P)
|
186
|
+
sage: B = gb_giac(I.gens(), elim_variables=[P.gen(0), P.gen(2)])
|
187
|
+
...
|
188
|
+
sage: B.is_groebner()
|
189
|
+
True
|
190
|
+
sage: B.ideal() == I.elimination_ideal([P.gen(0), P.gen(2)])
|
191
|
+
True
|
192
|
+
|
193
|
+
Computations over QQ can benefit from
|
194
|
+
|
195
|
+
* a probabilistic lifting::
|
196
|
+
|
197
|
+
sage: P = PolynomialRing(QQ,5, 'x')
|
198
|
+
sage: I = ideal([P.random_element(3,7) for j in range(5)])
|
199
|
+
sage: B1 = gb_giac(I.gens(),1e-16) # long time (1s)
|
200
|
+
...
|
201
|
+
sage: sage.structure.proof.all.polynomial(True)
|
202
|
+
sage: B2 = gb_giac(I.gens()) # long time (4s)
|
203
|
+
...
|
204
|
+
sage: B1 == B2 # long time
|
205
|
+
True
|
206
|
+
sage: B1.is_groebner() # not tested, too long time (50s)
|
207
|
+
True
|
208
|
+
|
209
|
+
* multi threaded operations::
|
210
|
+
|
211
|
+
sage: # needs sage.libs.singular
|
212
|
+
sage: P = PolynomialRing(QQ, 8, 'x')
|
213
|
+
sage: I = sage.rings.ideal.Cyclic(P)
|
214
|
+
sage: time B = gb_giac(I.gens(),1e-6,threads=2) # doctest: +SKIP
|
215
|
+
...
|
216
|
+
Time: CPU 168.98 s, Wall: 94.13 s
|
217
|
+
|
218
|
+
You can get detailed information by setting ``prot=True``
|
219
|
+
|
220
|
+
::
|
221
|
+
|
222
|
+
sage: # needs sage.libs.singular
|
223
|
+
sage: I = sage.rings.ideal.Katsura(P)
|
224
|
+
sage: gb_giac(I,prot=True) # random, long time (3s)
|
225
|
+
9381383 begin computing basis modulo 535718473
|
226
|
+
9381501 begin new iteration zmod, number of pairs: 8, base size: 8
|
227
|
+
...end, basis size 74 prime number 1
|
228
|
+
G=Vector [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,...
|
229
|
+
...creating reconstruction #0
|
230
|
+
...
|
231
|
+
++++++++basis size 74
|
232
|
+
checking pairs for i=0, j=
|
233
|
+
checking pairs for i=1, j=2,6,12,17,19,24,29,34,39,42,43,48,56,61,64,69,
|
234
|
+
...
|
235
|
+
checking pairs for i=72, j=73,
|
236
|
+
checking pairs for i=73, j=
|
237
|
+
Number of critical pairs to check 373
|
238
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++...
|
239
|
+
Successful... check of 373 critical pairs
|
240
|
+
12380865 end final check
|
241
|
+
Polynomial Sequence with 74 Polynomials in 8 Variables
|
242
|
+
|
243
|
+
|
244
|
+
TESTS::
|
245
|
+
|
246
|
+
sage: from sage.libs.giac.giac import libgiac
|
247
|
+
sage: libgiac("x2:=22; x4:='whywouldyoudothis'")
|
248
|
+
22,whywouldyoudothis
|
249
|
+
sage: gb_giac(I)
|
250
|
+
Traceback (most recent call last):
|
251
|
+
...
|
252
|
+
ValueError: Variables names ['x2', 'x4'] conflict in giac. Change them or purge them from in giac with libgiac.purge('x2')
|
253
|
+
sage: libgiac.purge('x2'),libgiac.purge('x4')
|
254
|
+
(22, whywouldyoudothis)
|
255
|
+
sage: gb_giac(I) # long time (3s)
|
256
|
+
...Polynomial Sequence with 74 Polynomials in 8 Variables
|
257
|
+
|
258
|
+
sage: I = ideal(P(0),P(0))
|
259
|
+
sage: I.groebner_basis() == gb_giac(I) # needs sage.libs.singular
|
260
|
+
True
|
261
|
+
|
262
|
+
Test the supported term orderings::
|
263
|
+
|
264
|
+
sage: # needs sage.libs.singular
|
265
|
+
sage: from sage.rings.ideal import Cyclic
|
266
|
+
sage: P = PolynomialRing(QQ, 'x', 4, order='lex')
|
267
|
+
sage: B = gb_giac(Cyclic(P))
|
268
|
+
...
|
269
|
+
sage: B.is_groebner(), B.ideal() == Cyclic(P)
|
270
|
+
(True, True)
|
271
|
+
sage: P = P.change_ring(order='deglex')
|
272
|
+
sage: B = gb_giac(Cyclic(P))
|
273
|
+
...
|
274
|
+
sage: B.is_groebner(), B.ideal() == Cyclic(P)
|
275
|
+
(True, True)
|
276
|
+
sage: P = P.change_ring(order='degrevlex(2),degrevlex(2)')
|
277
|
+
sage: B = gb_giac(Cyclic(P))
|
278
|
+
...
|
279
|
+
sage: B.is_groebner(), B.ideal() == Cyclic(P)
|
280
|
+
(True, True)
|
281
|
+
"""
|
282
|
+
try:
|
283
|
+
iter(gens)
|
284
|
+
except TypeError:
|
285
|
+
gens = gens.gens()
|
286
|
+
|
287
|
+
# get the ring from gens
|
288
|
+
P = next(iter(gens)).parent()
|
289
|
+
K = P.base_ring()
|
290
|
+
p = K.characteristic()
|
291
|
+
|
292
|
+
# check if the ideal is zero. (giac 1.2.0.19 segfault)
|
293
|
+
from sage.rings.ideal import Ideal
|
294
|
+
if (Ideal(gens)).is_zero():
|
295
|
+
return PolynomialSequence([P(0)], P, immutable=True)
|
296
|
+
|
297
|
+
# check for name confusions
|
298
|
+
blackgiacconstants = ['i', 'e'] # NB e^k is expanded to exp(k)
|
299
|
+
blacklist = blackgiacconstants + [str(j) for j in libgiac.VARS()]
|
300
|
+
problematicnames = sorted(set(P.gens_dict()).intersection(blacklist))
|
301
|
+
|
302
|
+
if problematicnames:
|
303
|
+
raise ValueError("Variables names %s conflict in giac. Change them or purge them from in giac with libgiac.purge(\'%s\')"
|
304
|
+
% (problematicnames, problematicnames[0]))
|
305
|
+
|
306
|
+
if K.is_prime_field() and p == 0:
|
307
|
+
F = libgiac(gens)
|
308
|
+
elif K.is_prime_field() and p < 2**31:
|
309
|
+
F = (libgiac(gens) % p)
|
310
|
+
else:
|
311
|
+
raise NotImplementedError("Only prime fields of cardinal < 2^31 are implemented in Giac for Groebner bases.")
|
312
|
+
|
313
|
+
# proof or probabilistic reconstruction
|
314
|
+
if proba_epsilon is None:
|
315
|
+
if proof_polynomial():
|
316
|
+
giacsettings.proba_epsilon = 0
|
317
|
+
else:
|
318
|
+
giacsettings.proba_epsilon = 1e-15
|
319
|
+
else:
|
320
|
+
giacsettings.proba_epsilon = proba_epsilon
|
321
|
+
|
322
|
+
# prot
|
323
|
+
if prot:
|
324
|
+
libgiac('debug_infolevel(2)')
|
325
|
+
|
326
|
+
# threads
|
327
|
+
if threads is not None:
|
328
|
+
giacsettings.threads = threads
|
329
|
+
|
330
|
+
if elim_variables is None:
|
331
|
+
var_names = P.variable_names()
|
332
|
+
order_name = P.term_order().name()
|
333
|
+
if order_name == "degrevlex":
|
334
|
+
giac_order = "revlex"
|
335
|
+
elif order_name == "lex":
|
336
|
+
giac_order = "plex"
|
337
|
+
elif order_name == "deglex":
|
338
|
+
giac_order = "tdeg"
|
339
|
+
else:
|
340
|
+
blocks = P.term_order().blocks()
|
341
|
+
if (len(blocks) == 2 and
|
342
|
+
all(order.name() == "degrevlex" for order in blocks)):
|
343
|
+
giac_order = "revlex"
|
344
|
+
var_names = var_names[:len(blocks[0])]
|
345
|
+
else:
|
346
|
+
raise NotImplementedError(
|
347
|
+
"%s is not a supported term order in "
|
348
|
+
"Giac Groebner bases." % P.term_order())
|
349
|
+
|
350
|
+
# compute de groebner basis with giac
|
351
|
+
gb_giac = F.gbasis(list(var_names), giac_order)
|
352
|
+
|
353
|
+
else:
|
354
|
+
gb_giac = F.eliminate(list(elim_variables), 'gbasis')
|
355
|
+
|
356
|
+
return PolynomialSequence(gb_giac, P, immutable=True)
|