I’m new to Julia and solving ODE’s in Julia and expect I’m overlooking something quite simple. I would expect the two functions below, test_1! and test_2! which both define the same simple system of ODEs, to perform identically. However test_1! erroneously produces a solution constant in time which is clearly incorrect while test_2! works fine.
Thank you in advance for any insights!
function test_1!(du, u, p, t)
W = p
du = copy(W)
function test_2!(du, u, p, t)
W = p
for i in 1:length(W)
du[i] = W[i]
Random.seed!(1234); # for reproducibility
nOsc = 5;
theta0 = 2 * pi * rand(Float64, nOsc);
W = 0.5 * randn(Float64, nOsc);
prob = ODEProblem(test_1!, theta0, (0, 20), [W]); # doesn't work. sol.u is constant
#prob = ODEProblem(test_2!, theta0, (0, 20), [W]); # works as expected.
sol = solve(prob)
du = copy(W) changes what the variable name
du refers to.
With the for loop you are instead modifying the array that the variable name
du refers to. Another way you could do that is with a line like
du .= W.
Thank you very much! Can you give me guidance or a link reference to when I need to use .= instead of =? For example suppose I modify du after initialization. Which assignment would I use? Is this correct?
du .= W
du = du + f(u)
Or would I continue to use .= like so?
du .= W
du .= du + f(u)
.= can’t initialize anything, the variable already needs to exist before you use it.
You would want to continue to use
.= as in your second example.
You can learn more about its use partway through this section of the documentation:
and in this section:
Yet another correct solution is
function test_3!(du, u, p, t)
W = p
du[:] = W
Some discussion of using
[:] on the left of the assignment symbol
= is at Values vs. Bindings: The Map is Not the Territory · John Myles White