@@ -2077,30 +2077,30 @@ cdef class MPolynomial_libsingular(MPolynomial):
2077
2077
raise TypeError (" number of arguments does not match number of variables in parent" )
2078
2078
2079
2079
try :
2080
- # Attempt evaluation via singular.
2081
2080
coerced_x = [parent.coerce(e) for e in x]
2082
2081
except TypeError :
2083
- # give up, evaluate functional
2082
+ # give up, evaluate symbolically
2084
2083
y = parent.base_ring().zero()
2085
- for (m,c) in self .dict().iteritems():
2086
- y += c* mul([ x[i]** m[i] for i in m.nonzero_positions()])
2084
+ for m, c in self .dict().iteritems():
2085
+ y += c * mul([x[i]** m[i] for i in m.nonzero_positions()])
2087
2086
return y
2088
2087
2089
- cdef poly * res # ownership will be transferred to us in the next line
2090
- singular_polynomial_call(& res, self ._poly, _ring, coerced_x, MPolynomial_libsingular_get_element)
2088
+ cdef poly * _res # contains the substituted polynomial
2089
+ singular_polynomial_call(& _res, self ._poly, _ring, coerced_x, MPolynomial_libsingular_get_element)
2090
+
2091
2091
res_parent = coercion_model.common_parent(parent._base, * x)
2092
2092
2093
- if res == NULL :
2093
+ if _res == NULL :
2094
2094
return res_parent(0 )
2095
- if p_LmIsConstant(res , _ring):
2096
- sage_res = si2sa( p_GetCoeff(res , _ring), _ring, parent._base )
2097
- p_Delete(& res , _ring) # sage_res contains copy
2095
+ if p_LmIsConstant(_res , _ring):
2096
+ res = si2sa(p_GetCoeff(_res , _ring), _ring, parent._base)
2097
+ p_Delete(& _res , _ring) # sage to delete; res contains copy
2098
2098
else :
2099
- sage_res = new_MP(parent, res) # pass on ownership of res to sage_res
2099
+ res = new_MP(parent, _res)
2100
2100
2101
- if parent(sage_res ) is not res_parent:
2102
- sage_res = res_parent(sage_res )
2103
- return sage_res
2101
+ if parent(res ) is not res_parent:
2102
+ res = res_parent(res )
2103
+ return res
2104
2104
2105
2105
def __hash__ (self ):
2106
2106
"""
@@ -3391,8 +3391,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
3391
3391
- ``fixed`` - (optional) dict with variable:value pairs
3392
3392
- ``**kw`` - names parameters
3393
3393
3394
- OUTPUT:
3395
- a new multivariate polynomial
3394
+ OUTPUT: a new multivariate polynomial
3396
3395
3397
3396
EXAMPLES::
3398
3397
@@ -3452,7 +3451,7 @@ cdef class MPolynomial_libsingular(MPolynomial):
3452
3451
3453
3452
sage: P = QQ['x,y']
3454
3453
sage: x = var('x')
3455
- sage: parent(P.zero() / x )
3454
+ sage: parent(P.zero().subs(x=x) )
3456
3455
Symbolic Ring
3457
3456
3458
3457
We are catching overflows::
@@ -3503,163 +3502,122 @@ cdef class MPolynomial_libsingular(MPolynomial):
3503
3502
c*x^2*y + d*x^2 + (2*c)*x*y + (2*d)*x + c*y + d
3504
3503
3505
3504
"""
3506
- cdef int mi, i, need_map, try_symbolic
3505
+ cdef int mi, i
3506
+ cdef bint change_ring = False # indicates the need to change the parent ring
3507
+ cdef bint need_map = False
3507
3508
3508
3509
cdef unsigned long degree = 0
3509
3510
cdef MPolynomialRing_libsingular parent = self ._parent
3510
3511
cdef ring * _ring = parent._ring
3511
3512
3512
- if (_ring != currRing): rChangeCurrRing(_ring)
3513
+ if (_ring != currRing):
3514
+ rChangeCurrRing(_ring)
3513
3515
3514
3516
cdef poly * _p = p_Copy(self ._poly, _ring)
3515
3517
cdef poly * _f
3516
3518
3517
- cdef ideal * to_id = idInit(_ring.N,1 )
3519
+ cdef ideal * to_id = idInit(_ring.N, 1 )
3518
3520
cdef ideal * from_id
3519
3521
cdef ideal * res_id
3520
- need_map = 0
3521
- try_symbolic = 0
3522
+ cdef dict gd
3522
3523
3523
- if _p == NULL :
3524
- # the polynomial is 0. There is nothing to do except to change the
3525
- # ring
3526
- try_symbolic = 1
3527
-
3528
- if not try_symbolic and fixed is not None :
3529
- for m,v in fixed.items():
3530
- if isinstance (m, (int , Integer)):
3531
- mi = m+ 1
3532
- elif isinstance (m,MPolynomial_libsingular) and m.parent() is parent:
3533
- for i from 0 < i <= _ring.N:
3534
- if p_GetExp((< MPolynomial_libsingular> m)._poly, i, _ring) != 0 :
3535
- mi = i
3536
- break
3537
- if i > _ring.N:
3538
- id_Delete(& to_id, _ring)
3539
- p_Delete(& _p, _ring)
3540
- raise TypeError (" key does not match" )
3541
- else :
3542
- id_Delete(& to_id, _ring)
3543
- p_Delete(& _p, _ring)
3544
- raise TypeError (" keys do not match self's parent" )
3545
- try :
3546
- v = parent.coerce(v)
3547
- except TypeError :
3548
- try_symbolic = 1
3549
- break
3550
- _f = (< MPolynomial_libsingular> v)._poly
3551
- if p_IsConstant(_f, _ring):
3552
- singular_polynomial_subst(& _p, mi- 1 , _f, _ring)
3553
- else :
3554
- need_map = 1
3555
- degree = < unsigned long > p_GetExp(_p, mi, _ring) * < unsigned long > p_GetMaxExp(_f, _ring)
3556
- if degree > _ring.bitmask:
3524
+ cdef list g = list (parent.gens())
3525
+ cdef list items = []
3526
+
3527
+ if not change_ring:
3528
+ if fixed is not None :
3529
+ for m, v in fixed.items():
3530
+ if isinstance (m, (int , Integer)):
3531
+ mi = m + 1
3532
+ elif isinstance (m, MPolynomial_libsingular) and m.parent() is parent:
3533
+ for i from 0 < i <= _ring.N:
3534
+ if p_GetExp((< MPolynomial_libsingular> m)._poly, i, _ring) != 0 :
3535
+ mi = i
3536
+ break
3537
+ if i > _ring.N:
3538
+ id_Delete(& to_id, _ring)
3539
+ p_Delete(& _p, _ring)
3540
+ raise TypeError (" key does not match" )
3541
+ else :
3557
3542
id_Delete(& to_id, _ring)
3558
3543
p_Delete(& _p, _ring)
3559
- raise OverflowError (" exponent overflow (%d )" % (degree))
3560
- to_id.m[mi- 1 ] = p_Copy(_f, _ring)
3561
-
3544
+ raise TypeError (" keys do not match self's parent" )
3545
+
3546
+ items.append((g[mi - 1 ], v))
3547
+ if kw:
3548
+ gd = parent.gens_dict(copy = False )
3549
+ for m, v in kw.items():
3550
+ items.append((gd[m], v))
3551
+ for m, v in items:
3562
3552
if _p == NULL :
3563
- # polynomial becomes 0 after some substitution
3564
- try_symbolic = 1
3553
+ change_ring = True
3565
3554
break
3566
-
3567
- cdef dict gd
3568
-
3569
- if not try_symbolic:
3570
- gd = parent.gens_dict(copy = False )
3571
- for m,v in kw.iteritems():
3572
- m = gd[m]
3573
- for i from 0 < i <= _ring.N:
3574
- if p_GetExp((< MPolynomial_libsingular> m)._poly, i, _ring) != 0 :
3575
- mi = i
3576
- break
3577
- if i > _ring.N:
3578
- id_Delete(& to_id, _ring)
3579
- p_Delete(& _p, _ring)
3580
- raise TypeError (" key does not match" )
3555
+ i = g.index(m)
3581
3556
try :
3582
3557
v = parent.coerce(v)
3583
- except TypeError :
3584
- try_symbolic = 1
3585
- break
3586
- _f = (< MPolynomial_libsingular> v)._poly
3558
+ except TypeError : # give up, evaluate symbolically
3559
+ id_Delete(& to_id, _ring)
3560
+ p_Delete(& _p, _ring)
3561
+
3562
+ gg = list (parent.gens())
3563
+ for m, v in items:
3564
+ gg[g.index(m)] = v
3565
+ y = parent.base_ring().zero()
3566
+ for (m,c) in self .dict().items():
3567
+ y += c* mul([ gg[i]** m[i] for i in m.nonzero_positions()])
3568
+ return y
3569
+ _f = (< MPolynomial_libsingular> v)._poly
3587
3570
if p_IsConstant(_f, _ring):
3588
- singular_polynomial_subst(& _p, mi - 1 , _f, _ring)
3571
+ singular_polynomial_subst(& _p, i , _f, _ring)
3589
3572
else :
3590
- if to_id.m[mi- 1 ] != NULL :
3591
- p_Delete(& to_id.m[mi- 1 ],_ring)
3592
- to_id.m[mi- 1 ] = p_Copy(_f, _ring)
3593
- degree = < unsigned long > p_GetExp(_p, mi, _ring) * < unsigned long > p_GetMaxExp(_f, _ring)
3594
- if degree > _ring.bitmask:
3573
+ need_map = True
3574
+ degree = (< unsigned long > p_GetExp(_p, i + 1 , _ring)) * (< unsigned long > p_GetMaxExp(_f, _ring))
3575
+ if degree > _ring.bitmask:
3595
3576
id_Delete(& to_id, _ring)
3596
3577
p_Delete(& _p, _ring)
3597
- raise OverflowError (" exponent overflow (%d )" % (degree))
3598
- need_map = 1
3599
-
3600
- if _p == NULL :
3601
- # the polynomial is 0
3602
- try_symbolic = 1
3603
- break
3578
+ raise OverflowError (" exponent overflow (%d )" % (degree,))
3579
+ to_id.m[i] = p_Copy(_f, _ring)
3604
3580
3605
- if need_map:
3606
- for mi from 0 <= mi < _ring.N:
3607
- if to_id.m[mi] == NULL :
3608
- to_id.m[mi] = p_ISet(1 ,_ring)
3609
- p_SetExp(to_id.m[mi], mi+ 1 , 1 , _ring)
3610
- p_Setm(to_id.m[mi], _ring)
3581
+ if not change_ring and need_map:
3582
+ for mi from 0 <= mi < _ring.N:
3583
+ if to_id.m[mi] == NULL :
3584
+ to_id.m[mi] = p_ISet(1 ,_ring)
3585
+ p_SetExp(to_id.m[mi], mi + 1 , 1 , _ring)
3586
+ p_Setm(to_id.m[mi], _ring)
3611
3587
3612
- from_id= idInit(1 ,1 )
3613
- from_id.m[0 ] = _p
3588
+ from_id = idInit(1 , 1 )
3589
+ from_id.m[0 ] = _p
3614
3590
3615
- rChangeCurrRing(_ring)
3616
- res_id = fast_map_common_subexp(from_id, _ring, to_id, _ring)
3617
- _p = res_id.m[0 ]
3591
+ rChangeCurrRing(_ring)
3592
+ res_id = fast_map_common_subexp(from_id, _ring, to_id, _ring)
3593
+ _p = res_id.m[0 ]
3618
3594
3619
- from_id.m[0 ] = NULL
3620
- res_id.m[0 ] = NULL
3595
+ from_id.m[0 ] = NULL
3596
+ res_id.m[0 ] = NULL
3621
3597
3622
- id_Delete(& from_id, _ring)
3623
- id_Delete(& res_id, _ring)
3598
+ id_Delete(& from_id, _ring)
3599
+ id_Delete(& res_id, _ring)
3624
3600
3625
3601
id_Delete(& to_id, _ring)
3626
3602
3627
- if not try_symbolic :
3603
+ if not change_ring :
3628
3604
return new_MP(parent,_p)
3629
3605
3630
- # now as everything else failed, try to do it symbolically with call
3631
-
3632
- cdef list g = list (parent.gens())
3633
-
3634
- if fixed is not None :
3635
- for m,v in fixed.items():
3636
- if isinstance (m, (int , Integer)):
3637
- mi = m+ 1
3638
- elif isinstance (m, MPolynomial_libsingular) and m.parent() is parent:
3639
- for i from 0 < i <= _ring.N:
3640
- if p_GetExp((< MPolynomial_libsingular> m)._poly, i, _ring) != 0 :
3641
- mi = i
3642
- break
3643
- if i > _ring.N:
3644
- raise TypeError (" key does not match" )
3645
- else :
3646
- raise TypeError (" keys do not match self's parent" )
3606
+ # finally change the parent of the result
3647
3607
3648
- g[mi - 1 ] = v
3608
+ res_parent = coercion_model.common_parent(parent._base, * [v for _, v in items])
3649
3609
3650
- gd = parent.gens_dict(copy = False )
3651
- for m,v in kw.iteritems():
3652
- m = gd[m]
3653
- for i from 0 < i <= _ring.N:
3654
- if p_GetExp((< MPolynomial_libsingular> m)._poly, i, _ring) != 0 :
3655
- mi = i
3656
- break
3657
- if i > _ring.N:
3658
- raise TypeError (" key does not match" )
3659
-
3660
- g[mi- 1 ] = v
3610
+ if _p == NULL :
3611
+ return res_parent(0 )
3661
3612
3662
- return self (* g)
3613
+ if p_LmIsConstant(_p, _ring):
3614
+ res = si2sa(p_GetCoeff(_p, _ring), _ring, parent._base)
3615
+ p_Delete(& _p, _ring) # safe to delete; res contains copy
3616
+ else :
3617
+ res = new_MP(parent, _p)
3618
+ if parent(res) is not res_parent:
3619
+ res = res_parent(res)
3620
+ return res
3663
3621
3664
3622
def monomials (self ):
3665
3623
"""
0 commit comments