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