You can have NDSolve
do the integration but not save the results (set second argument to {}
). Then use EvaluationMonitor
to save points at whatever interval dt
you please. This uses much less memory; in fact for dt = 10^-2
, the memory use is negligible for the settings below.
Since parameters were not given by the OP, I used the simplest choices. Also, waiting for ten billion steps seemed silly for a proof-of-concept trial, so I lengthened the step size.
MaxMemoryUsed[]
SeedRandom[1];
R[t_Real] := RandomVariate[NormalDistribution[0, 1]];
values = {k1 -> 1, k2 -> 1};
lastt = -1;
dt = 10^-2;
{foo, {pts}} =
Reap@NDSolve[{(-x''[t] - k1*x'[t] + k2*R[t]) == 0, x[0] == 0, x'[0] == 0} /. values,
{}, {t, 0, 10},
StartingStepSize -> 10^-5,
Method -> {"FixedStep", Method -> "ExplicitEuler"}, MaxSteps -> ∞,
EvaluationMonitor :> If[t >= lastt + dt, lastt = t; Sow[{t, x[t]}]]
];
sol = Interpolation[pts];
MaxMemoryUsed[]
Plot[sol[t], {t, 0, 10}]
(* 37243360 *)
(* 37243360 *)
When the integral x
is requested, the memory use by NDSolve
is significantly higher:
MaxMemoryUsed[]
SeedRandom[1];
R[t_Real] := RandomVariate[NormalDistribution[0, 1]];
values = {k1 -> 1, k2 -> 1};
lastt = -1;
dt = 10^-2;
{foo, {pts}} =
Reap@NDSolve[{(-x''[t] - k1*x'[t] + k2*R[t]) == 0, x[0] == 0, x'[0] == 0} /. values,
x, {t, 0, 10},
StartingStepSize -> 10^-5,
Method -> {"FixedStep", Method -> "ExplicitEuler"}, MaxSteps -> ∞,
EvaluationMonitor :> If[t >= lastt + dt, lastt = t; Sow[{t, x[t]}]]
];
sol = Interpolation[pts];
MaxMemoryUsed[]
Plot[x[t] /. First[foo] // Evaluate, {t, 0, 10}]
(* 37243360 *)
(* 127874624 *)
values
do? Is there a reason you are usingExplicitEuler
? You would benefit by letting Mathematica choose the solver automatically or use perhaps the magic-wandMethod->"LSODA"
. Also, why not just let t range from 0 to a very large number (for long term behavior)? $\endgroup$