You can still create a symbolic function via the function
function... :
f=function("f", eval_func=lambda self,*args:args[0]*matrix[[5]])
(or possibly
f=function("f", evalf_func=lambda self,*args:[u*matrix[[5]] for u in args])
depending of the semantics you wish to have for non-scalar arguments...)
The point is that f
can now appear in symbolic expressions, where its argument is symbolic. This allows its use in other symbolic expressions. Contrast :
sage: fs=function("fs", evalf_func=lambda self, *args: len(divisors(args[0])))
sage: gs(x)=fs(x)^2
sage: gs
x |--> fs(x)^2
sage: fs
fs
where fs
is treated as some "primitive" functoin, with :
sage: def fp(x): return len(divisors(x))
sage: gp(x)=fp(x)^2
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/usr/local/sage-9/local/lib/python3.9/site-packages/sage/arith/misc.py in divisors(n)
1484 try:
-> 1485 m = n.divisors
1486 except AttributeError:
/usr/local/sage-9/local/lib/python3.9/site-packages/sage/structure/element.pyx in sage.structure.element.Element.__getattr__ (build/cythonized/sage/structure/element.c:4708)()
492 """
--> 493 return self.getattr_from_category(name)
494
/usr/local/sage-9/local/lib/python3.9/site-packages/sage/structure/element.pyx in sage.structure.element.Element.getattr_from_category (build/cythonized/sage/structure/element.c:4820)()
505 cls = P._abstract_element_class
--> 506 return getattr_from_other_class(self, cls, name)
507
/usr/local/sage-9/local/lib/python3.9/site-packages/sage/cpython/getattr.pyx in sage.cpython.getattr.getattr_from_other_class (build/cythonized/sage/cpython/getattr.c:2618)()
371 dummy_error_message.name = name
--> 372 raise AttributeError(dummy_error_message)
373 attribute = <object>attr
AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'divisors'
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
<ipython-input-90-05136176d065> in <module>
----> 1 __tmp__=var("x"); gp = symbolic_expression(fp(x)**Integer(2)).function(x)
<ipython-input-87-c759a1d7e016> in fp(x)
----> 1 def fp(x): return len(divisors(x))
/usr/local/sage-9/local/lib/python3.9/site-packages/sage/arith/misc.py in divisors(n)
1492 one = parent(n)(1)
1493 output = [one]
-> 1494 for p, e in f:
1495 prev = output[:]
1496 pn = one
TypeError: 'sage.symbolic.expression.Expression' object is not iterable
where the expression serving as "function body" is somehow evaluated during the creation of the symbolic expression ; this entails trying to evaluate divisors(x)
, which fails, since divisors
is not a symbolic function...
Note that fs
has a, evalf_func
method, but not an eval_func
method : this ensures that fs(x)
will remain unevaluated, whereas fs(12)
will be (numerically) evaluated (and return 12
). Type function?
for more details (quite important here...).
HTH,