# How to define functions with varying number of variables

I want to compute the Frechet derivative for a vector field, and that code works perfectly for functions with two variables x and t.

var ("t x")
v  = function ("v")
u  = function ("u")
w1 = function ("w1")
w2 = function ("w2")
eqsys = [diff(v(x,t), x) - u(x,t), diff(v(x,t), t) - diff(u(x,t), x)/(u(x,t)**2)]

def FrechetD (support, dependVar, independVar, testfunction):
frechet = []
eps = var ("eps")
v = independVar[:] + [eps]
for j in range (len(support)):
deriv = []
for i in range (len(support)):
r0 (x, t, eps) =  dependVar[i](*independVar)+ testfunction[i](*independVar) * eps
s  =  support[j].substitute_function (dependVar[i], r0)
deriv.append (diff(s, eps).subs ({eps: 0}))
frechet.append (deriv)
return frechet
FrechetD (eqsys, [u,v], [x,t], [w1,w2])
[[-w1(x, t), diff(w2(x, t), x)],
[2*w1(x, t)*diff(u(x, t), x)/u(x, t)^3 - diff(w1(x, t), x)/u(x, t)^2,
diff(w2(x, t), t)]]


but my problem is the line

r0 (x, t, eps) =  dependVar[i](*independVar)+ testfunction[i](*independVar) * eps


because this depends on the hardcoded x and t. Without it the following derivation for eps always is 0. Even when I add someting like

_r0 = function('ro')(*v)


doesn't work. What i want to do is to something like

r0 (*v) =  dependVar[i](*independVar)+ testfunction[i](*independVar) * eps


to get rid of the hardcoded variables and/or the number of variables. Is that possible ?

edit retag close merge delete

Sort by » oldest newest most voted

Hello, @tamandua! I feel embarrassed to admit this is the first time I hear about the Fréchet derivative, thus I am not sure about what you are trying to achieve or how to test my code. However, I hope the following is useful for you.

On one hand, Sage's function() allows to define symbolic functions (referring to "function" in the mathematical sense). (Sorry about the repetitive words). In this particular case, I don't think you need such a thing, since the instructions you used to work with r0 work perfectly well with normal Python functions (this time, "function" in the sense of "subroutine"). For example, you could just define inside your innermost loop the following:

def r0(*args):
return dependVar[i](*independVar)+ testfunction[i](*independVar) * eps


and that should do the trick.

On the other hand, it is also possible to define a symbolic function with an arbitrary number of arguments, as you request in your question. For completeness (and for other users with this same question), I am going to describe what you should do. First, define a Python subroutine that accepts an arbitrary number of arguments. This is basically the same as my previous bit of code, but I will use a different name in order to avoid name clash. For example,

def _r0(*args):
return dependVar[i](*independVar)+ testfunction[i](*independVar) * eps


Now, you create a symbolic function r0 and indicate Sage that its values should be computed using the _r0 subroutine:

r0 = function('r0', eval_func=_r0)


That's it!

If you want to know more about Sage's function(), you can use the command function?, and you will be able to see the documentation of this command. In fact, it is way more advanced and complex than I can describe here. For example, you can actually define the symbolic function r0 and how to differentiate it symbolically.

In any case, here are the two versions of my code:

Please, let me know if this worked for you. I recommend you test it with different case, just to be sure. If it doesn't work, please, let me know so we can work an more adequate approach for your use!

I hope this helps!

more

Owe you some beer!

Both version work as expected. And also your explanation is very helpful.

I had implemented the classical "can't see the forest for the trees" pattern which hindered me to use the most natural python solution : a simple "def r0 (*args)".

THX a lot.

PS: Frechet derivative is a generalisation of the standard directional derivative which puts a weight (w1, w2 in the example) on the steepest descent. The Gateaux derivative generalizes the Frechet derivative to locally convex topological vector spaces like Banach spaces.

Hello, @tamandua! I'm happy to help! Thank you for the information about the Frechet and Gateaux derivatives. It is always great to learn something new!