Euler-Lagrange Library Functions
EulerLagrange.DegenerateLagrangianSystem — Type
DegenerateLagrangianSystem(K, H, t, x, v, params = NamedTuple(); simplify = false,
scalarize = true, cse = true, nanmath = false)The equations of motion of a degenerate Lagrangian $L = K - H$, generated symbolically.
A degenerate Lagrangian is already first order in $n$ equations, so ω is the $n × n$ two-form $ω_{ij} = ∂ϑ_i/∂q_j - ∂ϑ_j/∂q_i$. See LagrangianSystem for the regular, $2n × 2n$ case.
The secondary constraint ψ takes both time derivatives, matching the LDAE interface: ψ(out, t, q, v, p, q̇, ṗ, params), computing $\dot p - \dot q \cdot ∇ϑ(t, q)$.
Keyword arguments
simplify: applySymbolics.simplifytoKandHbefore differentiating, and to the inverse two-formσ = inv(ω)and the resulting vector field. Off by default; seeLagrangianSystemfor the measurements. It is worth at most ~10% on the evaluation of theσ ∇Hvector field here, against ~270× the construction cost.scalarize: applySymbolics.scalarizetoKandH, expanding array expressions.cse: eliminate common subexpressions in the generated code. On by default; it binds constant nodes to temporaries as well, so results may differ fromcse = falsein the last bit.nanmath: emitNaNMathvariants of functions likelog,sqrtand^, which returnNaNoutside their real domain instead of throwing aDomainError. Off by default, so the generated code uses the ordinaryBasefunctions and an out-of-domain state is reported as an error rather than propagating silently.
EulerLagrange.HamiltonianSystem — Type
HamiltonianSystem(H, t, q, p, params = NamedTuple(); simplify = false, scalarize = true,
cse = true, nanmath = false)The equations of motion of the Hamiltonian H, generated symbolically.
Keyword arguments
simplify: applySymbolics.simplifytoHbefore differentiating. Off by default; seeLagrangianSystemfor the measurements behind that choice.scalarize: applySymbolics.scalarizetoH, expanding array expressions into components.cse: eliminate common subexpressions in the generated code. On by default; it binds constant nodes to temporaries as well, so results may differ fromcse = falsein the last bit.nanmath: emitNaNMathvariants of functions likelog,sqrtand^, which returnNaNoutside their real domain instead of throwing aDomainError. Off by default, so the generated code uses the ordinaryBasefunctions and an out-of-domain state is reported as an error rather than propagating silently.
EulerLagrange.LagrangianSystem — Type
LagrangianSystem(L, t, x, v, params = NamedTuple(); simplify = false, scalarize = true,
cse = true, nanmath = false)The equations of motion of a regular Lagrangian L, generated symbolically.
Since L is regular, the system is second order in $n$ equations, equivalently first order in $2n$; accordingly ω is the $2n × 2n$ two-form on $(q, \dot q)$. See DegenerateLagrangianSystem for the first-order, $n × n$ case.
Keyword arguments
simplify: applySymbolics.simplifytoLbefore differentiating. Off by default, because it is at best neutral and often much worse: it rewrites a sum of fractions into a common-denominator form whose derivatives are far more expensive both to build and to evaluate. Measured across every EulerLagrange-based problem in GeometricProblems (88 generated functions),simplify = truewas never faster to evaluate and up to 15× slower, at 23× the total construction cost.scalarize: applySymbolics.scalarizetoL, expanding array expressions into components.cse: eliminate common subexpressions in the generated code. On by default: measured over 45 generated functions in GeometricProblems it was faster to evaluate 18 times, slower once, and equal otherwise, with the wins concentrated in the forces (up to 8.4× on the 18-degree-of-freedom N-body force). Note that it emits larger code in most cases — it binds constant nodes to temporaries as well as shared subexpressions — so size is not a proxy for speed here. Binding constants also means results may differ fromcse = falsein the last bit.nanmath: emitNaNMathvariants of functions likelog,sqrtand^, which returnNaNoutside their real domain instead of throwing aDomainError. Off by default, so the generated code uses the ordinaryBasefunctions and an out-of-domain state is reported as an error rather than propagating silently.
EulerLagrange.substitute_acceleration — Method
substitute_acceleration(equ, dv, Λ)Replace the time derivatives of the velocities, dv = d/dt(v), by the algebraic variable Λ.
Any quantity built from Dt(∂L/∂v) — g, and hence EL = f - g and ψ = ṗ - g — contains the acceleration. substitute_ẋ_with_v removes only the first derivatives d/dt(x), so without this the generated code refers to an unevaluated Differential(t)(v[i]): a variable that does not exist, which makes the function throw as soon as it is called. Λ is the slot the generated signatures already carry for exactly this purpose.
EulerLagrange.substitute_parameters — Method
substitute_parameters(code, params)Rewrite the anonymous function code built by Symbolics.build_function so that it takes a single params argument in place of one argument per entry of params.
symbolize names the symbolic stand-in for parameter k as kₚ, so build_function emits a signature like (ˍ₋out, t, X, V, Gₚ, mₚ) and a body referring to Gₚ and mₚ. This returns the equivalent (ˍ₋out, t, X, V, params) with params.G and params.m in the body. When params is empty, only the params argument is appended.
This walks the expression rather than round-tripping it through string and Meta.parse. The generated code reaches ~1 MB for a matrix-valued quantity in 18 degrees of freedom, where the text round-trip is both slow and dependent on how Base.show happens to render an Expr.
EulerLagrange.substitute_time_derivatives — Method
substitute_time_derivatives(equ, dq, V, dp, F)Replace the time derivatives dq = d/dt(q) and dp = d/dt(p) by the algebraic variables V, F.
The residual forms EHq = q̇ - ∂H/∂p and EHp = ṗ + ∂H/∂q contain those derivatives, and nothing else in the pipeline removes them, so without this they reach build_function as derivatives of variables the generated function never receives.