How to obtain val.argument of KeySet of OrderCollection?

Assume given

flatten(a) = collect(Iterators.flatten(a))

Assume furthermore given

julia> diff_eom.equations 
OrderedCollections.OrderedDict{Symbolics.Num, Symbolics.Equation} with 1 entry:
  x(t) => Differential(t)(Differential(t)(x(t))) - F*cos(t*ω) + x(t)*(ω0^2) ~ 0

Then the following two functions work beautifully and as a charm (stolen from HarmonicBalance.jl)

julia> keys(diff_eom.equations)
KeySet for a OrderedCollections.OrderedDict{Symbolics.Num, Symbolics.Equation} with 1 entry. Keys:
  x(t)

and

julia> flatten(unique([x.val.arguments for x in keys(diff_eom.equations)]))
1-element Vector{Any}:
 t

Assume wishing to extend this to (and later to N >> 1 ODEs)

julia> diff_eq
System of 2 differential equations
Variables:       (x(t))[1], (x(t))[2]
Harmonic ansatz: (x(t))[1] => ;   (x(t))[2] => ;   

Differential(t)(Differential(t)((x(t))[1])) - k*(x(t))[2] + (x(t))[1]*(ω0^2) ~ F*cos(t*ω)
Differential(t)(Differential(t)((x(t))[2])) - k*(x(t))[1] + (x(t))[2]*(ω0^2) ~ 0

Then the keys become

julia> keys(diff_eq.equations)
KeySet for a OrderedCollections.OrderedDict{Symbolics.Num, Symbolics.Equation} with 2 entries. Keys:
  (x(t))[1]
  (x(t))[2]

How do I get the t out in this case?

Merely repeating above is insufficient as shown below (Vector{Any} is no good sign)

julia> flatten(unique([x.val.arguments for x in keys(diff_eq.equations)]))
4-element Vector{Any}:
  x(t)
 1
  x(t)
 2

What is an appropriate syntax here? Thanks.

Part of the issue is a syntax issues.

For the scalar case, this works

julia> @variables t, s(t)
2-element Vector{Symbolics.Num}:
    t
 s(t)

julia> s.val.arguments
1-element Vector{Any}:
 t

How do I make this work for the vector-valued case? How do I extract t from

julia> @variables t, (v(t))[1:2]
2-element Vector{Any}:
 t
  (v(t))[1:2]

Below does not work yet.

julia> v[1].val.arguments
2-element Vector{Any}:
  v(t)
 1

Thanks.

Try (using your last example):
v[1].val.arguments[1].val.arguments

julia> v 
(v(t))[1:2]

julia> v[1].val.arguments[1].val.arguments
ERROR: type Term has no field val.
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] throw_no_field(::Val{:Term}, s::Symbol)
   @ Unityper ~/.julia/packages/Unityper/BiodR/src/compactify.jl:505
 [3] getproperty(x::SymbolicUtils.BasicSymbolic{Vector{Real}}, s::Symbol)
   @ SymbolicUtils ~/.julia/packages/Unityper/BiodR/src/compactify.jl:310
 [4] top-level scope
   @ REPL[82]:1
julia> v
(v(t))[1:2]

julia> Symbolics.value(v)
v(t)

julia> arguments(Symbolics.value(v))
1-element Vector{Any}:
 t

julia> only(arguments(Symbolics.value(v)))
t
julia> zt
3-element Vector{Num}:
 (z(t))[1]
 (z(t))[2]
 (z(t))[3]

julia> only(arguments(arguments(Symbolics.value(zt[1]))[1]))
t

I don’t use Symbolics.jl but there’s probably a better way than this, but it works. You could define a function get_farg (or whatever) and use multiple dispatch to give convenient methods for the different forms of your symbolic variables

2 Likes