Skip to content

Commit be112aa

Browse files
committed
Change independent variable of ODEs with array variables
1 parent 8513736 commit be112aa

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

src/systems/diffeqs/basic_transformations.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,25 @@ function change_independent_variable(
153153
@set! sys.eqs = [get_eqs(sys); eqs] # add extra equations we derived
154154
@set! sys.unknowns = [get_unknowns(sys); [iv1, div2_of_iv1]] # add new variables, will be transformed to e.g. t(u) and uˍt(u)
155155

156+
# A utility function that returns whether var (e.g. f(t)) is a function of iv (e.g. t)
157+
function is_function_of(var, iv)
158+
# Peel off outer calls to find the argument of the function of
159+
if iscall(var) && operation(var) === getindex # handle array variables
160+
var = arguments(var)[1] # (f(t))[1] -> f(t)
161+
end
162+
if iscall(var)
163+
var = only(arguments(var)) # e.g. f(t) -> t
164+
return isequal(var, iv)
165+
end
166+
return false
167+
end
168+
156169
# Create a utility that performs the chain rule on an expression, followed by insertion of the new independent variable:
157170
# e.g. (d/dt)(f(t)) -> (d/dt)(f(u(t))) -> df(u(t))/du(t) * du(t)/dt -> df(u)/du * uˍt(u)
158171
function transform(ex::T) where {T}
159172
# 1) Replace the argument of every function; e.g. f(t) -> f(u(t))
160173
for var in vars(ex; op = Nothing) # loop over all variables in expression (op = Nothing prevents interpreting "D(f(t))" as one big variable)
161-
is_function_of_iv1 = iscall(var) && isequal(only(arguments(var)), iv1) # of the form f(t)?
162-
if is_function_of_iv1 && !isequal(var, iv2_of_iv1) # prevent e.g. u(t) -> u(u(t))
174+
if is_function_of(var, iv1) && !isequal(var, iv2_of_iv1) # of the form f(t)? but prevent e.g. u(t) -> u(u(t))
163175
var_of_iv1 = var # e.g. f(t)
164176
var_of_iv2_of_iv1 = substitute(var_of_iv1, iv1 => iv2_of_iv1) # e.g. f(u(t))
165177
ex = substitute(ex, var_of_iv1 => var_of_iv2_of_iv1; fold)

0 commit comments

Comments
 (0)