2 from sympy
.core
.add
import Add
3 from sympy
.core
.sympify
import sympify
4 from sympy
.core
.relational
import Relational
7 """Call a function on all elements of composite objects.
9 This decorator is intended to make it uniformly possible to apply
10 functions to all elements of composite or iterable objects or just
11 to expressions. Currently supported, so called, threadable classes
12 are Add, Matrix, Relational and all other which implement __iter__
13 attribute. If the input expression is not of this type, then the
14 function will be applied to this object, as to a singleton.
16 Functions which will use this decorator must have the following
20 def function(expr, *args, **kwargs):
22 where 'expr' is obligatory threadable object (listed above). Other
23 arguments, if available, are transferred without any change. As an
24 example see functions in sympy.simplify module.
26 By default threading is done on elements of Add instance. To avoid
27 this behaviour set 'use_add' flag with False in keyword arguments
28 (see integrate() for details), e.g:
30 @threaded(use_add=False)
31 def function(expr, *args, **kwargs):
34 from sympy
.matrices
import Matrix
36 use_add
= flags
.get('use_add', True)
38 def threaded_proxy(func
):
39 def threaded_decorator(expr
, *args
, **kwargs
):
40 if isinstance(expr
, Matrix
):
41 return expr
.applyfunc(lambda f
: func(f
, *args
, **kwargs
))
42 elif hasattr(expr
, '__iter__'):
43 return expr
.__class
__([ func(f
, *args
, **kwargs
) for f
in expr
])
47 if isinstance(expr
, Relational
):
48 lhs
= func(expr
.lhs
, *args
, **kwargs
)
49 rhs
= func(expr
.rhs
, *args
, **kwargs
)
51 return Relational(lhs
, rhs
, expr
.rel_op
)
52 elif expr
.is_Add
and use_add
:
53 return Add(*[ func(f
, *args
, **kwargs
) for f
in expr
.args
])
55 return func(expr
, *args
, **kwargs
)
57 threaded_decorator
.__doc
__ = func
.__doc
__
58 threaded_decorator
.__name
__ = func
.__name
__
60 return threaded_decorator