Skip to content

Commit

Permalink
Merge pull request #1309 from skirpichev/misc
Browse files Browse the repository at this point in the history
Misc fixes
  • Loading branch information
skirpichev committed Mar 25, 2023
2 parents 1d632ce + 70a688a commit 9a5a5d2
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 29 deletions.
4 changes: 4 additions & 0 deletions .git_archival.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node: $Format:%H$
node-date: $Format:%cI$
describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$
ref-names: $Format:%D$
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
*.yaml text
*.cnf text
*.bib text
.git_archival.txt export-subst
21 changes: 20 additions & 1 deletion diofant/core/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,8 @@ def free_symbols(self):
return self.expr.free_symbols

def _eval_subs(self, old, new):
from .symbol import Dummy

if old in self.variables and not new._diff_wrt:
# issue sympy/sympy#4719
return Subs(self, (old, new))
Expand All @@ -1214,7 +1216,24 @@ def _subset(a, b):
if _subset(old_vars, self_vars):
return Derivative(new, *(self_vars - old_vars).elements())

return Derivative(*(x._subs(old, new) for x in self.args))
args = list(self.args)
newargs = [x._subs(old, new) for x in args]

if newargs[0] != args[0] and not isinstance(old, UndefinedFunction):
# Can't change expr by introducing something that is in
# the variables if it was already in the expr.
# E.g. for Derivative(f(x, g(y)), y), x cannot be replaced with
# anything that has y in it; for f(g(x), g(y)).diff(g(y))
# g(x) cannot be replaced with anything that has g(y).
syms = {vi: Dummy() for vi in self.variables if not vi.is_Symbol}
wrt = {syms.get(vi, vi) for vi in self.variables}
forbidden = args[0].xreplace(syms).free_symbols & wrt
nfree = new.xreplace(syms).free_symbols
ofree = old.xreplace(syms).free_symbols
if (nfree - ofree) & forbidden:
return Subs(self, (old, new))

return Derivative(*newargs)

def _eval_nseries(self, x, n, logx):
arg = self.expr.nseries(x, n, logx)
Expand Down
2 changes: 1 addition & 1 deletion diofant/tests/calculus/test_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def test_leading_order2():


def test_order_leadterm():
assert O(x**2)._eval_as_leading_term(x) == O(x**2)
assert O(x**2).as_leading_term(x) == O(x**2)


def test_order_symbols():
Expand Down
1 change: 0 additions & 1 deletion diofant/tests/core/test_arit.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,6 @@ def test_Mul_is_negative_positive():
assert (-neg).is_negative is False
assert (2*neg).is_negative is True

assert (2*pos)._eval_is_negative() is False
assert (2*pos).is_negative is False

assert pos.is_negative is False
Expand Down
28 changes: 14 additions & 14 deletions diofant/tests/core/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ def test_diff_symbols():
assert diff(f(x, y, z), x, y, (z, 2)) == Derivative(f(x, y, z), x, y, z, z)
assert diff(f(x, y, z), x, y, (z, 2), evaluate=False) == \
Derivative(f(x, y, z), x, y, z, z)
assert Derivative(f(x, y, z), x, y, z)._eval_derivative(z) == \
assert Derivative(f(x, y, z), x, y, z).diff(z) == \
Derivative(f(x, y, z), x, y, z, z)
assert Derivative(Derivative(f(x, y, z), x), y)._eval_derivative(z) == \
assert Derivative(Derivative(f(x, y, z), x), y).diff(z) == \
Derivative(f(x, y, z), x, y, z)


Expand Down Expand Up @@ -398,25 +398,25 @@ def test_function_complex():
def test_function__eval_nseries():
n = Symbol('n')

assert sin(x)._eval_nseries(x, 2, None) == x + O(x**3)
assert sin(x + 1)._eval_nseries(x, 2, None) == x*cos(1) + sin(1) + O(x**2)
assert sin(pi*(1 - x))._eval_nseries(x, 2, None) == pi*x + O(x**3)
assert acos(1 - x**2)._eval_nseries(x, 2, None) == sqrt(2)*x + O(x**2)
assert polygamma(n, x + 1)._eval_nseries(x, 2, None) == \
assert sin(x).series(x, n=3) == x + O(x**3)
assert sin(x + 1).series(x, n=2) == x*cos(1) + sin(1) + O(x**2)
assert sin(pi*(1 - x)).series(x, n=3) == pi*x + O(x**3)
assert acos(1 - x**2).series(x, n=2) == sqrt(2)*x + O(x**2)
assert polygamma(n, x + 1).series(x, n=2) == \
polygamma(n, 1) + polygamma(n + 1, 1)*x + O(x**2)
pytest.raises(PoleError, lambda: sin(1/x)._eval_nseries(x, 2, None))
assert acos(1 - x)._eval_nseries(x, 4, None) == sqrt(2)*sqrt(x) + \
pytest.raises(PoleError, lambda: sin(1/x).series(x, n=2))
assert acos(1 - x).series(x, n=2) == sqrt(2)*sqrt(x) + \
sqrt(2)*x**Rational(3, 2)/12 + O(x**2)
assert acos(1 + x)._eval_nseries(x, 4, None) == sqrt(2)*I*sqrt(x) - \
assert acos(1 + x).series(x, n=2) == sqrt(2)*I*sqrt(x) - \
sqrt(2)*I*x**(3/2)/12 + O(x**2)
assert loggamma(1/x)._eval_nseries(x, 0, None) == O(1/x) - log(x)/x
assert loggamma(1/x).series(x, n=-1) == O(1/x) - log(x)/x
assert loggamma(log(1/x)).series(x, n=1, logx=y) == loggamma(-y)

