Create Generic Function Without Macros From String and Symbolic Variable

I know you can create a function, say f(t) where t is a symbolic variable with a macro. How can you do it without using a macro where I have previously defined t. More specifically I wish to define several different functions, f(t), in a function where the name f is specified by a string. For example I have a function MultiVector("f",t) and I wish to return [f(t),fx(t),fy(t),fz(t),fxy(t),fyz(t),fzx(t), fxyz(t)]. Is there a way to do this. Also if t is replaces by multiple variables such as f(x,y,z) where the generating function could be `MultiVector(“f”,[x,y,z]). Thanks for any help.

Do you have a working code example of this? Not sure if you’re using atypical terminology for base Julia or talking about Symbolics.jl, in which case the post could use a more specific tag.

1 Like

I am using Julia Symbolics. My previous experience is with sympy. I am able to follow Symbolics but I don’t see how to use macros to create general functions say f(t) whose names are defined by strings such as "f".

1 Like

Hm, my Symbolics is rather rusty, but it seems like you want to do something with a value known only at runtime, but the macro @variables only works on values known when you write the line. Maybe you’re looking for the functions variable and variables? Those strictly take Symbols (from base Julia, not the same as symbolic expressions in Symbolics), so you’ll need to convert somewhere like Symbol("f"). Doing the same for function call expressions escape my memory at the moment, so I’ll add the tag and maybe someone who uses it on a regular basis can help.

Thank you. I will repost on the forum for Symbolics. Note I have a routine that uses Symbolics.variables("t") to create a variable t. I don’t know how to make a function with anything other than @variables t,f(t) and that doesn’t let me pass the name of the function from a string anymore than @variables t does. I am not particularly fond of the macros in Symbolics.

It should also be possible to interpolate into the macro with $. Like this, I think:

julia> f = :f
:f

julia> t = :t
:t

julia> @variables $t, $f($t)
2-element Vector{Num}:
 t
  f(t)

Definitely slipped my mind that interpolation was supported. I think brombo is saying a function needs to take those values though, so are runtime-known values supported, e.g. foo(f, t) = @variables $t, $f($t) allows foo(:sin, :x)?

Interpolation seems to work fine for me

julia> foo(:sin, :t)
2-element Vector{Num}:
      t
 sin(t)

Another option seems to be

let f = :sin, x = :t
    Symbolics.variable(f, T=Symbolics.FnType)(Symbolics.variable(x))
end
1 Like

I am using

str = "x"
xvar = Symbolics.variable(str)

and it works fine. Would the following work?

xstr = "x"
fstr = "f"
xvar = Symbolics.variable(xstr)
fvar = Symbolics.variable(fstr, T=Symbolics.FnType)(xvar)

or if f was a function of say an xvar and yvar then

xstr = "x"
ystr = "y"
fstr = "f"
xvar = Symbolics.variable(xstr)
yvar = Symbolics.variable(ystr)
fvar = Symbolics.variable(fstr, T=Symbolics.FnType)(xvar,yvar)

for f(x,y)?

Thank you. I tried it where f and x are strings and it worked fine and also for function with multiple arguments. Symbolics is great except that it generates lousy LaTeX strings which actually id probably the fault of LaTeXStrings and not Symbolics. LaTeXStrings needs to do a lot more post processing than it does.

Are you looking for build_function?

I have it working (thanks to advice on the forum) for a single variable. The question is how to implement my functions function for functions of multiple variables.

function functions(s::String,X::Vector{Num})
S = split(s," ")
F = []
for str in S
f = Symbolics.variable(str, T=Symbolics.FnType)(X)
push!(F,f)
end
return F
end

x,y = symbols("x y") #My function using Symbolics.variable(mystring)
F = functions("f fx fy fxy",[x,y]) #Equivalent of symbols but for functions
display(F)

Output -

4-element Vector{Any}:
f(Num[x,y])
fx(Num[x,y])
fy(Num[x,y])
fxy(Num[x,y])

How do I get -

4-element Vector{Any}:
f(x,y)
fx(x,y)
fy(x,y)
fxy(x,y)

Essentially how to convert -

([X[1],X[2]]) to (X[1],X[2]) in Symbolics argument

But for arbitrary length vector of variables?

Splatting

f = Symbolics.variable(str, T=Symbolics.FnType)(X...)

Than you. That was what I needed.