GitLab's annual major release is around the corner. Along with a lot of new and exciting features, there will be a few breaking changes. Learn more here.

Commits (5)
......@@ -5024,6 +5024,10 @@ cdef class Expression(CommutativeRingElement):
"""
Substitute the given subexpressions in this expression.
GiNaC supports several options that can be set with the
integer ``flags`` keyword (default: `0`). The value `1`
sets patternless subtitution.
EXAMPLES::
sage: var('x,y,z,a,b,c,d,f,g')
......@@ -5261,6 +5265,15 @@ cdef class Expression(CommutativeRingElement):
x^2 + 1/x
sage: (sqrt(x) + 1/sqrt(x)).subs({x: 1/x})
sqrt(x) + 1/sqrt(x)
Replacing a wildcard needs patternless substitution::
sage: w1 = SR.wild(1)
sage: sin(w1).subs(w1==x)
x
sage: w1 = SR.wild(1)
sage: sin(w1).subs(w1==x, flags=1)
sin(x)
"""
cdef dict sdict = {}
cdef GEx res
......@@ -5275,11 +5288,13 @@ cdef class Expression(CommutativeRingElement):
for a in args:
_dict_update_check_duplicate(sdict, _subs_make_dict(a))
cdef int flags = 0
if kwds:
# Ensure that the keys are symbolic variables.
varkwds = {self._parent.var(k): v for k,v in kwds.iteritems()}
# Check for duplicate
_dict_update_check_duplicate(sdict, varkwds)
flags = kwds.get('flags', 0)
cdef GExMap smap
for k, v in sdict.iteritems():
......@@ -5287,7 +5302,7 @@ cdef class Expression(CommutativeRingElement):
(<Expression>self.coerce_in(v))._gobj))
sig_on()
try:
res = self._gobj.subs_map(smap, 0)
res = self._gobj.subs_map(smap, flags)
finally:
sig_off()
return new_Expression_from_GEx(self._parent, res)
......
"""
EXAMPLES::
sage: var('a b c d e f k m n p s t y')
(a, b, c, d, e, f, k, m, n, p, s, t, y)
sage: w0=SR.wild(0); w1=SR.wild(1); w2=SR.wild(2); w3=SR.wild(3)
sage: w4=SR.wild(4); w5=SR.wild(5); w6=SR.wild(6); w7=SR.wild(7)
sage: (sqrt(c+x)*c).match(w0 * sqrt(w0+w1))
{$0: c, $1: x}
sage: (sqrt(c+x)*c).match(w1 * sqrt(w0+w1))
{$0: x, $1: c}
sage: (sqrt(c+x)*x).match(w0 * sqrt(w0+w1))
{$0: x, $1: c}
sage: (sqrt(c+x)*x).match(w1 * sqrt(w0+w1))
{$0: c, $1: x}
sage: def check(s, p):
....: m = s.match(p)
....: if (m and (p.subs(m, flags=1) - s).is_trivial_zero()):
....: return True
....: return False
sage: assert check((a+b)*(a+c), (w0+w1)*(w0+w2))
sage: assert check((a+b)*(a+c), (w0+w1)*(w1+w2))
sage: assert check((c+b)*(a+c), (w0+w1)*(w0+w2))
sage: assert check((c+b)*(a+c), (w0+w1)*(w1+w2))
sage: assert check((a+b)^(a+c), (w0+w1)^(w0+w2))
sage: assert check((a+b)^(a+c), (w0+w1)^(w1+w2))
sage: assert check((c+b)^(a+c), (w0+w1)^(w0+w2))
sage: assert check((c+b)^(a+c), (w0+w1)^(w1+w2))
sage: assert check((a^b)^(a+c), (w0^w1)^(w0+w2))
sage: assert not check((a^b)^(a+c), (w0^w1)^(w1+w2))
sage: assert check((c^b)^(a+c), (w0^w1)^(w0+w2))
sage: assert not check((c^b)^(a+c), (w0^w1)^(w1+w2))
sage: assert check (hypergeometric((a+c,b+c), (c,d), x),
....: hypergeometric((w0+w2,w1+w2), (w2,w3), x))
sage: assert not check (hypergeometric((a+c,b+c), (c,d), x),
....: hypergeometric((w0+w1,w1+w2), (w2,w3), x))
sage: assert check(((a+b+1)*(a+b+2))*b, w1*((w0+w1+w2)*(w0+w1+w3)))
sage: assert check(((a+b+1)*(a+b+2))*b, w0*((w0+w1+w2)*(w0+w1+w3)))
sage: assert check(((a+b+1)*(a+b+2))*a, w1*((w0+w1+w2)*(w0+w1+w3)))
sage: assert check(((a+b+1)*(a+b+2))*a, w0*((w0+w1+w2)*(w0+w1+w3)))
sage: assert check(((a+b+1)*(a+b+2))*b, w4*((w4+w1+w2)*(w4+w1+w3)))
sage: assert check(((a+b+1)*(a+b+2))*a, w4*((w4+w1+w2)*(w4+w1+w3)))
sage: assert check((a*b*c+b*c*d+c*d*e)*(b*c*e+c*d*f+d*e*f),
....: (w0*w2*w4+w4*w3*w1+w2*w4*w3)*(w4*w1*w2+w3*w1*w5+w3*w4*w5))
sage: assert check((a*b*d+b*c*d+c*d*e)*(b*c*e+c*d*f+d*e*f),
....: (w0*w2*w4+w4*w3*w1+w2*w4*w3)*(w2*w3*w1+w3*w4*w5+w4*w1*w5))
sage: assert check((a*b*d+b*c*d+c*d*e)*(b*c*a+b*d*f+d*a*f),
....: (w0*w2*w4+w4*w3*w1+w2*w4*w3)*(w2*w3*w1+w3*w4*w5+w4*w1*w5))
"""