# issue sympy/sympy#6725:
assert expint(Rational(3, 2), -x)._eval_nseries(x, 8, None) == \
assert expint(Rational(3, 2), -x).series(x, n=5) == \
2 - 2*I*sqrt(pi)*sqrt(x) - 2*x - x**2/3 - x**3/15 - x**4/84 + O(x**5)
assert sin(sqrt(x))._eval_nseries(x, 6, None) == \
sqrt(x) - x**Rational(3, 2)/6 + x**Rational(5, 2)/120 + O(x**Rational(7, 2))
assert sin(sqrt(x)).series(x, n=3) == \
sqrt(x) - x**Rational(3, 2)/6 + x**Rational(5, 2)/120 + O(x**3)


def test_doit():
Expand Down
5 changes: 4 additions & 1 deletion diofant/tests/core/test_subs.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,6 @@ def test_functions_subs():


def test_derivative_subs():
y = Symbol('y')
f = Function('f')
assert Derivative(f(x), x).subs({f(x): y}) != 0
assert Derivative(f(x), x).subs({f(x): y}).subs({y: f(x)}) == \
Expand All @@ -430,6 +429,10 @@ def test_derivative_subs():
assert cse(Derivative(f(x), x) + f(x))[1][0].has(Derivative)
assert cse(Derivative(f(x, y), x) +
Derivative(f(x, y), y))[1][0].has(Derivative)
# issue diofant/diofant#1303
g = Function('g')
d = f(x, y, z).diff(x)
assert d.subs({y: g(x, z)}) == Subs(d, (y, g(x, z)))


def test_derivative_subs2():
Expand Down
14 changes: 7 additions & 7 deletions diofant/tests/functions/test_gamma_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,13 +399,13 @@ def test_loggamma():
assert loggamma(w).is_extended_real is None

def tN(N, M):
assert loggamma(1/x)._eval_nseries(x, N, None).getn() == M
tN(0, -1)
tN(1, +1)
tN(2, +3)
tN(3, +3)
tN(4, +5)
tN(5, +5)
assert loggamma(1/x).series(x, n=N).getn() == M
tN(-1, -1)
tN(1, 1)
tN(2, 2)
tN(3, 3)
tN(4, 4)
tN(5, 5)


def test_polygamma_expansion():
Expand Down
8 changes: 4 additions & 4 deletions diofant/tests/simplify/test_simplify.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ def test_simplify_other():


def test_simplify_complex():
cosAsExp = cos(x)._eval_rewrite_as_exp(x)
tanAsExp = tan(x)._eval_rewrite_as_exp(x)
assert simplify(cosAsExp*tanAsExp).expand() == (
sin(x))._eval_rewrite_as_exp(x).expand() # issue sympy/sympy#4341
cosAsExp = cos(x).rewrite(exp)
tanAsExp = tan(x).rewrite(exp)
# issue sympy/sympy#4341
assert simplify(cosAsExp*tanAsExp).expand() == sin(x).rewrite(exp).expand()


def test_simplify_ratio():
Expand Down
18 changes: 18 additions & 0 deletions diofant/tests/solvers/test_ode.py
Original file line number Diff line number Diff line change
Expand Up @@ -3047,3 +3047,21 @@ def test_sympyissue_23562():
def test_sympyissue_23702():
assert dsolve(f(x).diff(x) - f(x), f(x),
init={f(0): f(0)}) == Eq(f(x), f(0)*exp(x))


def test_sympyissue_24957():
eq = (2*x**3 + 3*f(x)) + (3*x + f(x) - 1)*f(x).diff(x)
assert dsolve(eq) == [Eq(f(x), -3*x - sqrt(C1 - x**4 + 9*x**2 - 6*x) + 1),
Eq(f(x), -3*x + sqrt(C1 - x**4 + 9*x**2 - 6*x) + 1)]


def test_sympyissue_24955():
eq = x**2*f(x).diff(x) - f(x)**2*f(x).diff(x) + 2*x*f(x)
assert dsolve(eq) == [Eq(f(x), root(2, 3)*(-x**2/root(3*C1 + sqrt(9*C1**2 - 4*x**6), 3) -
root(2, 3)*root(3*C1 + sqrt(9*C1**2 - 4*x**6), 3)/2)),
Eq(f(x), root(2, 3)*(2*x**2/((1 + sqrt(3)*I)*root(3*C1 + sqrt(9*C1**2 - 4*x**6), 3)) +
root(2, 3)*root(3*C1 + sqrt(9*C1**2 - 4*x**6), 3)/4 +
root(2, 3)*sqrt(3)*I*root(3*C1 + sqrt(9*C1**2 - 4*x**6), 3)/4)),
Eq(f(x), root(2, 3)*(-2*x**2/((-1 + sqrt(3)*I)*root(3*C1 + sqrt(9*C1**2 - 4*x**6), 3)) +
root(2, 3)*root(3*C1 + sqrt(9*C1**2 - 4*x**6), 3)/4 -
root(2, 3)*sqrt(3)*I*root(3*C1 + sqrt(9*C1**2 - 4*x**6), 3)/4))]
2 changes: 2 additions & 0 deletions docs/release/notes-0.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,5 @@ These Sympy issues also were addressed:
* :sympyissue:`24477`: Expand before integrate gives different results with big O
* :sympyissue:`24928`: simplify(asinh(2)-oo)->0
* :sympyissue:`24948`: .is_positive returns None when it should be False
* :sympyissue:`24957`: Timeout for dsolve((2x^3+3y)+(3x+y-1)y'=0)
* :sympyissue:`24955`: Timeout for dsolve(x^2*y'-y^2*y'+2*x*y=0)

0 comments on commit 9a5a5d2

Please sign in to comment.