I have a simple stochastic differential equation (SDE) with white noise:

mysde[q_, I_, n0_, sd_] := 
    \[DifferentialD]n[t] == 
      ( I - q n[t]) \[DifferentialD]t + sd \[DifferentialD]w[t], n[t], 
    {n, n0}, t, w \[Distributed] WienerProcess[]]

I want to impose a condition that n[t] cannot fall below zero. At below zero, or an arbitrarily low value of n[t], it is considered zero. I am not sure how to implement this in the ItoProcess function and/or in the numerical solution:

sol[q_, I_, n0_, sd_] := RandomFunction[mysde[q, I, n0, sd], {0, 100, 0.1}, 1]

The variable drops below zero many times, which is not a desired behaviour:

With[{q = 2, I = 0.1, n0 = 1, sd = 0.1}, 
  Show[ListLinePlot[sol[q, I, n0, sd]], ImageSize -> 400]]

What are some ways to implement such a condition?

I have tried various functions on n[t] within the ItoProcess[], to attempt to re-set negative values of n[t] to zero, like If[], Max[], Clip[], and Piecewise[] to no avail. Any reasons why these functions do not dynamically work within the solver?

Also is there a way to extract the values of the noise, w[t], in a particular simulated path of the temporal data timeseries object?

One potential solution, which is not confirmed to be correct, is to write the equation for the log of my variable, ln[t] and to use the Geometric Brownian motion random process formulation, obtaining:

logsde[q_, I_, ln0_, sd_] := 
    \[DifferentialD]ln[t] == 
      ( I - q ln[t] - sd^2/2) \[DifferentialD]t + sd \[DifferentialD]w[t], ln[t], 
   {ln, ln0}, t, w \[Distributed] GeometricBrownianMotionProcess[I - q ln[t], sd, n0]]

logsol[q_, I_, ln0_, sd_] := RandomFunction[logsde[q, I, ln0, sd], {0, 100, 0.1}, 1]

Then I extract the simulated values, and exponentiate them to obtain the time series or path in the original scale:

td = With[{q = 0.1, I1 = 0.1, ln0 = 1, sd = .1}, 
  logsol[q, I1, ln0, sd]];

However I have lost the stochastic signal in this model; the simulation smooths out and looks continuous with no noise, except at the beginning of the simulation. This is obviously an incorrect formulation. What did I do here? How might I formulate this properly?

Are there other approaches?

So overall I have three questions:

  1. How to implement a boundary condition in ItoProcess[] for one of the state variables?
  2. How to recover the simulated values of the random variable? <- self-answered below
  3. How to properly specify a log-transformed version of the ItoProcess[]?
  • $\begingroup$ What is the mathematical model of "not below zero"? Say, should it bounce or once zero is always zero? Or It just needed to draw a plot, where the negative part is turned to aero? $\endgroup$
    – Andrew
    Jun 27 '13 at 7:38
  • $\begingroup$ I disagree with your statement that "is not supposed to happen in this model"; the solution to your top SDE is a normally distributed random variable with parameters you can get with Mean[mysde[q, ii, n0, sd][t]] and StandardDeviation[mysde[q, ii, n0, sd][t]] so yes, it can go negative. $\endgroup$ Jun 27 '13 at 8:21
  • $\begingroup$ b.gatessucks you are right, the model as specified, it does happen. However, I want to impose the condition that the variable n[t] cannot go below zero (or an arbitrarily small value). The question is how to modify the equation or include a condition in the model that would prevent negative values from occuring. $\endgroup$
    – ambein
    Jun 27 '13 at 14:34
  • $\begingroup$ To answer Andrew's question, the variable should be able to recover from zero. $\endgroup$
    – ambein
    Jun 27 '13 at 14:38
  • $\begingroup$ Would taking the absolute value of $n$ do? $\endgroup$
    – Andrew
    Jun 27 '13 at 14:48

This an answer of question 2, "How to recover the simulated values of the random variable?":

Just specify the random variable in the state vector argument. For example,

mysde[q_, I1_, n0_, sd_] := ItoProcess[
{\[DifferentialD]n[t] == 
( -q n[t]) \[DifferentialD]t + I1 \[DifferentialD]t + \[DifferentialD]w[t]}, 
{n[t], I1 + w[t]}, {n, n0}, t, w \[Distributed] WienerProcess[0, sd]]

This sink population has white noise inputs with mean, I1, and standard deviation, sd. The state vector is argument x taken by the ItoProcess function, {n[t], I1 + w[t]} here. The distribution of inputs is the stochastic variable, I1 + w[t], which I am interested in.

So simulate the stochastic model with initial condition and parameters:

sol[q_, I1_, n0_, sd_] := RandomFunction[mysde[q, I1, n0, sd], {0, 1000, 0.1}, 1]
td = With[{q = 1, I1 = 0.1, n0 = 0.1, sd = 0.01}, sol[q, I1, n0, sd]];

The object td gives the solution for a stochastic simulation. A run of all the variables may be visualized as a time series:


Extract the time series of just one of the variables, the stochastic forcing variable in this case, with,

stochvar = td["States"][[1]][[All, 1]]]

Do what you want with the data, for example:


I am sure there are more elegant approaches, but hopefully this provides a good example for some basics of the SDE functions in Mathematica.


The condition that n[t] cannot fall below zero is an inherent part of a solution algorithm that is applied for a numerical SDE solution and preserves a positivity of solution domain.

Typically, such problem is solved by using of implicit numerical solution. Currently, Mathematica has a support only for explicit methods for ItoProcess command (the brief explanation about the difference between analogous methods for non-stochastic DE).

For example, the implicit Milstein method for SDE of the form

$\mathrm{d} X_t = a(X_t) \, \mathrm{d} t + b(X_t) \, \mathrm{d} W_t$

is given by (may be compared to explicit one in the link above)

$Y_{n + 1} = Y_n + a(Y_{n+1}) \Delta t + b(Y_n) \Delta W_n + \frac{1}{2} b(Y_n) b'(Y_n) \left( (\Delta W_n)^2 - \Delta t \right)$

and, sometimes, after some basic math may be implemented by RecurrenceTable command as described here. At more complex case, each iteration step has to be solved numerically...

Additional information may be found, for example, in Ch. 12 of Kloeden & Platen, "Numerical Solution of Stochastic Differential Equations", 3rd, Springer, 1999.

  • $\begingroup$ Thank you so much, this is very helpful. I will look into this over the next several weeks. $\endgroup$
    – ambein
    Nov 26 '15 at 0:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.