In gnuplot, is there a way to pass a user defined function as an argument to another user defined function? For example, I can write a function loop which will sum shifts of a given function:
f(x) = (x <= 0) ? 0 : 1/(1 x)**2
loop(x, i, s) = (i == 0) ? f(x) : loop(x-s, i-1, s) f(x)
Then I can do things like:
plot loop(x, 10, 1)
But, how do I define a function loop2 that does this for any function, as in something like:
loop2(g, x, i, s) = (i == 0) ? g(x) : loop2(g, x-s, i-1, s) g(x)
so that I can then do things like:
f3(x) = (x <= 0) ? 0 : 1/(1 x)**3
plot loop2(f, x, 10, 1)
replot loop2(f3, x, 10, 1)
CodePudding user response:
I think this is not possible in gnuplot 5.4.
The development version (gnuplot 5.5) has recently gained the ability to label a block of text commands as a named executable function, known as a "function block". This gives you access to commands in a function block that are not possible in a one-line user defined function. Here is your example run in a recent build of the development version. At the top level the name of the function ("f" or "f3") is passed as a parameter that can be used to construct a call of the function itself.
function $loop2(name, x, i, s) << EOF
local temp = 0
eval sprintf("temp = %s(x)", name)
return (i == 0) ? temp : temp $loop2(name, x-s, i-1, s)
EOF
f(x) = (x <= 0) ? 0 : 1/(1 x)**2
f3(x) = (x <= 0) ? 0 : 1/(1 x)**3
set key left Left reverse
set tics nomirror
set border 3
set xrange [0:10]
set yrange [0:1.5]
plot $loop2("f", x, 10, 1), $loop2("f3", x, 10, 1)
And here is a link to an example in the demo collection that illustrates calling one function block from another, wrapping both in a top-level user defined function. function_block demo