I’m trying to apply the chain rule to effectively do a change of variables but I can’t figure out a rule that works.
Here is an example that I think should work.
@variables a b c(a,b)
r = @rule Differential(a)(~x) => Differential(a)(b)*Differential(b)(~x)
r(D(a)(c)) # nothing
What am I doing wrong?
Related question:
Is there a faster way of generating the substitution dictionary that does the same thing as the rule above. Below I’ve included the code I’ve written to generate the substitution Dict. Does anyone see a faster way to make this dictionary?
using Symbolics, Combinatorics
D = Differential
# The intention of this substitution code is
# to transform derivatives w.r.t. x of an unknown
# function ϕ into derivatives w.r.t. ξ
# The backward transform x(ξ) is known and so are its derivatives
# and dξ/dx is known as the inverse of the jacobian of x(ξ)
# Thus everything is to be written in terms of
# derivatives w.r.t. ξ of the functions ϕ and dξ/dx
N = 2
# x are the real coordinates
# ξ are the transformed coordinates
# dξdx is a workaround since (D(ξ[2])*D(x[1]))(ξ[1]) evaluates to 0
# dξdx[i,j] = dξ[j]/dx[i]
# ϕ is an unknown function
@variables x[1:N] (ξ(x...))[1:N] (dξdx(..))[1:N, 1:N] ϕ(..)
ϕ = ϕ(x...,ξ...)
dξdx = dξdx(ξ...,x...)
# The maximum number of derivative that
# the substitution dictionary should contain
maxdiff = 3
# This function is extreamly slow for N > 2
function generatesubsdict(N=N, maxdiff=maxdiff)
outputdict = Dict{Num,Num}()
# Generate all possible permutations of derivatives w.r.t. ξ
# since any one of them could appear in an equation
# differentiated w.r.t. x
xiperms = multiset_permutations.(
[repeat(1:N,maxdiff)], 1:maxdiff
) |> Iterators.flatten .|> x->x .|> x->ξ[x]
xidiffs = [prod(D.(xi)) for xi in xiperms]
# This loops over all xs
for i in 1:N
# Substitute all d/dx = sum(dξ/dx*d/dξ over ξ)
outputdict[D(x[i])(ϕ)] =
sum(dξdx[i,xi]*D(ξ[xi])(ϕ) for xi in 1:N)
# Same for all possible derivatives of ϕ w.r.t. ξ
for dxi in xidiffs
phidiff = dxi(ϕ)
outputdict[D(x[i])(phidiff)] =
sum(dξdx[i,xi]*D(ξ[xi])(phidiff)
for xi in 1:N)
end
# These are the cases of differentiating ξ w.r.t. x multiple times
# d/dx_i dξ_j/dx_k = sum((d/dξ_l dξ_j/dx_k)*dξ_l/dx_i over l)
for j in 1:N, k in 1:N
outputdict[D(x[i])(dξdx[j,k])] =
sum(D(ξ[xi])(dξdx[j,k])*dξdx[i,xi] for xi in 1:N)
for dxi in xidiffs
xidiff = dxi(dξdx[j,k])
outputdict[D(x[i])(xidiff)] =
sum(D(ξ[xi])(xidiff)*dξdx[i,xi]
for xi in 1:N)
end
end
end
return outputdict
end