# In-place functions in definition of ODEProblem (DifferentialEquations)

**URL:** https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029
**Category:** Modelling & Simulations
**Tags:** question
**Created:** [October 17, 2019, 3:08pm UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029 "2019-10-17T15:08:11Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [October 17, 2019, 3:08pm UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/1 "2019-10-17T15:08:11Z")

</div>

I am struggling with something as basic as definition of a function for ODEProblem using DifferentialEquations package:

In [Example 1 in the documentation for the package](http://docs.juliadiffeq.org/latest/tutorials/ode_example.html#Example-1-:-Solving-Scalar-Equations-1), the ODE is defined by a function on the right hand side of the ODE `d/dt u(t) = f(u,p,t)`, that is

```julia
f(u,p,t) = 1.01*u

```

Then in the following [Example 2](http://docs.juliadiffeq.org/latest/tutorials/ode_example.html#Example-2:-Solving-Systems-of-Equations-1) that deals with systems of ODEs, an in-place function is defined, namely

```julia
function lorenz(du,u,p,t)
 du[1] = 10.0*(u[2]-u[1])
 du[2] = u[1]*(28.0-u[3]) - u[2]
 du[3] = u[1]*u[2] - (8/3)*u[3]
end

```

In both cases, the `ODEProblem` is defined by including the name of the corresponding function among the input arguments to the `ODEProblem` constructor, that is, `f` and `lorenz`, respectively.

In the former (scalar) case, the function is a standard (output assigning) function while in the latter (multidimensional) case it is an _in-place_ function, isn’t it? (By the way, shouldn’t then the latter function be named `lorenz!` and not just `lorenz`?)

Now, what if I define the problem from Example 1 using an in-place function also in the scalar case:

```julia
using DifferentialEquations
using Plots

function f!(du,u,p,t)
    du = 10.01*u
end

u0=1/2
tspan = (0.0,1.0)

prob = ODEProblem(f!,u0,tspan)
sol = solve(prob,Tsit5(),reltol=1e-8,abstol=1e-8)

plot(sol)

```

The above code returns an error `ERROR: MethodError: no method matching similar(::Float64)` after calling `solve`.

Thanks for any shared insight.

---

<div class="post-metadata">

### Author: ![ElOceanografo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eloceanografo/32/624_2.png) [@ElOceanografo](https://discourse.julialang.org/u/ElOceanografo)
#### Post date: [October 17, 2019, 3:41pm UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/2 "2019-10-17T15:41:17Z")

</div>

The solver seems to assume that any in-place function will be array valued, and is trying to allocate a cache for itself to use internally while integrating. It calls `similar` on `u0`, but `u0` is just a `Float64`, so it chokes. Changing the problem definition to

```julia
prob = ODEProblem(f!, [u0], tspan)

```

makes it run.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [October 17, 2019, 4:22pm UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/3 "2019-10-17T16:22:02Z")

</div>

Exactly. Also, `du = 1.01u` isn’t actually in place since it’s not mutating anything on the heap, so that won’t work. Stack allocated variables thus need to be handled in a very different manner.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [October 17, 2019, 4:22pm UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/4 "2019-10-17T16:22:46Z")

</div>

> [@zdenek\_hurak](#):
>
> By the way, shouldn’t then the latter function be named `lorenz!` and not just `lorenz` ?

It should be. I’d gladly accept a PR.

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [October 17, 2019, 8:07pm UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/5 "2019-10-17T20:07:41Z")

</div>

Well, indeed, the solver no longer complains but the solution obtained in this way is certainly not correct (it is just constant).

Chris points out below that my `f!` function is actually not `in-place`. I confess at this point I am lost - I cannot see a difference with respect to the `lorenc` example (shown above). I guess this may have something to do with the difference between scalars and vectors used as function arguments.

---

<div class="post-metadata">

### Author: ![ElOceanografo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eloceanografo/32/624_2.png) [@ElOceanografo](https://discourse.julialang.org/u/ElOceanografo)
#### Post date: [October 17, 2019, 8:57pm UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/6 "2019-10-17T20:57:54Z")

</div>

This is a good explanation of stack- vs. heap-allocated variables: [memory management - What and where are the stack and heap? - Stack Overflow](https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap)

Basically, when `du` is a vector, it is a heap variable. When it is scalar, it a stack variable. The scalar `du` inside the function is created during the function call, and then forgotten when the function returns. It’s referring to a different location in memory than the `du` outside the function, so you can’t mutate it.\*

```julia
du = 0.0
function foo!(u)
    du = 2.0 * u
    println("inside the function, du = $du")
end

println(du)
# 0.0
foo!(10)
# inside the function, du = 20.0
println(du)
# 0.0

```

\*Actually you can, if you say `global du = 2.0 * u` in the function body. But there’s no good reason to, since allocating a single value on the stack will be as fast or faster than mutating a single-element array on the heap. Once an array gets big enough, though, it becomes faster to overwrite it in-place, rather than allocate a new block of memory for a new array.

---

<div class="post-metadata">

### Author: ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)
#### Post date: [March 27, 2020, 8:57am UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/7 "2020-03-27T08:57:26Z")

</div>

I just wanted to make sure about the in-place function definition here. Is the exclamation mark `!` at the end of the function `lorenz!` is simply a convention or does it do something?

When I run

```julia
function lorenz(du,u,p,t)
 du[1] = 10.0*(u[2]-u[1])
 du[2] = u[1]*(28.0-u[3]) - u[2]
 du[3] = u[1]*u[2] - (8/3)*u[3]
end

```

and

```julia
function lorenz!(du,u,p,t)
 du[1] = 10.0*(u[2]-u[1])
 du[2] = u[1]*(28.0-u[3]) - u[2]
 du[3] = u[1]*u[2] - (8/3)*u[3]
end

```

I get the same results. I just wanted to make sure that this is how it should be.

Just wanted to mention that I saw the answer [here in stack overflow](https://stackoverflow.com/questions/39293082/mutating-function-in-julia-function-that-modifies-its-arguments) about in-place functions, but I still wanted to make sure it is fine to use `lorenz` and `lorenz!`

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [March 27, 2020, 9:16am UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/8 "2020-03-27T09:16:08Z")

</div>

Roi,

the exclamation mark (the bang) really does NOTHING. It is just another symbol, a part of the name. I really mean it, you can view it as a symbol “A” or “3”. The convention in Julia community (not always adhered to) is to include it in the function name if the function modifies the input arguments.

---

<div class="post-metadata">

### Author: ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)
#### Post date: [March 27, 2020, 9:28am UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/9 "2020-03-27T09:28:38Z")

</div>

Thanks so much! I guess I just wanted to hear it from someone.

---

<div class="post-metadata">

### Author: ![will](https://avatars.discourse-cdn.com/v4/letter/w/90ced4/32.png) [@will](https://discourse.julialang.org/u/will)
#### Post date: [March 8, 2023, 12:08pm UTC](https://discourse.julialang.org/t/in-place-functions-in-definition-of-odeproblem-differentialequations/30029/10 "2023-03-08T12:08:21Z")

</div>

Yes, it’s a convention, 5th entry in in the style guide:  
[https://docs.julialang.org/en/v1/manual/style-guide/#bang-convention](https://docs.julialang.org/en/v1/manual/style-guide/#bang-convention)

Also confused me! (no pun intended 🙂 )
