Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/libs/singular/function.pyx
4045 views
1
"""
2
libSingular: Functions
3
4
Sage implements a C wrapper around the Singular interpreter which
5
allows to call any function directly from Sage without string parsing
6
or interprocess communication overhead. Users who do not want to call
7
Singular functions directly, usually do not have to worry about this
8
interface, since it is handled by higher level functions in Sage.
9
10
AUTHORS:
11
12
- Michael Brickenstein (2009-07): initial implementation, overall design
13
- Martin Albrecht (2009-07): clean up, enhancements, etc.
14
- Michael Brickenstein (2009-10): extension to more Singular types
15
- Martin Albrecht (2010-01): clean up, support for attributes
16
- Simon King (2011-04): include the documentation provided by Singular as a code block.
17
- Burcin Erocal, Michael Brickenstein, Oleksandr Motsak, Alexander Dreyer, Simon King
18
(2011-09) plural support
19
20
EXAMPLES:
21
22
The direct approach for loading a Singular function is to call the
23
function :func:`singular_function` with the function name as
24
parameter::
25
26
sage: from sage.libs.singular.function import singular_function
27
sage: P.<a,b,c,d> = PolynomialRing(GF(7))
28
sage: std = singular_function('std')
29
sage: I = sage.rings.ideal.Cyclic(P)
30
sage: std(I)
31
[a + b + c + d,
32
b^2 + 2*b*d + d^2,
33
b*c^2 + c^2*d - b*d^2 - d^3,
34
b*c*d^2 + c^2*d^2 - b*d^3 + c*d^3 - d^4 - 1,
35
b*d^4 + d^5 - b - d,
36
c^3*d^2 + c^2*d^3 - c - d,
37
c^2*d^4 + b*c - b*d + c*d - 2*d^2]
38
39
If a Singular library needs to be loaded before a certain function is
40
available, use the :func:`lib` function as shown below::
41
42
sage: from sage.libs.singular.function import singular_function, lib as singular_lib
43
sage: primdecSY = singular_function('primdecSY')
44
Traceback (most recent call last):
45
...
46
NameError: Function 'primdecSY' is not defined.
47
48
sage: singular_lib('primdec.lib')
49
sage: primdecSY = singular_function('primdecSY')
50
51
There is also a short-hand notation for the above::
52
53
sage: primdecSY = sage.libs.singular.ff.primdec__lib.primdecSY
54
55
The above line will load "primdec.lib" first and then load the
56
function ``primdecSY``.
57
58
TESTS::
59
60
sage: from sage.libs.singular.function import singular_function
61
sage: std = singular_function('std')
62
sage: loads(dumps(std)) == std
63
True
64
"""
65
#*****************************************************************************
66
# Copyright (C) 2009 Michael Brickenstein <[email protected]>
67
# Copyright (C) 2009,2010 Martin Albrecht <[email protected]>
68
#
69
# Distributed under the terms of the GNU General Public License (GPL)
70
# http://www.gnu.org/licenses/
71
#*****************************************************************************
72
from __future__ import with_statement
73
74
include "../../ext/stdsage.pxi"
75
include "../../ext/interrupt.pxi"
76
77
from sage.structure.sage_object cimport SageObject
78
79
from sage.rings.integer cimport Integer
80
81
from sage.modules.free_module_element cimport FreeModuleElement_generic_dense
82
83
from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, new_MP
84
from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular
85
86
from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, NCPolynomial_plural, new_NCP
87
from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal
88
89
from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
90
91
from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal, singular_ideal_to_sage_sequence
92
93
from sage.libs.singular.decl cimport leftv, idhdl, poly, ideal, ring, number, intvec, lists
94
from sage.libs.singular.decl cimport sleftv_bin, omAllocBin, omFreeBin, omStrDup, slists_bin, omAlloc0Bin
95
from sage.libs.singular.decl cimport iiMake_proc, iiExprArith1, iiExprArith2, iiExprArith3, iiExprArithM, iiLibCmd
96
from sage.libs.singular.decl cimport ggetid, IDEAL_CMD, CMD_M, POLY_CMD, PROC_CMD, RING_CMD, QRING_CMD, NUMBER_CMD, INT_CMD, INTVEC_CMD, RESOLUTION_CMD
97
from sage.libs.singular.decl cimport MODUL_CMD, LIST_CMD, MATRIX_CMD, VECTOR_CMD, STRING_CMD, V_LOAD_LIB, V_REDEFINE, INTMAT_CMD, NONE, PACKAGE_CMD
98
from sage.libs.singular.decl cimport IsCmd, rChangeCurrRing, currRing, p_Copy, rIsPluralRing, rPrint, rOrderingString
99
from sage.libs.singular.decl cimport IDROOT, enterid, currRingHdl, memcpy, IDNEXT, IDTYP, IDPACKAGE
100
from sage.libs.singular.decl cimport errorreported, verbose, Sy_bit, currentVoice, myynest
101
from sage.libs.singular.decl cimport intvec_new_int3, intvec_new, matrix, mpNew
102
from sage.libs.singular.decl cimport p_Add_q, p_SetComp, p_GetComp, pNext, p_Setm, IDELEMS
103
from sage.libs.singular.decl cimport idInit, syStrategy, atSet, atGet, setFlag, FLAG_STD
104
105
from sage.libs.singular.option import opt_ctx
106
from sage.libs.singular.polynomial cimport singular_vector_maximal_component, singular_polynomial_check
107
from sage.libs.singular.singular cimport sa2si, si2sa, si2sa_intvec
108
109
from sage.libs.singular.singular import error_messages
110
111
from sage.interfaces.singular import get_docstring
112
113
from sage.misc.misc import get_verbose
114
115
from sage.structure.sequence import Sequence, Sequence_generic
116
from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
117
118
119
cdef poly* sage_vector_to_poly(v, ring *r) except <poly*> -1:
120
"""
121
Convert a vector or list of multivariate polynomials to a
122
polynomial by adding them all up.
123
"""
124
cdef poly *res = NULL
125
cdef poly *poly_component
126
cdef poly *p_iter
127
cdef int component
128
129
for (i, p) in enumerate(v):
130
component = <int>i+1
131
poly_component = copy_sage_polynomial_into_singular_poly(p)
132
p_iter = poly_component
133
while p_iter!=NULL:
134
p_SetComp(p_iter, component, r)
135
p_Setm(p_iter, r)
136
p_iter=pNext(p_iter)
137
res=p_Add_q(res, poly_component, r)
138
return res
139
140
141
cdef class RingWrap:
142
"""
143
A simple wrapper around Singular's rings.
144
"""
145
def __repr__(self):
146
"""
147
EXAMPLE::
148
149
sage: from sage.libs.singular.function import singular_function
150
sage: P.<x,y,z> = PolynomialRing(QQ)
151
sage: ringlist = singular_function("ringlist")
152
sage: l = ringlist(P)
153
sage: ring = singular_function("ring")
154
sage: ring(l, ring=P)
155
<RingWrap>
156
"""
157
if not self.is_commutative():
158
return "<noncommutative RingWrap>"
159
return "<RingWrap>"
160
161
def __dealloc__(self):
162
if self._ring!=NULL:
163
self._ring.ref -= 1
164
165
def ngens(self):
166
"""
167
Get number of generators.
168
169
EXAMPLE::
170
171
sage: from sage.libs.singular.function import singular_function
172
sage: P.<x,y,z> = PolynomialRing(QQ)
173
sage: ringlist = singular_function("ringlist")
174
sage: l = ringlist(P)
175
sage: ring = singular_function("ring")
176
sage: ring(l, ring=P).ngens()
177
3
178
"""
179
return self._ring.N
180
181
def var_names(self):
182
"""
183
Get names of variables.
184
185
EXAMPLE::
186
187
sage: from sage.libs.singular.function import singular_function
188
sage: P.<x,y,z> = PolynomialRing(QQ)
189
sage: ringlist = singular_function("ringlist")
190
sage: l = ringlist(P)
191
sage: ring = singular_function("ring")
192
sage: ring(l, ring=P).var_names()
193
['x', 'y', 'z']
194
"""
195
return [self._ring.names[i] for i in range(self.ngens())]
196
197
def npars(self):
198
"""
199
Get number of parameters.
200
201
EXAMPLE::
202
203
sage: from sage.libs.singular.function import singular_function
204
sage: P.<x,y,z> = PolynomialRing(QQ)
205
sage: ringlist = singular_function("ringlist")
206
sage: l = ringlist(P)
207
sage: ring = singular_function("ring")
208
sage: ring(l, ring=P).npars()
209
0
210
"""
211
return self._ring.P
212
213
def ordering_string(self):
214
"""
215
Get Singular string defining monomial ordering.
216
217
EXAMPLE::
218
219
sage: from sage.libs.singular.function import singular_function
220
sage: P.<x,y,z> = PolynomialRing(QQ)
221
sage: ringlist = singular_function("ringlist")
222
sage: l = ringlist(P)
223
sage: ring = singular_function("ring")
224
sage: ring(l, ring=P).ordering_string()
225
'dp(3),C'
226
"""
227
return rOrderingString(self._ring)
228
229
230
231
def par_names(self):
232
"""
233
Get parameter names.
234
235
EXAMPLE::
236
237
sage: from sage.libs.singular.function import singular_function
238
sage: P.<x,y,z> = PolynomialRing(QQ)
239
sage: ringlist = singular_function("ringlist")
240
sage: l = ringlist(P)
241
sage: ring = singular_function("ring")
242
sage: ring(l, ring=P).par_names()
243
[]
244
"""
245
return [self._ring.parameter[i] for i in range(self.npars())]
246
247
def characteristic(self):
248
"""
249
Get characteristic.
250
251
EXAMPLE::
252
253
sage: from sage.libs.singular.function import singular_function
254
sage: P.<x,y,z> = PolynomialRing(QQ)
255
sage: ringlist = singular_function("ringlist")
256
sage: l = ringlist(P)
257
sage: ring = singular_function("ring")
258
sage: ring(l, ring=P).characteristic()
259
0
260
"""
261
return self._ring.ch
262
263
def is_commutative(self):
264
"""
265
Determine whether a given ring is commutative.
266
267
EXAMPLE::
268
269
sage: from sage.libs.singular.function import singular_function
270
sage: P.<x,y,z> = PolynomialRing(QQ)
271
sage: ringlist = singular_function("ringlist")
272
sage: l = ringlist(P)
273
sage: ring = singular_function("ring")
274
sage: ring(l, ring=P).is_commutative()
275
True
276
"""
277
return not rIsPluralRing(self._ring)
278
279
def _output(self):
280
"""
281
Use Singular output.
282
283
EXAMPLE::
284
285
sage: from sage.libs.singular.function import singular_function
286
sage: P.<x,y,z> = PolynomialRing(QQ)
287
sage: ringlist = singular_function("ringlist")
288
sage: l = ringlist(P)
289
sage: ring = singular_function("ring")
290
sage: ring(l, ring=P)._output()
291
"""
292
rPrint(self._ring)
293
294
cdef class Resolution:
295
"""
296
A simple wrapper around Singular's resolutions.
297
"""
298
def __init__(self, base_ring):
299
"""
300
EXAMPLE::
301
302
sage: from sage.libs.singular.function import singular_function
303
sage: mres = singular_function("mres")
304
sage: syz = singular_function("syz")
305
sage: P.<x,y,z> = PolynomialRing(QQ)
306
sage: I = P.ideal([x+y,x*y-y, y*2,x**2+1])
307
sage: M = syz(I)
308
sage: resolution = mres(M, 0)
309
"""
310
#FIXME: still not working noncommutative
311
assert is_sage_wrapper_for_singular_ring(base_ring)
312
self.base_ring = base_ring
313
def __repr__(self):
314
"""
315
EXAMPLE::
316
317
sage: from sage.libs.singular.function import singular_function
318
sage: mres = singular_function("mres")
319
sage: syz = singular_function("syz")
320
sage: P.<x,y,z> = PolynomialRing(QQ)
321
sage: I = P.ideal([x+y,x*y-y, y*2,x**2+1])
322
sage: M = syz(I)
323
sage: resolution = mres(M, 0)
324
sage: resolution
325
<Resolution>
326
"""
327
return "<Resolution>"
328
def __dealloc__(self):
329
"""
330
EXAMPLE::
331
332
sage: from sage.libs.singular.function import singular_function
333
sage: mres = singular_function("mres")
334
sage: syz = singular_function("syz")
335
sage: P.<x,y,z> = PolynomialRing(QQ)
336
sage: I = P.ideal([x+y,x*y-y, y*2,x**2+1])
337
sage: M = syz(I)
338
sage: resolution = mres(M, 0)
339
sage: del resolution
340
"""
341
if self._resolution != NULL:
342
self._resolution.references -= 1
343
344
cdef leftv* new_leftv(void *data, res_type):
345
"""
346
INPUT:
347
348
- ``data`` - some Singular data this interpreter object points to
349
- ``res_type`` - the type of that data
350
"""
351
cdef leftv* res
352
res = <leftv*>omAllocBin(sleftv_bin)
353
res.Init()
354
res.data = data
355
res.rtyp = res_type
356
return res
357
358
cdef free_leftv(leftv *args, ring *r = NULL):
359
"""
360
Kills this ``leftv`` and all ``leftv``s in the tail.
361
362
INPUT:
363
364
- ``args`` - a list of Singular arguments
365
"""
366
args.CleanUp(r)
367
omFreeBin(args, sleftv_bin)
368
369
# =====================================
370
# = Singular/Plural Abstraction Layer =
371
# =====================================
372
373
def is_sage_wrapper_for_singular_ring(ring):
374
"""
375
Check whether wrapped ring arises from Singular or Singular/Plural.
376
377
EXAMPLE::
378
379
sage: from sage.libs.singular.function import is_sage_wrapper_for_singular_ring
380
sage: P.<x,y,z> = QQ[]
381
sage: is_sage_wrapper_for_singular_ring(P)
382
True
383
384
::
385
386
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
387
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
388
sage: is_sage_wrapper_for_singular_ring(P)
389
True
390
391
"""
392
if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
393
return True
394
if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
395
return True
396
return False
397
398
cdef new_sage_polynomial(ring, poly *p):
399
if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
400
return new_MP(ring, p)
401
else:
402
if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
403
return new_NCP(ring, p)
404
raise ValueError("not a singular or plural ring")
405
406
def is_singular_poly_wrapper(p):
407
"""
408
Checks if p is some data type corresponding to some singular ``poly``.
409
410
EXAMPLE::
411
412
sage: from sage.libs.singular.function import is_singular_poly_wrapper
413
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
414
sage: H.<x,y,z> = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y})
415
sage: is_singular_poly_wrapper(x+y)
416
True
417
418
"""
419
return PY_TYPE_CHECK(p, MPolynomial_libsingular) or PY_TYPE_CHECK(p, NCPolynomial_plural)
420
421
def all_singular_poly_wrapper(s):
422
"""
423
Tests for a sequence ``s``, whether it consists of
424
singular polynomials.
425
426
EXAMPLE::
427
428
sage: from sage.libs.singular.function import all_singular_poly_wrapper
429
sage: P.<x,y,z> = QQ[]
430
sage: all_singular_poly_wrapper([x+1, y])
431
True
432
sage: all_singular_poly_wrapper([x+1, y, 1])
433
False
434
"""
435
for p in s:
436
if not is_singular_poly_wrapper(p):
437
return False
438
return True
439
440
cdef poly* access_singular_poly(p) except <poly*> -1:
441
"""
442
Get the raw ``poly`` pointer from a wrapper object.
443
"""
444
if PY_TYPE_CHECK(p, MPolynomial_libsingular):
445
return (<MPolynomial_libsingular> p)._poly
446
else:
447
if PY_TYPE_CHECK(p, NCPolynomial_plural):
448
return (<NCPolynomial_plural> p)._poly
449
raise ValueError("not a singular polynomial wrapper")
450
451
cdef ring* access_singular_ring(r) except <ring*> -1:
452
"""
453
Get the singular ``ring`` pointer from a wrapper object.
454
"""
455
if PY_TYPE_CHECK(r, MPolynomialRing_libsingular):
456
return (<MPolynomialRing_libsingular> r )._ring
457
if PY_TYPE_CHECK(r, NCPolynomialRing_plural):
458
return (<NCPolynomialRing_plural> r )._ring
459
raise ValueError("not a singular polynomial ring wrapper")
460
461
cdef poly* copy_sage_polynomial_into_singular_poly(p):
462
return p_Copy(access_singular_poly(p), access_singular_ring(p.parent()))
463
464
def all_vectors(s):
465
"""
466
Checks if a sequence ``s`` consists of free module
467
elements over a singular ring.
468
469
EXAMPLE::
470
471
sage: from sage.libs.singular.function import all_vectors
472
sage: P.<x,y,z> = QQ[]
473
sage: M = P**2
474
sage: all_vectors([x])
475
False
476
sage: all_vectors([(x,y)])
477
False
478
sage: all_vectors([M(0), M((x,y))])
479
True
480
sage: all_vectors([M(0), M((x,y)),(0,0)])
481
False
482
"""
483
for p in s:
484
if not (PY_TYPE_CHECK(p, FreeModuleElement_generic_dense)\
485
and is_sage_wrapper_for_singular_ring(p.parent().base_ring())):
486
return False
487
return True
488
489
490
cdef class Converter(SageObject):
491
"""
492
A :class:`Converter` interfaces between Sage objects and Singular
493
interpreter objects.
494
"""
495
496
def __init__(self, args, ring, attributes=None):
497
"""
498
Create a new argument list.
499
500
INPUT:
501
502
- ``args`` - a list of Python objects
503
- ``ring`` - a multivariate polynomial ring
504
- ``attributes`` - an optional dictionary of Singular
505
attributes (default: ``None``)
506
507
EXAMPLE::
508
509
sage: from sage.libs.singular.function import Converter
510
sage: P.<a,b,c> = PolynomialRing(GF(127))
511
sage: Converter([a,b,c],ring=P)
512
Singular Converter in Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
513
"""
514
cdef leftv *v
515
self.args = NULL
516
self._sage_ring = ring
517
if ring is not None:
518
self._singular_ring = access_singular_ring(ring)
519
520
from sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
521
from sage.matrix.matrix_integer_dense import Matrix_integer_dense
522
from sage.matrix.matrix_generic_dense import Matrix_generic_dense
523
for a in args:
524
if is_singular_poly_wrapper(a):
525
v = self.append_polynomial(a)
526
527
elif is_sage_wrapper_for_singular_ring(a):
528
v = self.append_ring(a)
529
530
elif PY_TYPE_CHECK(a, MPolynomialIdeal) or \
531
PY_TYPE_CHECK(a, NCPolynomialIdeal):
532
v = self.append_ideal(a)
533
534
elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long):
535
v = self.append_int(a)
536
537
elif PY_TYPE_CHECK(a, basestring):
538
v = self.append_str(a)
539
540
elif PY_TYPE_CHECK(a, Matrix_mpolynomial_dense):
541
v = self.append_matrix(a)
542
543
elif PY_TYPE_CHECK(a, Matrix_integer_dense):
544
v = self.append_intmat(a)
545
546
elif PY_TYPE_CHECK(a, Matrix_generic_dense) and\
547
is_sage_wrapper_for_singular_ring(a.parent().base_ring()):
548
self.append_matrix(a)
549
550
elif PY_TYPE_CHECK(a, Resolution):
551
v = self.append_resolution(a)
552
553
elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
554
and is_sage_wrapper_for_singular_ring(
555
a.parent().base_ring()):
556
v = self.append_vector(a)
557
558
# as output ideals get converted to sequences
559
# sequences of polynomials should get converted to ideals
560
# this means, that Singular lists should not be converted to Sequences,
561
# as we do not want ambiguities
562
elif PY_TYPE_CHECK(a, Sequence_generic)\
563
and all_singular_poly_wrapper(a):
564
v = self.append_ideal(ring.ideal(a))
565
elif PY_TYPE_CHECK(a, PolynomialSequence):
566
v = self.append_ideal(ring.ideal(a))
567
elif PY_TYPE_CHECK(a, Sequence_generic)\
568
and all_vectors(a):
569
v = self.append_module(a)
570
elif PY_TYPE_CHECK(a, list):
571
v = self.append_list(a)
572
573
elif PY_TYPE_CHECK(a, tuple):
574
is_intvec = True
575
for i in a:
576
if not (PY_TYPE_CHECK(i, int)
577
or PY_TYPE_CHECK(i, Integer)):
578
is_intvec = False
579
break
580
if is_intvec:
581
v = self.append_intvec(a)
582
else:
583
v = self.append_list(a)
584
elif a.parent() is self._sage_ring.base_ring():
585
v = self.append_number(a)
586
587
elif PY_TYPE_CHECK(a, Integer):
588
v = self.append_int(a)
589
590
else:
591
raise TypeError("unknown argument type '%s'"%(type(a),))
592
593
if attributes and a in attributes:
594
for attrib in attributes[a]:
595
if attrib == "isSB" :
596
val = int(attributes[a][attrib])
597
atSet(v, omStrDup("isSB"), <void*><int>val, INT_CMD)
598
setFlag(v, FLAG_STD)
599
else:
600
raise NotImplementedError("Support for attribute '%s' not implemented yet."%attrib)
601
602
def ring(self):
603
"""
604
Return the ring in which the arguments of this list live.
605
606
EXAMPLE::
607
608
sage: from sage.libs.singular.function import Converter
609
sage: P.<a,b,c> = PolynomialRing(GF(127))
610
sage: Converter([a,b,c],ring=P).ring()
611
Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
612
"""
613
return self._sage_ring
614
615
def _repr_(self):
616
"""
617
EXAMPLE::
618
619
sage: from sage.libs.singular.function import Converter
620
sage: P.<a,b,c> = PolynomialRing(GF(127))
621
sage: Converter([a,b,c],ring=P) # indirect doctest
622
Singular Converter in Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
623
"""
624
return "Singular Converter in %s"%(self._sage_ring)
625
626
def __dealloc__(self):
627
cdef ring *r = access_singular_ring(self._sage_ring)
628
if self.args:
629
free_leftv(self.args, r)
630
631
def __len__(self):
632
"""
633
EXAMPLE::
634
635
sage: from sage.libs.singular.function import Converter
636
sage: P.<a,b,c> = PolynomialRing(GF(127))
637
sage: len(Converter([a,b,c],ring=P))
638
3
639
"""
640
cdef leftv * v
641
v=self.args
642
cdef int l
643
l=0
644
while v != NULL:
645
l=l+1
646
v=v.next
647
return l
648
649
cdef leftv* pop_front(self) except NULL:
650
"""
651
Pop a Singular element from the front of the list.
652
"""
653
assert(self.args != NULL)
654
cdef leftv *res = self.args
655
self.args = self.args.next
656
res.next = NULL
657
return res
658
659
cdef leftv *_append_leftv(self, leftv *v):
660
"""
661
Append a new Singular element to the list.
662
"""
663
cdef leftv* last
664
if not self.args == NULL:
665
last = self.args
666
while not last.next == NULL:
667
last=last.next
668
last.next=v
669
else:
670
self.args = v
671
return v
672
673
cdef leftv *_append(self, void* data, int res_type):
674
"""
675
Create a new ``leftv`` and append it to the list.
676
677
INPUT:
678
679
- ``data`` - the raw data
680
- ``res_type`` - the type of the data
681
"""
682
return self._append_leftv( new_leftv(data, res_type) )
683
684
cdef to_sage_matrix(self, matrix* mat):
685
"""
686
Convert singular matrix to matrix over the polynomial ring.
687
"""
688
from sage.matrix.constructor import Matrix
689
#cdef ring *singular_ring = (<MPolynomialRing_libsingular>\
690
# self._sage_ring)._ring
691
ncols = mat.ncols
692
nrows = mat.nrows
693
result = Matrix(self._sage_ring, nrows, ncols)
694
for i in xrange(nrows):
695
for j in xrange(ncols):
696
p = new_sage_polynomial(self._sage_ring, mat.m[i*ncols+j])
697
mat.m[i*ncols+j]=NULL
698
result[i,j] = p
699
return result
700
701
cdef to_sage_vector_destructive(self, poly *p, free_module = None):
702
#cdef ring *r=self._ring._ring
703
cdef int rank
704
if free_module:
705
rank = free_module.rank()
706
else:
707
rank = singular_vector_maximal_component(p, self._singular_ring)
708
free_module = self._sage_ring**rank
709
cdef poly *acc
710
cdef poly *p_iter
711
cdef poly *first
712
cdef poly *previous
713
cdef int i
714
result = []
715
for i from 1 <= i <= rank:
716
previous = NULL
717
acc = NULL
718
first = NULL
719
p_iter=p
720
while p_iter != NULL:
721
if p_GetComp(p_iter, self._singular_ring) == i:
722
p_SetComp(p_iter,0, self._singular_ring)
723
p_Setm(p_iter, self._singular_ring)
724
if acc == NULL:
725
first = p_iter
726
else:
727
acc.next = p_iter
728
acc = p_iter
729
if p_iter==p:
730
p=pNext(p_iter)
731
if previous != NULL:
732
previous.next=pNext(p_iter)
733
p_iter = pNext(p_iter)
734
acc.next = NULL
735
else:
736
previous = p_iter
737
p_iter = pNext(p_iter)
738
739
result.append(new_sage_polynomial(self._sage_ring, first))
740
return free_module(result)
741
742
cdef object to_sage_module_element_sequence_destructive( self, ideal *i):
743
"""
744
Convert a SINGULAR module to a Sage Sequence (the format Sage
745
stores a Groebner basis in).
746
747
INPUT:
748
749
- ``i`` -- a SINGULAR ideal
750
- ``r`` -- a SINGULAR ring
751
- ``sage_ring`` -- a Sage ring matching r
752
"""
753
#cdef MPolynomialRing_libsingular sage_ring = self._ring
754
cdef int j
755
cdef int rank=i.rank
756
free_module = self._sage_ring ** rank
757
l = []
758
759
for j from 0 <= j < IDELEMS(i):
760
p = self.to_sage_vector_destructive(i.m[j], free_module)
761
i.m[j]=NULL#save it from getting freed
762
l.append( p )
763
764
return Sequence(l, check=False, immutable=True)
765
766
767
cdef to_sage_integer_matrix(self, intvec* mat):
768
"""
769
Convert Singular matrix to matrix over the polynomial ring.
770
"""
771
from sage.matrix.constructor import Matrix
772
from sage.rings.integer_ring import ZZ
773
774
ncols = mat.cols()
775
nrows = mat.rows()
776
777
result = Matrix(ZZ, nrows, ncols)
778
for i in xrange(nrows):
779
for j in xrange(ncols):
780
result[i,j] = mat.get(i*ncols+j)
781
return result
782
783
784
cdef leftv *append_polynomial(self, p) except NULL:
785
"""
786
Append the polynomial ``p`` to the list.
787
"""
788
cdef poly* _p
789
_p = copy_sage_polynomial_into_singular_poly(p)
790
791
return self._append(_p, POLY_CMD)
792
793
cdef leftv *append_ideal(self, i) except NULL:
794
"""
795
Append the ideal ``i`` to the list.
796
"""
797
cdef ideal* singular_ideal = sage_ideal_to_singular_ideal(i)
798
return self._append(singular_ideal, IDEAL_CMD)
799
800
cdef leftv *append_module(self, m) except NULL:
801
"""
802
Append sequence ``m`` of vectors over the polynomial ring to
803
the list
804
"""
805
rank = max([v.parent().rank() for v in m])
806
cdef ideal *result
807
cdef ring *r = self._singular_ring
808
cdef ideal *i
809
cdef int j = 0
810
811
812
813
i = idInit(len(m),rank)
814
for f in m:
815
i.m[j] = sage_vector_to_poly(f, r)
816
j+=1
817
return self._append(<void*> i, MODUL_CMD)
818
819
cdef leftv *append_number(self, n) except NULL:
820
"""
821
Append the number ``n`` to the list.
822
"""
823
cdef number *_n = sa2si(n, self._singular_ring)
824
return self._append(<void *>_n, NUMBER_CMD)
825
826
cdef leftv *append_ring(self, r) except NULL:
827
"""
828
Append the ring ``r`` to the list.
829
"""
830
cdef ring *_r = access_singular_ring(r)
831
_r.ref+=1
832
return self._append(<void *>_r, RING_CMD)
833
834
cdef leftv *append_matrix(self, mat) except NULL:
835
836
sage_ring = mat.base_ring()
837
cdef ring *r=<ring*> access_singular_ring(sage_ring)
838
839
cdef poly *p
840
ncols = mat.ncols()
841
nrows = mat.nrows()
842
cdef matrix* _m=mpNew(nrows,ncols)
843
for i in xrange(nrows):
844
for j in xrange(ncols):
845
#FIXME
846
p = copy_sage_polynomial_into_singular_poly(mat[i,j])
847
_m.m[ncols*i+j]=p
848
return self._append(_m, MATRIX_CMD)
849
850
cdef leftv *append_int(self, n) except NULL:
851
"""
852
Append the integer ``n`` to the list.
853
"""
854
cdef long _n = n
855
return self._append(<void*>_n, INT_CMD)
856
857
858
859
cdef leftv *append_list(self, l) except NULL:
860
"""
861
Append the list ``l`` to the list.
862
"""
863
864
cdef Converter c = Converter(l, self._sage_ring)
865
n = len(c)
866
867
cdef lists *singular_list=<lists*>omAlloc0Bin(slists_bin)
868
singular_list.Init(n)
869
cdef leftv* iv
870
for i in xrange(n):
871
iv=c.pop_front()
872
memcpy(&singular_list.m[i],iv,sizeof(leftv))
873
omFreeBin(iv, sleftv_bin)
874
875
return self._append(<void*>singular_list, LIST_CMD)
876
877
cdef leftv *append_intvec(self, a) except NULL:
878
"""
879
Append ``a`` to the list as intvec.
880
"""
881
s = len(a)
882
cdef intvec *iv=intvec_new()
883
iv.resize(s)
884
#new intvec(s);
885
886
for i in xrange(s):
887
iv.ivGetVec()[i]=<int>a[i]
888
return self._append(<void*>iv, INTVEC_CMD)
889
890
cdef leftv *append_vector(self, v) except NULL:
891
"""
892
Append vector ``v`` from free
893
module over polynomial ring.
894
"""
895
cdef ring *r = self._singular_ring
896
cdef poly *p = sage_vector_to_poly(v, r)
897
return self._append(<void*> p, VECTOR_CMD)
898
899
cdef leftv *append_resolution(self, Resolution resolution) except NULL:
900
"""
901
Append free resolution ``r`` to the list.
902
"""
903
resolution._resolution.references += 1
904
return self._append(<void*> resolution._resolution, RESOLUTION_CMD)
905
906
cdef leftv *append_intmat(self, a) except NULL:
907
"""
908
Append ``a`` to the list as intvec.
909
"""
910
cdef int nrows = <int> a.nrows()
911
cdef int ncols = <int> a.ncols()
912
cdef intvec *iv=intvec_new_int3(nrows, ncols, 0)
913
#new intvec(s);
914
915
for i in xrange(nrows):
916
for j in xrange(ncols):
917
iv.ivGetVec()[i*ncols+j]=<int>a[i,j]
918
return self._append(<void*>iv, INTMAT_CMD)
919
920
cdef leftv *append_str(self, n) except NULL:
921
"""
922
Append the string ``n`` to the list.
923
"""
924
cdef char *_n = <char *>n
925
return self._append(omStrDup(_n), STRING_CMD)
926
927
cdef to_python(self, leftv* to_convert):
928
"""
929
Convert the ``leftv`` to a Python object.
930
931
INPUT:
932
933
- ``to_convert`` - a Singular ``leftv``
934
"""
935
#FIXME
936
cdef MPolynomial_libsingular res_poly
937
cdef int rtyp = to_convert.rtyp
938
cdef lists *singular_list
939
cdef Resolution res_resolution
940
if rtyp == IDEAL_CMD:
941
return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._singular_ring, self._sage_ring)
942
943
elif rtyp == POLY_CMD:
944
#FIXME
945
res_poly = MPolynomial_libsingular(self._sage_ring)
946
res_poly._poly = <poly*>to_convert.data
947
to_convert.data = NULL
948
#prevent it getting free, when cleaning the leftv
949
return res_poly
950
951
elif rtyp == INT_CMD:
952
return <long>to_convert.data
953
954
elif rtyp == NUMBER_CMD:
955
return si2sa(<number *>to_convert.data, self._singular_ring, self._sage_ring.base_ring())
956
957
elif rtyp == INTVEC_CMD:
958
return si2sa_intvec(<intvec *>to_convert.data)
959
960
elif rtyp == STRING_CMD:
961
ret = <char *>to_convert.data
962
return ret
963
elif rtyp == VECTOR_CMD:
964
result = self.to_sage_vector_destructive(
965
<poly *> to_convert.data)
966
to_convert.data = NULL
967
return result
968
969
970
elif rtyp == RING_CMD or rtyp==QRING_CMD:
971
return new_RingWrap( <ring*> to_convert.data )
972
973
elif rtyp == MATRIX_CMD:
974
return self.to_sage_matrix(<matrix*> to_convert.data )
975
976
elif rtyp == LIST_CMD:
977
singular_list = <lists*> to_convert.data
978
ret = []
979
for i in xrange(singular_list.nr+1):
980
ret.append(
981
self.to_python(
982
&(singular_list.m[i])))
983
return ret
984
985
986
elif rtyp == MODUL_CMD:
987
return self.to_sage_module_element_sequence_destructive(
988
<ideal*> to_convert.data
989
)
990
elif rtyp == INTMAT_CMD:
991
return self.to_sage_integer_matrix(
992
<intvec*> to_convert.data)
993
elif rtyp == RESOLUTION_CMD:
994
res_resolution = Resolution(self._sage_ring)
995
res_resolution._resolution = <syStrategy*> to_convert.data
996
res_resolution._resolution.references += 1
997
return res_resolution
998
elif rtyp == NONE:
999
return None
1000
else:
1001
raise NotImplementedError("rtyp %d not implemented."%(rtyp))
1002
1003
cdef class BaseCallHandler:
1004
"""
1005
A call handler is an abstraction which hides the details of the
1006
implementation differences between kernel and library functions.
1007
"""
1008
cdef leftv* handle_call(self, Converter argument_list, ring *_ring=NULL):
1009
"""
1010
Actual function call.
1011
"""
1012
return NULL
1013
1014
cdef bint free_res(self):
1015
"""
1016
Do we need to free the result object.
1017
"""
1018
return False
1019
1020
cdef class LibraryCallHandler(BaseCallHandler):
1021
"""
1022
A call handler is an abstraction which hides the details of the
1023
implementation differences between kernel and library functions.
1024
1025
This class implements calling a library function.
1026
1027
.. note::
1028
1029
Do not construct this class directly, use
1030
:func:`singular_function` instead.
1031
"""
1032
def __init__(self):
1033
"""
1034
EXAMPLE::
1035
1036
sage: from sage.libs.singular.function import LibraryCallHandler
1037
sage: LibraryCallHandler()
1038
<sage.libs.singular.function.LibraryCallHandler object at 0x...>
1039
"""
1040
super(LibraryCallHandler, self).__init__()
1041
1042
cdef leftv* handle_call(self, Converter argument_list, ring *_ring=NULL):
1043
if _ring != currRing: rChangeCurrRing(_ring)
1044
return iiMake_proc(self.proc_idhdl, NULL, argument_list.args)
1045
1046
cdef bint free_res(self):
1047
"""
1048
We do not need to free the result object for library
1049
functions.
1050
"""
1051
return False
1052
1053
cdef class KernelCallHandler(BaseCallHandler):
1054
"""
1055
A call handler is an abstraction which hides the details of the
1056
implementation differences between kernel and library functions.
1057
1058
This class implements calling a kernel function.
1059
1060
.. note::
1061
1062
Do not construct this class directly, use
1063
:func:`singular_function` instead.
1064
"""
1065
def __init__(self, cmd_n, arity):
1066
"""
1067
EXAMPLE::
1068
1069
sage: from sage.libs.singular.function import KernelCallHandler
1070
sage: KernelCallHandler(0,0)
1071
<sage.libs.singular.function.KernelCallHandler object at 0x...>
1072
"""
1073
super(KernelCallHandler, self).__init__()
1074
self.cmd_n = cmd_n
1075
self.arity = arity
1076
1077
cdef leftv* handle_call(self, Converter argument_list, ring *_ring=NULL):
1078
cdef leftv * res
1079
res = <leftv*> omAllocBin(sleftv_bin)
1080
res.Init()
1081
cdef leftv *arg1
1082
cdef leftv *arg2
1083
cdef leftv *arg3
1084
if self.arity != CMD_M:
1085
number_of_arguments=len(argument_list)
1086
1087
if number_of_arguments == 1:
1088
arg1 = argument_list.pop_front()
1089
if _ring != currRing: rChangeCurrRing(_ring)
1090
iiExprArith1(res, arg1, self.cmd_n)
1091
free_leftv(arg1)
1092
1093
elif number_of_arguments == 2:
1094
arg1 = argument_list.pop_front()
1095
arg2 = argument_list.pop_front()
1096
if _ring != currRing: rChangeCurrRing(_ring)
1097
iiExprArith2(res, arg1, self.cmd_n, arg2, self.cmd_n>255)
1098
free_leftv(arg1)
1099
free_leftv(arg2)
1100
1101
elif number_of_arguments == 3:
1102
arg1 = argument_list.pop_front()
1103
arg2 = argument_list.pop_front()
1104
arg3 = argument_list.pop_front()
1105
if _ring != currRing: rChangeCurrRing(_ring)
1106
iiExprArith3(res, self.cmd_n, arg1, arg2, arg3)
1107
free_leftv(arg1)
1108
free_leftv(arg2)
1109
free_leftv(arg3)
1110
else:
1111
if _ring != currRing: rChangeCurrRing(_ring)
1112
iiExprArithM(res, argument_list.args, self.cmd_n)
1113
1114
return res
1115
1116
cdef bint free_res(self):
1117
"""
1118
We need to free the result object for kernel functions.
1119
"""
1120
return True
1121
1122
cdef class SingularFunction(SageObject):
1123
"""
1124
The base class for Singular functions either from the kernel or
1125
from the library.
1126
"""
1127
def __init__(self, name):
1128
"""
1129
INPUT:
1130
1131
- ``name`` - the name of the function
1132
1133
EXAMPLE::
1134
1135
sage: from sage.libs.singular.function import SingularFunction
1136
sage: SingularFunction('foobar')
1137
foobar (singular function)
1138
"""
1139
self._name = name
1140
1141
global currRingHdl
1142
if currRingHdl == NULL:
1143
currRingHdl = enterid("my_awesome_sage_ring", 0, RING_CMD, &IDROOT, 1)
1144
currRingHdl.data.uring.ref += 1
1145
1146
cdef BaseCallHandler get_call_handler(self):
1147
"""
1148
Return a call handler which does the actual work.
1149
"""
1150
raise NotImplementedError
1151
1152
cdef bint function_exists(self):
1153
"""
1154
Return ``True`` if the function exists in this interface.
1155
"""
1156
raise NotImplementedError
1157
1158
def _repr_(self):
1159
"""
1160
EXAMPLE::
1161
1162
sage: from sage.libs.singular.function import SingularFunction
1163
sage: SingularFunction('foobar') # indirect doctest
1164
foobar (singular function)
1165
"""
1166
return "%s (singular function)" %(self._name)
1167
1168
def __call__(self, *args, ring=None, bint interruptible=True, attributes=None):
1169
"""
1170
Call this function with the provided arguments ``args`` in the
1171
ring ``R``.
1172
1173
INPUT:
1174
1175
- ``args`` - a list of arguments
1176
- ``ring`` - a multivariate polynomial ring
1177
- ``interruptible`` - if ``True`` pressing Ctrl-C during the
1178
execution of this function will interrupt the computation
1179
(default: ``True``)
1180
1181
- ``attributes`` - a dictionary of optional Singular
1182
attributes assigned to Singular objects (default: ``None``)
1183
1184
EXAMPLE::
1185
1186
sage: from sage.libs.singular.function import singular_function
1187
sage: size = singular_function('size')
1188
sage: P.<a,b,c> = PolynomialRing(QQ)
1189
sage: size(a, ring=P)
1190
1
1191
sage: size(2r,ring=P)
1192
1
1193
sage: size(2, ring=P)
1194
1
1195
sage: size(2)
1196
Traceback (most recent call last):
1197
...
1198
ValueError: Could not detect ring.
1199
sage: size(Ideal([a*b + c, a + 1]), ring=P)
1200
2
1201
sage: size(Ideal([a*b + c, a + 1]))
1202
2
1203
sage: size(1,2, ring=P)
1204
Traceback (most recent call last):
1205
...
1206
RuntimeError: Error in Singular function call 'size':
1207
size(`int`,`int`) failed
1208
1209
sage: size('foobar', ring=P)
1210
6
1211
1212
Show the usage of the optional ``attributes`` parameter::
1213
1214
sage: P.<x,y,z> = PolynomialRing(QQ)
1215
sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
1216
sage: I = Ideal(I.groebner_basis())
1217
sage: hilb = sage.libs.singular.ff.hilb
1218
sage: hilb(I) # Singular will print // ** _ is no standard basis
1219
1220
So we tell Singular that ``I`` is indeed a Groebner basis::
1221
1222
sage: hilb(I,attributes={I:{'isSB':1}}) # no complaint from Singular
1223
1224
1225
TESTS:
1226
1227
We show that the interface recovers gracefully from errors::
1228
1229
sage: P.<e,d,c,b,a> = PolynomialRing(QQ,5,order='lex')
1230
sage: I = sage.rings.ideal.Cyclic(P)
1231
1232
sage: triangL = sage.libs.singular.ff.triang__lib.triangL
1233
sage: _ = triangL(I)
1234
Traceback (most recent call last):
1235
...
1236
RuntimeError: Error in Singular function call 'triangL':
1237
The input is no groebner basis.
1238
leaving triang.lib::triangL
1239
1240
sage: G= Ideal(I.groebner_basis())
1241
sage: triangL(G,attributes={G:{'isSB':1}})
1242
[[e + d + c + b + a, ...]]
1243
"""
1244
if ring is None:
1245
ring = self.common_ring(args, ring)
1246
if not (PY_TYPE_CHECK(ring, MPolynomialRing_libsingular) or \
1247
PY_TYPE_CHECK(ring, NCPolynomialRing_plural)):
1248
raise TypeError("Cannot call Singular function '%s' with ring parameter of type '%s'"%(self._name,type(ring)))
1249
return call_function(self, args, ring, interruptible, attributes)
1250
1251
def _sage_doc_(self):
1252
"""
1253
EXAMPLE::
1254
1255
sage: from sage.libs.singular.function import singular_function
1256
sage: groebner = singular_function('groebner')
1257
sage: 'groebner' in groebner._sage_doc_()
1258
True
1259
"""
1260
1261
prefix = \
1262
"""
1263
This function is an automatically generated C wrapper around the Singular
1264
function '%s'.
1265
1266
This wrapper takes care of converting Sage datatypes to Singular
1267
datatypes and vice versa. In addition to whatever parameters the
1268
underlying Singular function accepts when called this function also
1269
accepts the following keyword parameters:
1270
1271
INPUT:
1272
1273
- ``args`` - a list of arguments
1274
- ``ring`` - a multivariate polynomial ring
1275
- ``interruptible`` - if ``True`` pressing Ctrl-C during the
1276
execution of this function will
1277
interrupt the computation (default: ``True``)
1278
- ``attributes`` - a dictionary of optional Singular
1279
attributes assigned to Singular objects (default: ``None``)
1280
1281
EXAMPLE::
1282
1283
sage: groebner = sage.libs.singular.ff.groebner
1284
sage: P.<x, y> = PolynomialRing(QQ)
1285
sage: I = P.ideal(x^2-y, y+x)
1286
sage: groebner(I)
1287
[x + y, y^2 - y]
1288
1289
sage: triangL = sage.libs.singular.ff.triang__lib.triangL
1290
sage: P.<x1, x2> = PolynomialRing(QQ, order='lex')
1291
sage: f1 = 1/2*((x1^2 + 2*x1 - 4)*x2^2 + 2*(x1^2 + x1)*x2 + x1^2)
1292
sage: f2 = 1/2*((x1^2 + 2*x1 + 1)*x2^2 + 2*(x1^2 + x1)*x2 - 4*x1^2)
1293
sage: I = Ideal(Ideal(f1,f2).groebner_basis()[::-1])
1294
sage: triangL(I, attributes={I:{'isSB':1}})
1295
[[x2^4 + 4*x2^3 - 6*x2^2 - 20*x2 + 5, 8*x1 - x2^3 + x2^2 + 13*x2 - 5],
1296
[x2, x1^2],
1297
[x2, x1^2],
1298
[x2, x1^2]]
1299
1300
The Singular documentation for '%s' is given below.
1301
"""%(self._name,self._name)
1302
# Trac ticket #11268: Include the Singular documentation as a block of code
1303
singular_doc = get_docstring(self._name).split('\n')
1304
return prefix + "\n::\n\n"+'\n'.join([" "+L for L in singular_doc])
1305
1306
cdef common_ring(self, tuple args, ring=None):
1307
"""
1308
Return the common ring for the argument list ``args``.
1309
1310
If ``ring`` is not ``None`` this routine checks whether it is
1311
the parent/ring of all members of ``args`` instead.
1312
1313
If no common ring was found a ``ValueError`` is raised.
1314
1315
INPUT:
1316
1317
- ``args`` - a list of Python objects
1318
- ``ring`` - an optional ring to check
1319
"""
1320
from sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
1321
from sage.matrix.matrix_integer_dense import Matrix_integer_dense
1322
ring2 = None
1323
for a in args:
1324
if PY_TYPE_CHECK(a, MPolynomialIdeal) or \
1325
PY_TYPE_CHECK(a, NCPolynomialIdeal):
1326
ring2 = a.ring()
1327
elif is_singular_poly_wrapper(a):
1328
ring2 = a.parent()
1329
elif is_sage_wrapper_for_singular_ring(a):
1330
ring2 = a
1331
elif PY_TYPE_CHECK(a, int) or\
1332
PY_TYPE_CHECK(a, long) or\
1333
PY_TYPE_CHECK(a, basestring):
1334
continue
1335
elif PY_TYPE_CHECK(a, Matrix_integer_dense):
1336
continue
1337
elif PY_TYPE_CHECK(a, Matrix_mpolynomial_dense):
1338
ring2 = a.base_ring()
1339
elif PY_TYPE_CHECK(a, list) or PY_TYPE_CHECK(a, tuple)\
1340
or PY_TYPE_CHECK(a, Sequence_generic):
1341
#TODO: catch exception, if recursion finds no ring
1342
ring2 = self.common_ring(tuple(a), ring)
1343
elif PY_TYPE_CHECK(a, Resolution):
1344
ring2 = (<Resolution> a).base_ring
1345
elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
1346
and is_sage_wrapper_for_singular_ring(
1347
a.parent().base_ring()):
1348
ring2 = a.parent().base_ring()
1349
elif ring is not None:
1350
a.parent() is ring
1351
continue
1352
1353
if ring is None:
1354
ring = ring2
1355
elif ring is not ring2:
1356
raise ValueError("Rings do not match up.")
1357
if ring is None:
1358
raise ValueError("Could not detect ring.")
1359
return ring
1360
1361
def __reduce__(self):
1362
"""
1363
EXAMPLE::
1364
1365
sage: from sage.libs.singular.function import singular_function
1366
sage: groebner = singular_function('groebner')
1367
sage: groebner == loads(dumps(groebner))
1368
True
1369
"""
1370
return singular_function, (self._name,)
1371
1372
def __cmp__(self, other):
1373
"""
1374
EXAMPLE::
1375
1376
sage: from sage.libs.singular.function import singular_function
1377
sage: groebner = singular_function('groebner')
1378
sage: groebner == singular_function('groebner')
1379
True
1380
sage: groebner == singular_function('std')
1381
False
1382
sage: groebner == 1
1383
False
1384
"""
1385
if not PY_TYPE_CHECK(other, SingularFunction):
1386
return cmp(type(self),type(other))
1387
else:
1388
return cmp(self._name, (<SingularFunction>other)._name)
1389
1390
cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=True, attributes=None):
1391
global currRingHdl
1392
global errorreported
1393
global currentVoice
1394
global myynest
1395
global error_messages
1396
1397
1398
cdef ring *si_ring
1399
if PY_TYPE_CHECK(R, MPolynomialRing_libsingular):
1400
si_ring = (<MPolynomialRing_libsingular>R)._ring
1401
else:
1402
si_ring = (<NCPolynomialRing_plural>R)._ring
1403
1404
if si_ring != currRing: rChangeCurrRing(si_ring)
1405
1406
if currRingHdl.data.uring!= currRing:
1407
currRingHdl.data.uring.ref -= 1
1408
currRingHdl.data.uring = currRing # ref counting?
1409
currRingHdl.data.uring.ref += 1
1410
1411
cdef Converter argument_list = Converter(args, R, attributes)
1412
1413
cdef leftv * _res
1414
1415
currentVoice = NULL
1416
myynest = 0
1417
errorreported = 0
1418
1419
while error_messages:
1420
error_messages.pop()
1421
1422
with opt_ctx: # we are preserving the global options state here
1423
if signal_handler:
1424
sig_on()
1425
_res = self.call_handler.handle_call(argument_list, si_ring)
1426
sig_off()
1427
else:
1428
_res = self.call_handler.handle_call(argument_list, si_ring)
1429
1430
if myynest:
1431
myynest = 0
1432
1433
if currentVoice:
1434
currentVoice = NULL
1435
1436
if errorreported:
1437
errorreported = 0
1438
error_msg = " " + "\n ".join(error_messages)
1439
raise RuntimeError("Error in Singular function call '%s':\n%s"%(self._name,
1440
error_msg))
1441
1442
res = argument_list.to_python(_res)
1443
1444
if self.call_handler.free_res():
1445
free_leftv(_res, si_ring)
1446
else:
1447
_res.CleanUp(si_ring)
1448
1449
return res
1450
1451
cdef class SingularLibraryFunction(SingularFunction):
1452
"""
1453
EXAMPLES::
1454
1455
sage: from sage.libs.singular.function import SingularLibraryFunction
1456
sage: R.<x,y> = PolynomialRing(QQ, order='lex')
1457
sage: I = R.ideal(x, x+1)
1458
sage: f = SingularLibraryFunction("groebner")
1459
sage: f(I)
1460
[1]
1461
"""
1462
def __init__(self, name):
1463
"""
1464
Construct a new Singular kernel function.
1465
1466
EXAMPLES::
1467
1468
sage: from sage.libs.singular.function import SingularLibraryFunction
1469
sage: R.<x,y> = PolynomialRing(QQ, order='lex')
1470
sage: I = R.ideal(x + 1, x*y + 1)
1471
sage: f = SingularLibraryFunction("groebner")
1472
sage: f(I)
1473
[y - 1, x + 1]
1474
"""
1475
super(SingularLibraryFunction,self).__init__(name)
1476
self.call_handler = self.get_call_handler()
1477
1478
cdef BaseCallHandler get_call_handler(self):
1479
cdef idhdl* singular_idhdl = ggetid(self._name)
1480
if singular_idhdl==NULL:
1481
raise NameError("Function '%s' is not defined."%self._name)
1482
if singular_idhdl.typ!=PROC_CMD:
1483
raise ValueError("Not a procedure")
1484
1485
cdef LibraryCallHandler res = LibraryCallHandler()
1486
res.proc_idhdl = singular_idhdl
1487
return res
1488
1489
cdef bint function_exists(self):
1490
cdef idhdl* singular_idhdl = ggetid(self._name)
1491
return singular_idhdl!=NULL
1492
1493
cdef class SingularKernelFunction(SingularFunction):
1494
"""
1495
EXAMPLES::
1496
1497
sage: from sage.libs.singular.function import SingularKernelFunction
1498
sage: R.<x,y> = PolynomialRing(QQ, order='lex')
1499
sage: I = R.ideal(x, x+1)
1500
sage: f = SingularKernelFunction("std")
1501
sage: f(I)
1502
[1]
1503
"""
1504
def __init__(self, name):
1505
"""
1506
Construct a new Singular kernel function.
1507
1508
EXAMPLES::
1509
1510
sage: from sage.libs.singular.function import SingularKernelFunction
1511
sage: R.<x,y> = PolynomialRing(QQ, order='lex')
1512
sage: I = R.ideal(x + 1, x*y + 1)
1513
sage: f = SingularKernelFunction("std")
1514
sage: f(I)
1515
[y - 1, x + 1]
1516
"""
1517
super(SingularKernelFunction,self).__init__(name)
1518
self.call_handler = self.get_call_handler()
1519
1520
cdef BaseCallHandler get_call_handler(self):
1521
cdef int cmd_n = -1
1522
arity = IsCmd(self._name, cmd_n) # call by reverence for CMD_n
1523
if cmd_n == -1:
1524
raise NameError("Function '%s' is not defined."%self._name)
1525
1526
return KernelCallHandler(cmd_n, arity)
1527
1528
cdef bint function_exists(self):
1529
cdef int cmd_n = -1
1530
arity = IsCmd(self._name, cmd_n) # call by reverence for CMD_n
1531
return cmd_n != -1
1532
1533
1534
def singular_function(name):
1535
"""
1536
Construct a new libSingular function object for the given
1537
``name``.
1538
1539
This function works both for interpreter and built-in functions.
1540
1541
INPUT:
1542
1543
- ``name`` - the name of the function
1544
1545
EXAMPLE::
1546
1547
sage: from sage.libs.singular.function import singular_function
1548
sage: P.<x,y,z> = PolynomialRing(QQ)
1549
sage: f = 3*x*y + 2*z + 1
1550
sage: g = 2*x + 1/2
1551
sage: I = Ideal([f,g])
1552
1553
sage: number_foobar = singular_function('number_foobar');
1554
Traceback (most recent call last):
1555
...
1556
NameError: Function 'number_foobar' is not defined.
1557
1558
sage: from sage.libs.singular.function import lib as singular_lib
1559
sage: singular_lib('general.lib')
1560
sage: number_e = singular_function('number_e')
1561
sage: number_e(10r,ring=P)
1562
67957045707/25000000000
1563
sage: RR(number_e(10r,ring=P))
1564
2.71828182828000
1565
1566
sage: std = singular_function("std")
1567
sage: std(I)
1568
[3*y - 8*z - 4, 4*x + 1]
1569
sage: singular_list = singular_function("list")
1570
sage: singular_list(2, 3, 6, ring=P)
1571
[2, 3, 6]
1572
sage: size = singular_function("size")
1573
sage: size([2, 3, 3], ring=P)
1574
3
1575
sage: size("sage", ring=P)
1576
4
1577
sage: size(["hello", "sage"], ring=P)
1578
2
1579
sage: factorize = singular_function("factorize")
1580
sage: factorize(f)
1581
[[1, 3*x*y + 2*z + 1], (1, 1)]
1582
sage: singular_lib('primdec.lib')
1583
sage: primdecGTZ = singular_function("primdecGTZ")
1584
sage: primdecGTZ(I)
1585
[[[y - 8/3*z - 4/3, x + 1/4], [y - 8/3*z - 4/3, x + 1/4]]]
1586
sage: singular_list((1,2,3),3,[1,2,3], ring=P)
1587
[(1, 2, 3), 3, [1, 2, 3]]
1588
sage: ringlist=singular_function("ringlist")
1589
sage: l = ringlist(P)
1590
sage: l[3].__class__
1591
<class 'sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic'>
1592
sage: l
1593
[0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0]]
1594
sage: ring=singular_function("ring")
1595
sage: ring(l, ring=P)
1596
<RingWrap>
1597
sage: matrix = Matrix(P,2,2)
1598
sage: matrix.randomize(terms=1)
1599
sage: det = singular_function("det")
1600
sage: det(matrix)
1601
-3/5*x*y*z
1602
sage: coeffs = singular_function("coeffs")
1603
sage: coeffs(x*y+y+1,y)
1604
[ 1]
1605
[x + 1]
1606
sage: F.<x,y,z> = GF(3)[]
1607
sage: intmat = Matrix(ZZ, 2,2, [100,2,3,4])
1608
sage: det(intmat, ring=F)
1609
394
1610
sage: random = singular_function("random")
1611
sage: A = random(10,2,3, ring =F); A.nrows(), max(A.list()) <= 10
1612
(2, True)
1613
sage: P.<x,y,z> = PolynomialRing(QQ)
1614
sage: M=P**3
1615
sage: leadcoef = singular_function("leadcoef")
1616
sage: v=M((100*x,5*y,10*z*x*y))
1617
sage: leadcoef(v)
1618
10
1619
sage: v = M([x+y,x*y+y**3,z])
1620
sage: lead = singular_function("lead")
1621
sage: lead(v)
1622
(0, y^3)
1623
sage: jet = singular_function("jet")
1624
sage: jet(v, 2)
1625
(x + y, x*y, z)
1626
sage: syz = singular_function("syz")
1627
sage: I = P.ideal([x+y,x*y-y, y*2,x**2+1])
1628
sage: M = syz(I)
1629
sage: M
1630
[(-2*y, 2, y + 1, 0), (0, -2, x - 1, 0), (x*y - y, -y + 1, 1, -y), (x^2 + 1, -x - 1, -1, -x)]
1631
sage: singular_lib("mprimdec.lib")
1632
sage: syz(M)
1633
[(-x - 1, y - 1, 2*x, -2*y)]
1634
sage: GTZmod = singular_function("GTZmod")
1635
sage: GTZmod(M)
1636
[[[(-2*y, 2, y + 1, 0), (0, x + 1, 1, -y), (0, -2, x - 1, 0), (x*y - y, -y + 1, 1, -y), (x^2 + 1, 0, 0, -x - y)], [0]]]
1637
sage: mres = singular_function("mres")
1638
sage: resolution = mres(M, 0)
1639
sage: resolution
1640
<Resolution>
1641
sage: singular_list(resolution)
1642
[[(-2*y, 2, y + 1, 0), (0, -2, x - 1, 0), (x*y - y, -y + 1, 1, -y), (x^2 + 1, -x - 1, -1, -x)], [(-x - 1, y - 1, 2*x, -2*y)], [(0)]]
1643
1644
sage: A.<x,y> = FreeAlgebra(QQ, 2)
1645
sage: P.<x,y> = A.g_algebra({y*x:-x*y})
1646
sage: I= Sequence([x*y,x+y], check=False, immutable=True)
1647
sage: twostd = singular_function("twostd")
1648
sage: twostd(I)
1649
[x + y, y^2]
1650
sage: M=syz(I)
1651
doctest...
1652
sage: M
1653
[(x + y, x*y)]
1654
sage: syz(M, ring=P)
1655
[(0)]
1656
sage: mres(I, 0)
1657
<Resolution>
1658
sage: M=P**3
1659
sage: v=M((100*x,5*y,10*y*x*y))
1660
sage: leadcoef(v)
1661
-10
1662
sage: v = M([x+y,x*y+y**3,x])
1663
sage: lead(v)
1664
(0, y^3)
1665
sage: jet(v, 2)
1666
(x + y, x*y, x)
1667
sage: l = ringlist(P)
1668
sage: len(l)
1669
6
1670
sage: ring(l, ring=P)
1671
<noncommutative RingWrap>
1672
sage: I=twostd(I)
1673
sage: l[3]=I
1674
sage: ring(l, ring=P)
1675
<noncommutative RingWrap>
1676
1677
"""
1678
1679
cdef SingularFunction fnc
1680
try:
1681
return SingularKernelFunction(name)
1682
except NameError:
1683
return SingularLibraryFunction(name)
1684
1685
def lib(name):
1686
"""
1687
Load the Singular library ``name``.
1688
1689
INPUT:
1690
1691
- ``name`` - a Singular library name
1692
1693
EXAMPLE::
1694
1695
sage: from sage.libs.singular.function import singular_function
1696
sage: from sage.libs.singular.function import lib as singular_lib
1697
sage: singular_lib('general.lib')
1698
sage: primes = singular_function('primes')
1699
sage: primes(2,10, ring=GF(127)['x,y,z'])
1700
(2, 3, 5, 7)
1701
"""
1702
global verbose
1703
cdef int vv = verbose
1704
1705
if get_verbose() <= 0:
1706
verbose &= ~Sy_bit(V_LOAD_LIB)
1707
1708
if get_verbose() <= 0:
1709
verbose &= ~Sy_bit(V_REDEFINE)
1710
1711
cdef bint failure = iiLibCmd(omStrDup(name), 1, 1, 1)
1712
verbose = vv
1713
1714
if failure:
1715
raise NameError("Library '%s' not found."%(name,))
1716
1717
1718
1719
def list_of_functions(packages=False):
1720
"""
1721
Return a list of all function names currently available.
1722
1723
INPUT:
1724
1725
- ``packages`` - include local functions in packages.
1726
1727
EXAMPLE::
1728
1729
sage: 'groebner' in sage.libs.singular.function.list_of_functions()
1730
True
1731
"""
1732
cdef list l = []
1733
cdef idhdl *h=IDROOT
1734
cdef idhdl *ph = NULL
1735
while h!=NULL:
1736
if PROC_CMD == IDTYP(h):
1737
l.append(h.id)
1738
if PACKAGE_CMD == IDTYP(h):
1739
if packages:
1740
ph = IDPACKAGE(h).idroot
1741
while ph != NULL:
1742
if PROC_CMD == IDTYP(ph):
1743
l.append(ph.id)
1744
ph = IDNEXT(ph)
1745
h = IDNEXT(h)
1746
return l
1747
1748
1749
#cdef ring*?
1750
cdef inline RingWrap new_RingWrap(ring* r):
1751
cdef RingWrap ring_wrap_result = PY_NEW(RingWrap)
1752
ring_wrap_result._ring = r
1753
ring_wrap_result._ring.ref += 1
1754
1755
return ring_wrap_result
1756
1757