JuliaSymbolics / Symbolics.jl

Symbolic programming for the next generation of numerical software
https://symbolics.juliasymbolics.org/stable/
Other
1.32k stars 146 forks source link

Q: correct use of build_function with kwargs #1151

Open Audrius-St opened 1 month ago

Audrius-St commented 1 month ago

Hello,

When I attempt to use build_function with kwargs I encounter an error message that I don't understand; that one of the kwargs is not defined.

My question is what am I doing incorrectly in my use of build_function.

Below is a simplified MNWE followed by the error message.

begin
    @variables x
    @variables xa, xb

    n_dX::Int64 = 100

    Xo::Float64 = 0.0
    Xf::Float64 = 2.0 * π
    X::Vector{Float64} = collect(range(Xo, Xf, n_dX))

    f_tpTs = (-(1//2)*((x - xb)^2)*sin(xb) + (x - xb)*cos(xb)*(1 + (3(-x + xb)) / (-xa + xb)))*(((x - xa) / (-xa + xb))^3) + (-(1//2)*((x - xa)^2)*sin(xa) + (x - xa)*(1 + (3(x - xa)) / (-xa + xb))*cos(xa))*(((-x + xb) / (-xa + xb))^3)

    f_tpTs_nm =
        eval(
            build_function(
                f_tpTs, x;
                expression = Val{false},
                target = Symbolics.JuliaTarget(),
                xa = Xo, xb = Xf
            )
        )

    # The error message is generated by the following line:
    f_tpTs_nm_vec = f_tpTs_nm.(X)
end

generates the following error message stating that the kwarg xb is not defined

ERROR: LoadError: UndefVarError: `xb` not defined
Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/SymbolicUtils/qyMYa/src/code.jl:375 [inlined]
  [2] macro expansion
    @ ~/.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:163 [inlined]
  [3] macro expansion
    @ ./none:0 [inlined]
  [4] generated_callfunc
    @ ./none:0 [inlined]
  [5] (::RuntimeGeneratedFunctions.RuntimeGeneratedFunction{…})(args::Float64)
    @ RuntimeGeneratedFunctions ~/.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:150
  [6] _broadcast_getindex_evalf
    @ ./broadcast.jl:709 [inlined]
  [7] _broadcast_getindex
    @ ./broadcast.jl:682 [inlined]
  [8] getindex
    @ ./broadcast.jl:636 [inlined]
  [9] copy
    @ ./broadcast.jl:942 [inlined]
 [10] materialize(bc::Base.Broadcast.Broadcasted{…})
    @ Base.Broadcast ./broadcast.jl:903
 [11] main()
    @ Main ~/projects/Hamiltonian/test/test_symbolic_series.jl:171
 [12] top-level scope
    @ ~/projects/Hamiltonian/test/test_symbolic_series.jl:187
 [13] include(fname::String)
    @ Base.MainInclude ./client.jl:489
 [14] top-level scope
    @ REPL[3]:1
in expression starting at /home/Audrius-St/projects/Hamiltonian/test/test_symbolic_series.jl:186
Some type information was truncated. Use `show(err)` to see complete types.
julia> show(err)
1-element ExceptionStack:
LoadError: UndefVarError: `xb` not defined
Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/SymbolicUtils/qyMYa/src/code.jl:375 [inlined]
  [2] macro expansion
    @ ~/.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:163 [inlined]
  [3] macro expansion
    @ ./none:0 [inlined]
  [4] generated_callfunc
    @ ./none:0 [inlined]
  [5] (::RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:x,), Symbolics.var"#_RGF_ModTag", Symbolics.var"#_RGF_ModTag", (0x3dd15a9b, 0x9901c002, 0x8d0643e3, 0x01053400, 0x284b0670), Expr})(args::Float64)
    @ RuntimeGeneratedFunctions ~/.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:150
  [6] _broadcast_getindex_evalf
    @ ./broadcast.jl:709 [inlined]
  [7] _broadcast_getindex
    @ ./broadcast.jl:682 [inlined]
  [8] getindex
    @ ./broadcast.jl:636 [inlined]
  [9] copy
    @ ./broadcast.jl:942 [inlined]
 [10] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:x,), Symbolics.var"#_RGF_ModTag", Symbolics.var"#_RGF_ModTag", (0x3dd15a9b, 0x9901c002, 0x8d0643e3, 0x01053400, 0x284b0670), Expr}, Tuple{Vector{Float64}}})
    @ Base.Broadcast ./broadcast.jl:903
 [11] main()
    @ Main ~/projects/Hamiltonian/test/test_symbolic_series.jl:171
 [12] top-level scope
    @ ~/projects/Hamiltonian/test/test_symbolic_series.jl:187
 [13] include(fname::String)
    @ Base.MainInclude ./client.jl:489
 [14] top-level scope
    @ REPL[3]:1
in expression starting at /home/Audrius-St/projects/Hamiltonian/test/test_symbolic_series.jl:186
ChrisRackauckas commented 1 month ago

I don't quite understand. xb is not a kwarg, so the error message is correct?

Audrius-St commented 1 month ago

Well, I've not passed kwargs before, my understanding is based on reading the Julia documentation and it sounds like I've misunderstood it.

I thought the general syntax for kwargs is of the form f(x; xa=Xo, xb=Xf).

The error message does not mention kwargs.

I would like to evaluate

f_tpTs_nm_vec = f_tpTs_nm.(X)

for the vector X

I would like to know what I'm doing incorrectly in the build_function that give me the error message, ERROR: LoadError: UndefVarError: xb not defined now run for the MNWE above and given below

julia> include("test_symbolic_series.jl")
ERROR: LoadError: UndefVarError: `xb` not defined
Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/SymbolicUtils/qyMYa/src/code.jl:375 [inlined]
  [2] macro expansion
    @ ~/.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:163 [inlined]
  [3] macro expansion
    @ ./none:0 [inlined]
  [4] generated_callfunc
    @ ./none:0 [inlined]
  [5] (::RuntimeGeneratedFunctions.RuntimeGeneratedFunction{…})(args::Float64)
    @ RuntimeGeneratedFunctions ~/.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:150
  [6] _broadcast_getindex_evalf
    @ ./broadcast.jl:709 [inlined]
  [7] _broadcast_getindex
    @ ./broadcast.jl:682 [inlined]
  [8] getindex
    @ ./broadcast.jl:636 [inlined]
  [9] copy
    @ ./broadcast.jl:942 [inlined]
 [10] materialize(bc::Base.Broadcast.Broadcasted{…})
    @ Base.Broadcast ./broadcast.jl:903
 [11] top-level scope
    @ ~/projects/Hamiltonian/test/test_symbolic_series.jl:28
 [12] include(fname::String)
    @ Base.MainInclude ./client.jl:489
 [13] top-level scope
    @ REPL[6]:1
ChrisRackauckas commented 1 month ago

build_function does not have a way to build functions with keyword arguments.

Audrius-St commented 1 month ago

From the Symbolics.jl documentation,

build_function(ex, args...;
               expression = Val{true},
               target = JuliaTarget(),
               parallel=nothing,
               kwargs...)

can I pass xa and xb as kwargs... set to Xo and Xf, respectively?

Or not. If yes, then I would appreciate being informed of the correct syntax. The documentation provides a definition, but no examples.

ChrisRackauckas commented 4 weeks ago

can I pass xa and xb as kwargs... set to Xo and Xf, respectively?

Those are for forwarding other keyword arguments, not for declaring new ones.