def test_latex_printer():
r = Function('r')('t')
assert VectorLatexPrinter().doprint(r ** 2) == "r^{2}"
python类Function()的实例源码
def test_replace_map():
from sympy import symbols, Function, Matrix
F, G = symbols('F, G', cls=Function)
K = Matrix(2, 2, [(G(0), {F(0): G(0)}), (G(1), {F(1): G(1)}), (G(1), {F(1)\
: G(1)}), (G(2), {F(2): G(2)})])
M = Matrix(2, 2, lambda i, j: F(i+j))
N = M.replace(F, G, True)
assert N == K
def python(expr, **settings):
"""Return Python interpretation of passed expression
(can be passed to the exec() function without any modifications)"""
printer = PythonPrinter(settings)
exprp = printer.doprint(expr)
result = ''
# Returning found symbols and functions
renamings = {}
for symbolname in printer.symbols:
newsymbolname = symbolname
# Escape symbol names that are reserved python keywords
if kw.iskeyword(newsymbolname):
while True:
newsymbolname += "_"
if (newsymbolname not in printer.symbols and
newsymbolname not in printer.functions):
renamings[sympy.Symbol(
symbolname)] = sympy.Symbol(newsymbolname)
break
result += newsymbolname + ' = Symbol(\'' + symbolname + '\')\n'
for functionname in printer.functions:
newfunctionname = functionname
# Escape function names that are reserved python keywords
if kw.iskeyword(newfunctionname):
while True:
newfunctionname += "_"
if (newfunctionname not in printer.symbols and
newfunctionname not in printer.functions):
renamings[sympy.Function(
functionname)] = sympy.Function(newfunctionname)
break
result += newfunctionname + ' = Function(\'' + functionname + '\')\n'
if not len(renamings) == 0:
exprp = expr.subs(renamings)
result += 'e = ' + printer._str(exprp)
return result
def _print_expint(self, e):
from sympy import Function
if e.args[0].is_Integer and self._use_unicode:
return self._print_Function(Function('E_%s' % e.args[0])(e.args[1]))
return self._print_Function(e)
def test_printmethod():
x = symbols('x')
class nint(Function):
def _fcode(self, printer):
return "nint(%s)" % printer._print(self.args[0])
assert fcode(nint(x)) == " nint(x)"
def test_not_fortran():
x = symbols('x')
g = Function('g')
assert fcode(
gamma(x)) == "C Not Fortran:\nC gamma(x)\n gamma(x)"
assert fcode(Integral(sin(x))) == "C Not Fortran:\nC Integral(sin(x), x)\n Integral(sin(x), x)"
assert fcode(g(x)) == "C Not Fortran:\nC g(x)\n g(x)"
def _functions(expr, x):
""" Find the types of functions in expr, to estimate the complexity. """
from sympy import Function
return set(e.func for e in expr.atoms(Function) if x in e.free_symbols)
def test_free_symbols():
from sympy import Function
f = Function('f')
assert mellin_transform(f(x), x, s).free_symbols == set([s])
assert mellin_transform(f(x)*a, x, s).free_symbols == set([s, a])
def test_sine_transform():
from sympy import sinh, cosh, EulerGamma
t = symbols("t")
w = symbols("w")
a = symbols("a")
f = Function("f")
# Test unevaluated form
assert sine_transform(f(t), t, w) == SineTransform(f(t), t, w)
assert inverse_sine_transform(
f(w), w, t) == InverseSineTransform(f(w), w, t)
assert sine_transform(1/sqrt(t), t, w) == 1/sqrt(w)
assert inverse_sine_transform(1/sqrt(w), w, t) == 1/sqrt(t)
assert sine_transform(
(1/sqrt(t))**3, t, w) == sqrt(w)*gamma(S(1)/4)/(2*gamma(S(5)/4))
assert sine_transform(t**(-a), t, w) == 2**(
-a + S(1)/2)*w**(a - 1)*gamma(-a/2 + 1)/gamma((a + 1)/2)
assert inverse_sine_transform(2**(-a + S(
1)/2)*w**(a - 1)*gamma(-a/2 + 1)/gamma(a/2 + S(1)/2), w, t) == t**(-a)
assert sine_transform(
exp(-a*t), t, w) == sqrt(2)*w/(sqrt(pi)*(a**2 + w**2))
assert inverse_sine_transform(
sqrt(2)*w/(sqrt(pi)*(a**2 + w**2)), w, t) == exp(-a*t)
assert sine_transform(
log(t)/t, t, w) == -sqrt(2)*sqrt(pi)*(log(w**2) + 2*EulerGamma)/4
assert sine_transform(
t*exp(-a*t**2), t, w) == sqrt(2)*w*exp(-w**2/(4*a))/(4*a**(S(3)/2))
assert inverse_sine_transform(
sqrt(2)*w*exp(-w**2/(4*a))/(4*a**(S(3)/2)), w, t) == t*exp(-a*t**2)
def test_cosine_transform():
from sympy import sinh, cosh, Si, Ci
t = symbols("t")
w = symbols("w")
a = symbols("a")
f = Function("f")
# Test unevaluated form
assert cosine_transform(f(t), t, w) == CosineTransform(f(t), t, w)
assert inverse_cosine_transform(
f(w), w, t) == InverseCosineTransform(f(w), w, t)
assert cosine_transform(1/sqrt(t), t, w) == 1/sqrt(w)
assert inverse_cosine_transform(1/sqrt(w), w, t) == 1/sqrt(t)
assert cosine_transform(1/(
a**2 + t**2), t, w) == sqrt(2)*sqrt(pi)*exp(-a*w)/(2*a)
assert cosine_transform(t**(
-a), t, w) == 2**(-a + S(1)/2)*w**(a - 1)*gamma((-a + 1)/2)/gamma(a/2)
assert inverse_cosine_transform(2**(-a + S(
1)/2)*w**(a - 1)*gamma(-a/2 + S(1)/2)/gamma(a/2), w, t) == t**(-a)
assert cosine_transform(
exp(-a*t), t, w) == sqrt(2)*a/(sqrt(pi)*(a**2 + w**2))
assert inverse_cosine_transform(
sqrt(2)*a/(sqrt(pi)*(a**2 + w**2)), w, t) == exp(-a*t)
assert cosine_transform(exp(-a*sqrt(t))*cos(a*sqrt(
t)), t, w) == a*exp(-a**2/(2*w))/(2*w**(S(3)/2))
assert cosine_transform(1/(a + t), t, w) == sqrt(2)*(
(-2*Si(a*w) + pi)*sin(a*w)/2 - cos(a*w)*Ci(a*w))/sqrt(pi)
assert inverse_cosine_transform(sqrt(2)*meijerg(((S(1)/2, 0), ()), (
(S(1)/2, 0, 0), (S(1)/2,)), a**2*w**2/4)/(2*pi), w, t) == 1/(a + t)
assert cosine_transform(1/sqrt(a**2 + t**2), t, w) == sqrt(2)*meijerg(
((S(1)/2,), ()), ((0, 0), (S(1)/2,)), a**2*w**2/4)/(2*sqrt(pi))
assert inverse_cosine_transform(sqrt(2)*meijerg(((S(1)/2,), ()), ((0, 0), (S(1)/2,)), a**2*w**2/4)/(2*sqrt(pi)), w, t) == 1/(t*sqrt(a**2/t**2 + 1))
def _print_Function(self, expr):
"""Print a Function object.
:param expr: The expression.
:rtype : str
:return: The printed string.
:raise RuntimeError: Raise if the function is not supported.
"""
assert isinstance(expr, _sympy.Function)
# Check the function.
fn_object = _mexp_function.find_sympy_function(expr.func.__name__)
if fn_object is None:
raise RuntimeError("Unsupported function: \"%s\"." % expr.func.__name__)
if fn_object.get_argument_count() != len(expr.args):
raise RuntimeError("Argument count mismatch.")
# Stringify the arguments.
arg_text = ""
for arg_id in range(0, len(expr.args)):
arg_text += self.doprint(expr.args[arg_id])
if arg_id + 1 != len(expr.args):
arg_text += ","
return "%s(%s)" % (fn_object.get_function_name(), arg_text)
def _print_Function(self, e):
"""Print a Function object.
:param e: The expression.
:rtype : bce.dom.mathml.all.Base
:return: The printed MathML object.
"""
assert isinstance(e, _sympy.Function)
# Check the function.
fn_object = _mexp_function.find_sympy_function(e.func.__name__)
if fn_object is None:
raise RuntimeError("Unsupported function: \"%s\"." % e.func.__name__)
if fn_object.get_argument_count() != len(e.args):
raise RuntimeError("Argument count mismatch.")
# Build the node.
node = _mathml.RowComponent()
node.append_object(_mathml.TextComponent(fn_object.get_function_name()))
node.append_object(_mathml.OperatorComponent(_mathml.OPERATOR_LEFT_PARENTHESIS))
for arg_id in range(0, len(e.args)):
arg_value = e.args[arg_id]
node.append_object(self.doprint(arg_value))
if arg_id + 1 != len(e.args):
node.append_object(_mathml.OperatorComponent(_mathml.OPERATOR_SEPARATOR))
node.append_object(_mathml.OperatorComponent(_mathml.OPERATOR_RIGHT_PARENTHESIS))
return node
def test_printmethod():
class nint(Function):
def _fcode(self, printer):
return "nint(%s)" % printer._print(self.args[0])
assert fcode(nint(x)) == "nint(x)"
def test_user_functions():
g = Function('g')
assert fcode(g(x), user_functions={"g": "great"}) == "great(x)"
assert fcode(sin(x), user_functions={"sin": "zsin"}) == "zsin(x)"
assert fcode(gamma(x), user_functions={"gamma": "mygamma"}) == "mygamma(x)"
assert fcode(factorial(n), user_functions={"factorial": "fct"}) == "fct(n)"
def generate_helpers_C(self, chunk_size=100):
"""
translates the helpers to C code using SymEngine’s `C-code printer <https://github.com/symengine/symengine/pull/1054>`_.
Parameters
----------
chunk_size : integer
If the number of instructions in the final C code exceeds this number, it will be split into chunks of this size. See `large_systems` on why this is useful.
If there is an obvious grouping of your helpers, the group size suggests itself for `chunk_size`.
If smaller than 1, no chunking will happen.
"""
if self.helpers:
get_helper = symengine.Function("get_general_helper")
set_helper = symengine.Function("set_general_helper")
for i,helper in enumerate(self.helpers):
self.general_subs[helper[0]] = get_helper(i)
self.render_and_write_code(
(set_helper(i, helper[1].subs(self.general_subs)) for i,helper in enumerate(self.helpers)),
name = "general_helpers",
chunk_size = chunk_size,
arguments = self._default_arguments() + [("general_helper","double *__restrict const")],
omp = False,
)
self._helper_C_source = True
def test_f():
f = Function("f")
assert residue(f(x)/x**5, x, 0) == f(x).diff(x, 4).subs(x, 0)/24
def test_var_cls():
f = var('f', cls=Function)
assert isinstance(f, FunctionClass)
g, h = var('g,h', cls=Function)
assert isinstance(g, FunctionClass)
assert isinstance(h, FunctionClass)
def test_function():
f = Function('f')
l, x = map(Symbol, 'lx')
assert exp(l(x))*l(x)/exp(l(x)) == l(x)
assert exp(f(x))*f(x)/exp(f(x)) == f(x)
def test_sympy__physics__quantum__operator__DifferentialOperator():
from sympy.physics.quantum.operator import DifferentialOperator
from sympy import Derivative, Function
f = Function('f')
assert _test_args(DifferentialOperator(1/x*Derivative(f(x), x), f(x)))
def _atomic(e):
"""Return atom-like quantities as far as substitution is
concerned: Derivatives, Functions and Symbols. Don't
return any 'atoms' that are inside such quantities unless
they also appear outside, too.
Examples
========
>>> from sympy import Derivative, Function, cos
>>> from sympy.abc import x, y
>>> from sympy.core.basic import _atomic
>>> f = Function('f')
>>> _atomic(x + y)
{x, y}
>>> _atomic(x + f(y))
{x, f(y)}
>>> _atomic(Derivative(f(x), x) + cos(x) + y)
{y, cos(x), Derivative(f(x), x)}
"""
from sympy import Derivative, Function, Symbol
pot = preorder_traversal(e)
seen = set()
try:
free = e.free_symbols
except AttributeError:
return {e}
atoms = set()
for p in pot:
if p in seen:
pot.skip()
continue
seen.add(p)
if isinstance(p, Symbol) and p in free:
atoms.add(p)
elif isinstance(p, (Derivative, Function)):
pot.skip()
atoms.add(p)
return atoms