I have the following system of differential equations
systeqns[gn_, gp_, sn_, sp_, K_, a_,
b_, n0_, p0_, tg_] := {
n'[t] ==
If[t <= tg, gn, sn]*n[t]*(1 - (n[t] + p[t])/K) -
a*n[t] + b*p[t],
p'[t] ==
If[t <= tg, gp, sp]*p[t]*(1 - (n[t] + p[t])/K) +
a*n[t] - b*p[t],
tot'[t] == n'[t] + p'[t],
p[0] == p0,
n[0] == n0,
tot[0] == p0 + n0}
sol[gn_, gp_, sn_, sp_, K_, a_, b_,
n0_, p0_, tg_, ts_] :=
First[Evaluate[
NDSolve[systeqns[gn, gp, sn, sp,
K, a, b, n0, p0, tg], {n, p, tot}, {t, 0, tg + ts},
Method -> {"StiffnessSwitching"}, AccuracyGoal -> 1000,
WorkingPrecision -> 30, MaxSteps -> Infinity]]];
From which I calculate
avgR[gn_, gp_, sn_, sp_, K_, a_, b_,
n0_, p0_, tg_, ts_] :=
Log[(tot[tg + ts]/tot[0]) /.
sol[gn, gp, sn, sp, K, a, b, n0,
p0, tg, ts]]
I define some example values
tgex = 5; tsex = 5;gnex = 2;gpex = 2/10;snex = -2;spex = -2/10;bex = 1/10000;n0ex = 1;p0ex = 1/1000;Kex = 10^9;
I am then interested in determining the value of a that maximizes avgR. Graphically, this would be around a=0.2:
vals = Table[{10^pow,
avgR[gnex, gpex, snex, spex, Kex,
10^pow, bex, n0ex, p0ex, tgex, tsex]}, {pow, -4, 0, 1/10}];
ListLogLinearPlot[vals, PlotRange -> All, Frame -> True,
FrameLabel -> {"Switching rate a", "Average population growth rate"},
PlotStyle -> {Thick}, PlotTheme -> {"Classic", "LargeLabels"},
Joined -> True]

But trying to calculate this value using NMaximize returns an error:
NMaximize[{avgR[gnex, gpex, snex, spex, Kex,
a, bex, n0ex, p0ex, tgex, tsex],
a > 10^-4 && a < 1}, {a, 1/10}, Method -> "DifferentialEvolution"]
NDSolve::ndnum: Encountered non-numerical value for a derivative at t == 0. >>
Any thoughts what I am doing wrong?
Interpolating the values first does work btw, but that is no good for me, since I would eventually like to maximise both a and b, and this would require me calculating too big a grid :
f = Interpolation[vals];
Maximize[{f[a], 10^-4 < a < 1}, a]
{6.507434893938602167476249656, {a ->
0.20613498164678882000313750361}}
So I am looking for a solution to get NMaximize working...
a_?NumericQto restrict evaluation ofsolto numeric values ofa, which fixes the problem, is explained in the linked resources of this answer to the "pitfalls" question. – Michael E2 Dec 03 '14 at 12:44WhenEvent[]+ParametricNDSolve[]is much more convenient to use in situations like this. – J. M.'s missing motivation Jul 01 '16 at 01:05