# Non-negative ODE solution

**URL:** <https://discourse.julialang.org/t/non-negative-ode-solution/23449>\
**Category:** General Usage\
**Created:** [April 23, 2019, 5:23pm UTC](https://discourse.julialang.org/t/non-negative-ode-solution/23449 "2019-04-23T17:23:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dg.aragones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dg.aragones/32/11275_2.png) [@dg.aragones](https://discourse.julialang.org/u/dg.aragones)\
**Post date:** [April 23, 2019, 5:23pm UTC](https://discourse.julialang.org/t/non-negative-ode-solution/23449/1 "2019-04-23T17:23:35Z")

</div>

Is there any Julia option equivalent to “Nonnegative” in “odeset” in Matlab?

Here is the documentation about the function I’m talking about:

> **[Nonnegative ODE Solution
- MATLAB & Simulink](https://www.mathworks.com/help/matlab/math/nonnegative-ode-solution.html)**
>
> This topic shows how to constrain the solution of an ODE to be nonnegative.

I think it’s a very useful function and it’d be nice to have something similar in Julia.

Thanks in advance!

---

<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:** [April 23, 2019, 5:34pm UTC](https://discourse.julialang.org/t/non-negative-ode-solution/23449/2 "2019-04-23T17:34:03Z")

</div>

Hey,  
There are two ways to do this. One is to use `isoutofdomain`. It’s documented with the other solver options:

[http://docs.juliadiffeq.org/latest/basics/common\_solver\_opts.html#Miscellaneous-1](http://docs.juliadiffeq.org/latest/basics/common_solver_opts.html#Miscellaneous-1)

`isoutofdomain = (u,p,t)->any(x->x<0,u)` makes any step with a negative value get rejected and use a smaller `dt`. This is a method that is always safe, but may get a few more rejections.

The other method is to use `PositiveDomain()` as a callback on the problem. This uses continuous extensions in the event handling to perform the pullback to the positive time.

[http://docs.juliadiffeq.org/latest/features/callback\_library.html#PositiveDomain-1](http://docs.juliadiffeq.org/latest/features/callback_library.html#PositiveDomain-1)

This is more like MATLAB’s version. This is less safe than `isoutofdomain` since it requires that the function is differentiable around zero in order for the interpolation to make sense, but it can be (a tiny bit) faster.

---

<div class="post-metadata">

**Author:** ![VitaminBrad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vitaminbrad/32/17350_2.png) [@VitaminBrad](https://discourse.julialang.org/u/VitaminBrad)\
**Post date:** [August 21, 2020, 3:02pm UTC](https://discourse.julialang.org/t/non-negative-ode-solution/23449/3 "2020-08-21T15:02:57Z")

</div>

Hi Chris,

it seems these links have broken sometime in the past year.

I tried the `isoutofdomain` approach and I got the following warning and the simulation would stop early.

 ![](https://global.discourse-cdn.com/julialang/original/3X/2/0/20dd8f4339557a6d333c07a4d4fb934b67f9cf79.png)

Is there an example available to see where the line `PositiveDomain()` goes? Thanks!

Best,  
Brad

---

<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:** [August 21, 2020, 3:21pm UTC](https://discourse.julialang.org/t/non-negative-ode-solution/23449/4 "2020-08-21T15:21:21Z")

</div>

Usually that happens if the true solution is negative. Are you sure it’s not?

---

<div class="post-metadata">

**Author:** ![VitaminBrad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vitaminbrad/32/17350_2.png) [@VitaminBrad](https://discourse.julialang.org/u/VitaminBrad)\
**Post date:** [August 21, 2020, 7:47pm UTC](https://discourse.julialang.org/t/non-negative-ode-solution/23449/5 "2020-08-21T19:47:02Z")

</div>

How horribly embaressing… I thought I had correctly addressed the local vs. global scope situation with regards to using the `eval` function inside of the function to solve (e.g. latka\_volterra(du,u,p,t)), but it seems I didn’t fully. I wasn’t updating states correctly that depending on the values of other states. It’s working beautifully now and I’ll begin fitting soon. 😁

`function tau_agg!(du, u_local, p, t)`  
`global u = u_local`  
` du[:] = eval.(doyle_eqs[:,5])`  
`end`

This appears to work now. 🙂

Shall I delete my comments to prevent confusion for future onlookers?

Sincerest apologies for taking your time on a personal fumble. I’ll try to make it the last.

---

<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:** [August 21, 2020, 7:53pm UTC](https://discourse.julialang.org/t/non-negative-ode-solution/23449/6 "2020-08-21T19:53:36Z")

</div>

No worries. I think I need to just keep dropping that nugget around that `isoutofdomain` isn’t magic: it makes things not numerically leave the domain by forcing solver rejections whenever it does, but if the solution truly leaves the domain, you’ll get dtmin issues as it tries to make the calculation more and more accurate to not leave the domain, but dt-\>0 as it accurately keeps leaving the domain.
