Correct evaluation for inverse trig/hyperbolic functions at infinity#1396
Closed
skirpichev wants to merge 5 commits intodiofant:masterfrom
Closed
Correct evaluation for inverse trig/hyperbolic functions at infinity#1396skirpichev wants to merge 5 commits intodiofant:masterfrom
skirpichev wants to merge 5 commits intodiofant:masterfrom
Conversation
4c41584 to
ea520f0
Compare
Member
Author
|
Now for inverse functions with infinite components: script a.pyfrom diofant import *
cases = [oo, -oo, I*oo, -I*oo, oo - I*oo, oo + I*oo,
-oo - I*oo, -oo + I*oo]
bad = 0
for f in [asin, acos, asec, acsc, asinh, acosh, atan, acot, atanh, acoth]:
for a in cases:
if f(a, evaluate=False).evalf() != f(a, evaluate=True).evalf():
bad += 1
print(f, a)
print(f"Bad cases: {bad}") |
9de3cfe to
7c97faf
Compare
1c56ae9 to
4e3bcb0
Compare
Without this evalf() produces different results for evaluated and not
evaluated expressions. Also, eval() results differ from numeric
libraries:
In [2]: asin(+oo, evaluate=False).evalf()
Out[2]: 1.5707963267949 - inf⋅ⅈ
In [3]: asin(+oo, evaluate=True).evalf()
Out[3]: -inf⋅ⅈ
In [4]: cmath.asin(complex('(inf-0j)'))
Out[4]: (1.5707963267948966-infj)
Rewrite rules also break evaluation:
In [5]: asin(oo, evaluate=False).rewrite(acos)
Out[5]:
π
─ - ∞⋅ⅈ
2
Old evaluation rules are fine for Mathematica, which has either
DirectedInfinity or ComplexInfinity:
In[1]:= Infinity + I
Out[1]= Infinity
But in the Diofant:
In [6]: oo + I
Out[6]: ∞ + ⅈ
4e3bcb0 to
2441272
Compare
Member
Author
|
With #1404: script a.pyfrom diofant import *
x = symbols('x')
funcs = [cos, sin, tan, cot, csc, sec, acos, asin, atan, acot, acsc, asec,
cosh, sinh, tanh, coth, csch, sech, acosh, asinh, atanh, acoth]
# acsch, asech]
points = [oo, -oo, I*oo, -I*oo]
bad = 0
total = 0
for f1 in funcs:
for f2 in funcs:
total += 1
expr1 = f1(x)
expr2 = expr1.rewrite(f2)
fine = True
for p in points:
val1 = expr1.subs({x: p}).evalf()
try:
val2 = expr2.subs({x: p}).evalf()
test = val1 != val2
except:
test = True
if test:
if expr1.limit(x, p).evalf() == expr2.limit(x, p).evalf():
continue
print()
pprint((f1, f2, p))
pprint((expr1, ' --> ', expr2))
fine = False
if not fine:
bad += 1
print(bad, 'bad rewrites out of', total) |
Member
Author
|
Another series of bulk tests: script c.pyimport numpy as np
from diofant import *
x = symbols('x')
funcs = [cos, sin, tan, cot , csc , sec , acos, asin, atan, acot , acsc , asec,
cosh, sinh, tanh, coth, csch, sech, acosh, asinh, atanh, acoth]
numtests = 10
std = 10
normal = np.random.randn
points_real = std*normal(numtests)
points_complex = std*(normal(numtests) + normal(numtests)*1j)
points = ([Float(_, dps=60) for _ in points_real] +
[Float(_.real, dps=60) + I*Float(_.imag, dps=60) for _ in points_complex])
def isclose(n1, n2):
try:
return bool(abs(n1 - n2)/(abs(n1) + abs(n2)) < 1e-5)
except TypeError:
return False
bad = 0
total = 0
for f1 in funcs:
for f2 in funcs:
total += 1
expr1 = f1(x)
expr2 = expr1.rewrite(f2)
fine = True
for p in points:
val1 = expr1.subs({x:p}).evalf(strict=False)
val2 = expr2.subs({x:p}).evalf(strict=False)
if not isclose(val1, val2):
print()
print(f1, f2, p)
print(expr1, ' --> ', expr2)
print(val1, val2)
fine = False
if not fine:
bad += 1
print(bad, 'bad rewrites out of', total) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Without this evalf() produces different results for evaluated and not evaluated expressions. Also, eval() results differ from numeric libraries:
Rewrite rules also break evaluation:
Old evaluation rules are fine for Mathematica, which has either DirectedInfinity or ComplexInfinity:
But in the Diofant: