def real(self, nested_scope=None):
"""Return the correspond floating point number."""
op = self.children[0].name
expr = self.children[1]
dispatch = {
'sin': sympy.sin,
'cos': sympy.cos,
'tan': sympy.tan,
'asin': sympy.asin,
'acos': sympy.acos,
'atan': sympy.atan,
'exp': sympy.exp,
'ln': sympy.log,
'sqrt': sympy.sqrt
}
if op in dispatch:
arg = expr.real(nested_scope)
return dispatch[op](arg)
else:
raise NodeException("internal error: undefined external")
python类atan()的实例源码
def sym(self, nested_scope=None):
"""Return the corresponding symbolic expression."""
op = self.children[0].name
expr = self.children[1]
dispatch = {
'sin': sympy.sin,
'cos': sympy.cos,
'tan': sympy.tan,
'asin': sympy.asin,
'acos': sympy.acos,
'atan': sympy.atan,
'exp': sympy.exp,
'ln': sympy.log,
'sqrt': sympy.sqrt
}
if op in dispatch:
arg = expr.sym(nested_scope)
return dispatch[op](arg)
else:
raise NodeException("internal error: undefined external")
def test_callback_factory__broadcast():
args = x, y = symbols('x y')
expr = x + atan(y)
cb = _callback_factory(args, [expr], 'numpy', np.float64, 'C')
inp = np.array([[17, 1], [18, 2]])
ref = [17 + np.arctan(1), 18 + np.arctan(2)]
assert np.allclose(cb(inp), ref)
inp2 = np.array([
[[17, 1], [18, 2]],
[[27, 21], [28, 22]]
])
ref2 = [
[17 + np.arctan(1), 18 + np.arctan(2)],
[27 + np.arctan(21), 28 + np.arctan(22)]
]
assert np.allclose(cb(inp2), ref2)
def eval(cls, arg):
from sympy import exp_polar, pi, I, arg as argument
if arg.is_number:
ar = argument(arg)
#if not ar.has(argument) and not ar.has(atan):
if ar in (0, pi/2, -pi/2, pi):
return exp_polar(I*ar)*abs(arg)
if arg.is_Mul:
args = arg.args
else:
args = [arg]
included = []
excluded = []
positive = []
for arg in args:
if arg.is_polar:
included += [arg]
elif arg.is_positive:
positive += [arg]
else:
excluded += [arg]
if len(excluded) < len(args):
if excluded:
return Mul(*(included + positive))*polar_lift(Mul(*excluded))
elif included:
return Mul(*(included + positive))
else:
return Mul(*positive)*exp_polar(0)
def eval(cls, ar, period):
# Our strategy is to evaluate the argument on the riemann surface of the
# logarithm, and then reduce.
# NOTE evidently this means it is a rather bad idea to use this with
# period != 2*pi and non-polar numbers.
from sympy import ceiling, oo, atan2, atan, polar_lift, pi, Mul
if not period.is_positive:
return None
if period == oo and isinstance(ar, principal_branch):
return periodic_argument(*ar.args)
if ar.func is polar_lift and period >= 2*pi:
return periodic_argument(ar.args[0], period)
if ar.is_Mul:
newargs = [x for x in ar.args if not x.is_positive]
if len(newargs) != len(ar.args):
return periodic_argument(Mul(*newargs), period)
unbranched = cls._getunbranched(ar)
if unbranched is None:
return None
if unbranched.has(periodic_argument, atan2, arg, atan):
return None
if period == oo:
return unbranched
if period != oo:
n = ceiling(unbranched/period - S(1)/2)*period
if not n.has(ceiling):
return unbranched - n
def test_issue_5414():
assert ratint(1/(x**2 + 16), x) == atan(x/4)/4
def test_issue_5817():
a, b, c = symbols('a,b,c', positive=True)
assert simplify(ratint(a/(b*c*x**2 + a**2 + b*a), x)) == \
sqrt(a)*atan(sqrt(
b)*sqrt(c)*x/(sqrt(a)*sqrt(a + b)))/(sqrt(b)*sqrt(c)*sqrt(a + b))
def test_issue_5981():
u = symbols('u')
assert integrate(1/(u**2 + 1)) == atan(u)
def eval_arctan(integrand, symbol):
return sympy.atan(symbol)
def eval_trigsubstitution(theta, func, rewritten, substep, integrand, symbol):
func = func.subs(sympy.sec(theta), 1/sympy.cos(theta))
trig_function = list(func.find(TrigonometricFunction))
assert len(trig_function) == 1
trig_function = trig_function[0]
relation = sympy.solve(symbol - func, trig_function)
assert len(relation) == 1
numer, denom = sympy.fraction(relation[0])
if isinstance(trig_function, sympy.sin):
opposite = numer
hypotenuse = denom
adjacent = sympy.sqrt(denom**2 - numer**2)
inverse = sympy.asin(relation[0])
elif isinstance(trig_function, sympy.cos):
adjacent = numer
hypotenuse = denom
opposite = sympy.sqrt(denom**2 - numer**2)
inverse = sympy.acos(relation[0])
elif isinstance(trig_function, sympy.tan):
opposite = numer
adjacent = denom
hypotenuse = sympy.sqrt(denom**2 + numer**2)
inverse = sympy.atan(relation[0])
substitution = [
(sympy.sin(theta), opposite/hypotenuse),
(sympy.cos(theta), adjacent/hypotenuse),
(sympy.tan(theta), opposite/adjacent),
(theta, inverse)
]
return _manualintegrate(substep).subs(substitution).trigsimp()
def eval(cls, arg):
from sympy import exp_polar, pi, I, arg as argument
if arg.is_number:
ar = argument(arg)
# In general we want to affirm that something is known,
# e.g. `not ar.has(argument) and not ar.has(atan)`
# but for now we will just be more restrictive and
# see that it has evaluated to one of the known values.
if ar in (0, pi/2, -pi/2, pi):
return exp_polar(I*ar)*abs(arg)
if arg.is_Mul:
args = arg.args
else:
args = [arg]
included = []
excluded = []
positive = []
for arg in args:
if arg.is_polar:
included += [arg]
elif arg.is_positive:
positive += [arg]
else:
excluded += [arg]
if len(excluded) < len(args):
if excluded:
return Mul(*(included + positive))*polar_lift(Mul(*excluded))
elif included:
return Mul(*(included + positive))
else:
return Mul(*positive)*exp_polar(0)
def eval(cls, ar, period):
# Our strategy is to evaluate the argument on the Riemann surface of the
# logarithm, and then reduce.
# NOTE evidently this means it is a rather bad idea to use this with
# period != 2*pi and non-polar numbers.
from sympy import ceiling, oo, atan2, atan, polar_lift, pi, Mul
if not period.is_positive:
return None
if period == oo and isinstance(ar, principal_branch):
return periodic_argument(*ar.args)
if ar.func is polar_lift and period >= 2*pi:
return periodic_argument(ar.args[0], period)
if ar.is_Mul:
newargs = [x for x in ar.args if not x.is_positive]
if len(newargs) != len(ar.args):
return periodic_argument(Mul(*newargs), period)
unbranched = cls._getunbranched(ar)
if unbranched is None:
return None
if unbranched.has(periodic_argument, atan2, arg, atan):
return None
if period == oo:
return unbranched
if period != oo:
n = ceiling(unbranched/period - S(1)/2)*period
if not n.has(ceiling):
return unbranched - n
def eval(cls, arg):
from sympy import atan
arg = sympify(arg)
if arg.is_Number:
if arg is S.NaN:
return S.NaN
elif arg is S.Zero:
return S.Zero
elif arg is S.One:
return S.Infinity
elif arg is S.NegativeOne:
return S.NegativeInfinity
elif arg is S.Infinity:
return -S.ImaginaryUnit * atan(arg)
elif arg is S.NegativeInfinity:
return S.ImaginaryUnit * atan(-arg)
elif arg.is_negative:
return -cls(-arg)
else:
if arg is S.ComplexInfinity:
return S.NaN
i_coeff = arg.as_coefficient(S.ImaginaryUnit)
if i_coeff is not None:
return S.ImaginaryUnit * atan(i_coeff)
else:
if _coeff_isneg(arg):
return -cls(-arg)
def test_issue_5414():
assert ratint(1/(x**2 + 16), x) == atan(x/4)/4
def test_issue_5817():
a, b, c = symbols('a,b,c', positive=True)
assert simplify(ratint(a/(b*c*x**2 + a**2 + b*a), x)) == \
sqrt(a)*atan(sqrt(
b)*sqrt(c)*x/(sqrt(a)*sqrt(a + b)))/(sqrt(b)*sqrt(c)*sqrt(a + b))
def test_log_to_atan():
f, g = (Poly(x + S(1)/2, x, domain='QQ'), Poly(sqrt(3)/2, x, domain='EX'))
fg_ans = 2*atan(2*sqrt(3)*x/3 + sqrt(3)/3)
assert log_to_atan(f, g) == fg_ans
assert log_to_atan(g, f) == -fg_ans
def eval_arctan(a, b, c, integrand, symbol):
return a / b * 1 / sympy.sqrt(c / b) * sympy.atan(symbol / sympy.sqrt(c / b))
def eval_trigsubstitution(theta, func, rewritten, substep, restriction, integrand, symbol):
func = func.subs(sympy.sec(theta), 1/sympy.cos(theta))
trig_function = list(func.find(TrigonometricFunction))
assert len(trig_function) == 1
trig_function = trig_function[0]
relation = sympy.solve(symbol - func, trig_function)
assert len(relation) == 1
numer, denom = sympy.fraction(relation[0])
if isinstance(trig_function, sympy.sin):
opposite = numer
hypotenuse = denom
adjacent = sympy.sqrt(denom**2 - numer**2)
inverse = sympy.asin(relation[0])
elif isinstance(trig_function, sympy.cos):
adjacent = numer
hypotenuse = denom
opposite = sympy.sqrt(denom**2 - numer**2)
inverse = sympy.acos(relation[0])
elif isinstance(trig_function, sympy.tan):
opposite = numer
adjacent = denom
hypotenuse = sympy.sqrt(denom**2 + numer**2)
inverse = sympy.atan(relation[0])
substitution = [
(sympy.sin(theta), opposite/hypotenuse),
(sympy.cos(theta), adjacent/hypotenuse),
(sympy.tan(theta), opposite/adjacent),
(theta, inverse)
]
return sympy.Piecewise(
(_manualintegrate(substep).subs(substitution).trigsimp(), restriction)
)
def reflect(self, line):
from sympy import atan, Point, Dummy, oo
g = self
l = line
o = Point(0, 0)
if l.slope == 0:
y = l.args[0].y
if not y: # x-axis
return g.scale(y=-1)
reps = [(p, p.translate(y=2*(y - p.y))) for p in g.atoms(Point)]
elif l.slope == oo:
x = l.args[0].x
if not x: # y-axis
return g.scale(x=-1)
reps = [(p, p.translate(x=2*(x - p.x))) for p in g.atoms(Point)]
else:
if not hasattr(g, 'reflect') and not all(
isinstance(arg, Point) for arg in g.args):
raise NotImplementedError(
'reflect undefined or non-Point args in %s' % g)
a = atan(l.slope)
c = l.coefficients
d = -c[-1]/c[1] # y-intercept
# apply the transform to a single point
x, y = Dummy(), Dummy()
xf = Point(x, y)
xf = xf.translate(y=-d).rotate(-a, o).scale(y=-1
).rotate(a, o).translate(y=d)
# replace every point using that transform
reps = [(p, xf.xreplace({x: p.x, y: p.y})) for p in g.atoms(Point)]
return g.xreplace(dict(reps))
def test_callback_factory():
args = x, y = symbols('x y')
expr = x + atan(y)
cb = _callback_factory(args, [expr], 'numpy', np.float64, 'C')
inp = np.array([17, 1])
ref = 17 + np.arctan(1)
assert np.allclose(cb(inp), ref)
def test_callback_factory__numba():
args = x, y = symbols('x y')
expr = x + atan(y)
cb = _callback_factory(args, [expr], 'numpy', np.float64, 'C', use_numba=True)
n = 500
inp = np.empty((n, 2))
inp[:, 0] = np.linspace(0, 1, n)
inp[:, 1] = np.linspace(-10, 10, n)
assert np.allclose(cb(inp), inp[:, 0] + np.arctan(inp[:, 1]))
def find_substitutions(integrand, symbol, u_var):
results = []
def test_subterm(u, u_diff):
substituted = integrand / u_diff
if symbol not in substituted.free_symbols:
# replaced everything already
return False
substituted = substituted.subs(u, u_var).cancel()
if symbol not in substituted.free_symbols:
return substituted.as_independent(u_var, as_Add=False)
return False
def possible_subterms(term):
if isinstance(term, (TrigonometricFunction,
sympy.asin, sympy.acos, sympy.atan,
sympy.exp, sympy.log, sympy.Heaviside)):
return [term.args[0]]
elif isinstance(term, sympy.Mul):
r = []
for u in term.args:
r.append(u)
r.extend(possible_subterms(u))
return r
elif isinstance(term, sympy.Pow):
if term.args[1].is_constant(symbol):
return [term.args[0]]
elif term.args[0].is_constant(symbol):
return [term.args[1]]
elif isinstance(term, sympy.Add):
r = []
for arg in term.args:
r.append(arg)
r.extend(possible_subterms(arg))
return r
return []
for u in possible_subterms(integrand):
if u == symbol:
continue
u_diff = manual_diff(u, symbol)
new_integrand = test_subterm(u, u_diff)
if new_integrand is not False:
constant, new_integrand = new_integrand
substitution = (u, constant, new_integrand)
if substitution not in results:
results.append(substitution)
return results
def _parts_rule(integrand, symbol):
# LIATE rule:
# log, inverse trig, algebraic (polynomial), trigonometric, exponential
def pull_out_polys(integrand):
integrand = integrand.together()
polys = [arg for arg in integrand.args if arg.is_polynomial(symbol)]
if polys:
u = sympy.Mul(*polys)
dv = integrand / u
return u, dv
def pull_out_u(*functions):
def pull_out_u_rl(integrand):
if any([integrand.has(f) for f in functions]):
args = [arg for arg in integrand.args
if any(isinstance(arg, cls) for cls in functions)]
if args:
u = reduce(lambda a,b: a*b, args)
dv = integrand / u
return u, dv
return pull_out_u_rl
liate_rules = [pull_out_u(sympy.log), pull_out_u(sympy.atan, sympy.asin, sympy.acos),
pull_out_polys, pull_out_u(sympy.sin, sympy.cos),
pull_out_u(sympy.exp)]
dummy = sympy.Dummy("temporary")
# we can integrate log(x) and atan(x) by setting dv = 1
if isinstance(integrand, (sympy.log, sympy.atan, sympy.asin, sympy.acos)):
integrand = dummy * integrand
for index, rule in enumerate(liate_rules):
result = rule(integrand)
if result:
u, dv = result
# Don't pick u to be a constant if possible
if symbol not in u.free_symbols and not u.has(dummy):
return
u = u.subs(dummy, 1)
dv = dv.subs(dummy, 1)
for rule in liate_rules[index + 1:]:
r = rule(integrand)
# make sure dv is amenable to integration
if r and r[0].subs(dummy, 1) == dv:
du = u.diff(symbol)
v_step = integral_steps(dv, symbol)
v = _manualintegrate(v_step)
return u, dv, v, du, v_step
def manualintegrate(f, var):
"""manualintegrate(f, var)
Compute indefinite integral of a single variable using an algorithm that
resembles what a student would do by hand.
Unlike ``integrate``, var can only be a single symbol.
Examples
========
>>> from sympy import sin, cos, tan, exp, log, integrate
>>> from sympy.integrals.manualintegrate import manualintegrate
>>> from sympy.abc import x
>>> manualintegrate(1 / x, x)
log(x)
>>> integrate(1/x)
log(x)
>>> manualintegrate(log(x), x)
x*log(x) - x
>>> integrate(log(x))
x*log(x) - x
>>> manualintegrate(exp(x) / (1 + exp(2 * x)), x)
atan(exp(x))
>>> integrate(exp(x) / (1 + exp(2 * x)))
RootSum(4*_z**2 + 1, Lambda(_i, _i*log(2*_i + exp(x))))
>>> manualintegrate(cos(x)**4 * sin(x), x)
-cos(x)**5/5
>>> integrate(cos(x)**4 * sin(x), x)
-cos(x)**5/5
>>> manualintegrate(cos(x)**4 * sin(x)**3, x)
cos(x)**7/7 - cos(x)**5/5
>>> integrate(cos(x)**4 * sin(x)**3, x)
cos(x)**7/7 - cos(x)**5/5
>>> manualintegrate(tan(x), x)
-log(cos(x))
>>> integrate(tan(x), x)
-log(sin(x)**2 - 1)/2
See Also
========
sympy.integrals.integrals.integrate
sympy.integrals.integrals.Integral.doit
sympy.integrals.integrals.Integral
"""
return _manualintegrate(integral_steps(f, var))
def find_substitutions(integrand, symbol, u_var):
results = []
def test_subterm(u, u_diff):
substituted = integrand / u_diff
if symbol not in substituted.free_symbols:
# replaced everything already
return False
substituted = substituted.subs(u, u_var).cancel()
if symbol not in substituted.free_symbols:
return substituted.as_independent(u_var, as_Add=False)
return False
def possible_subterms(term):
if isinstance(term, (TrigonometricFunction,
sympy.asin, sympy.acos, sympy.atan,
sympy.exp, sympy.log, sympy.Heaviside)):
return [term.args[0]]
elif isinstance(term, sympy.Mul):
r = []
for u in term.args:
r.append(u)
r.extend(possible_subterms(u))
return r
elif isinstance(term, sympy.Pow):
if term.args[1].is_constant(symbol):
return [term.args[0]]
elif term.args[0].is_constant(symbol):
return [term.args[1]]
elif isinstance(term, sympy.Add):
r = []
for arg in term.args:
r.append(arg)
r.extend(possible_subterms(arg))
return r
return []
for u in possible_subterms(integrand):
if u == symbol:
continue
u_diff = manual_diff(u, symbol)
new_integrand = test_subterm(u, u_diff)
if new_integrand is not False:
constant, new_integrand = new_integrand
if new_integrand == integrand.subs(symbol, u_var):
continue
substitution = (u, constant, new_integrand)
if substitution not in results:
results.append(substitution)
return results
def _parts_rule(integrand, symbol):
# LIATE rule:
# log, inverse trig, algebraic, trigonometric, exponential
def pull_out_algebraic(integrand):
integrand = integrand.cancel().together()
algebraic = [arg for arg in integrand.args if arg.is_algebraic_expr(symbol)]
if algebraic:
u = sympy.Mul(*algebraic)
dv = (integrand / u).cancel()
if not u.is_polynomial() and isinstance(dv, sympy.exp):
return
return u, dv
def pull_out_u(*functions):
def pull_out_u_rl(integrand):
if any([integrand.has(f) for f in functions]):
args = [arg for arg in integrand.args
if any(isinstance(arg, cls) for cls in functions)]
if args:
u = reduce(lambda a,b: a*b, args)
dv = integrand / u
return u, dv
return pull_out_u_rl
liate_rules = [pull_out_u(sympy.log), pull_out_u(sympy.atan, sympy.asin, sympy.acos),
pull_out_algebraic, pull_out_u(sympy.sin, sympy.cos),
pull_out_u(sympy.exp)]
dummy = sympy.Dummy("temporary")
# we can integrate log(x) and atan(x) by setting dv = 1
if isinstance(integrand, (sympy.log, sympy.atan, sympy.asin, sympy.acos)):
integrand = dummy * integrand
for index, rule in enumerate(liate_rules):
result = rule(integrand)
if result:
u, dv = result
# Don't pick u to be a constant if possible
if symbol not in u.free_symbols and not u.has(dummy):
return
u = u.subs(dummy, 1)
dv = dv.subs(dummy, 1)
for rule in liate_rules[index + 1:]:
r = rule(integrand)
# make sure dv is amenable to integration
if r and sympy.simplify(r[0].subs(dummy, 1)) == sympy.simplify(dv):
du = u.diff(symbol)
v_step = integral_steps(sympy.simplify(dv), symbol)
v = _manualintegrate(v_step)
return u, dv, v, du, v_step