1

As a simple example let's consider the function $f(x) = x \left(1-\frac{x}{3}\right) \left(\frac{x}{10}-1\right)$:

f[x_] := x (1-x/3) (x/10-1)

I want to find, $r(c)$, the root of the function $f(x)+c$ that is closer to $0$ for $c\in[0,1]$.

The value of the local minimum of $f$ is $c_{\text{min}}=-0.642389\dots$, this implies that for $c\le -c_{\text{min}}$, $r(c) < 1.38$ and for $c > -c_{\text{min}}$, $r(c) > 10.25$.

The problem of course is that if I call FindRoot with $0$ as the initial point,for $c=-c_{\text{min}}+\varepsilon$ the function $f(x)+c$ come close to the $x$ axis and the algorithm takes too long to converge.

Is there any way to tell mathematica that if it takes too long to find a root starting at 0, it should instead start at 10?

I would like to be able to plot the discontinuous function $r(c)$.

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
tst
  • 953
  • 6
  • 13
  • @AccidentalFourierTransform I forgot some minus signs. Sorry about that. I fixed it now. – tst Jun 12 '18 at 14:09
  • Perhaps try NSolve[eq, x, Reals] and analyze the root closest to zero. Might depend on how complicated your actual $f(x)$ is. – Michael E2 Jun 12 '18 at 14:15

2 Answers2

3

You can use NDSolveValue for a function that can't be handled with NSolve. Your function:

f[x_] := x (1-x/3) (x/10-1)

eqn = f[x[t]] + t == 0;

The corresponding ODE:

ode = D[eqn, t];
ode //TeXForm

$\left(1-\frac{x(t)}{3}\right) \left(\frac{x(t)}{10}-1\right) x'(t)+\frac{1}{10} \left(1-\frac{x(t)}{3}\right) x(t) x'(t)-\frac{1}{3} \left(\frac{x(t)}{10}-1\right) x(t) x'(t)+1=0$

To use NDSolveValue we will need initial conditions. Clearly:

t == -f[x[t]]

so we can use the initial conditions:

x[-f[0]] == 0

x[0] == 0

or

x[-f[11]] == 11

x[44/15] == 11

Now we are ready to use NDSolveValue:

left = NDSolveValue[
    {ode, x[-f[0]] == 0},
    x,
    {t, 0, 1},
    "ExtrapolationHandler" -> {Infinity&, "WarningMessage"->False}
];

right = NDSolveValue[
    {ode, x[-f[11]] == 11},
    x,
    {t, 0, 1}
];

min[t_] := Min[left[t], right[t]]

NDSolveValue::ndsz: At t == 0.6423882561207013`, step size is effectively zero; singularity or stiff system suspected.

(See @MichaelE2's answer to the question Suppress extrapolation of interpolating function in a ContourPlot for an explanation of the "ExtrapolationHandler" option)

Visualization:

Plot[min[t], {t, 0, 1}]

enter image description here

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
0

Is this what you want?

Using

r[c_] := x /. NSolve[f[x] + c, x, Reals]
Show[
 Plot[r[c], {c, 0, 1/405 (-442 + 79 Sqrt[79])}], 
 Plot[r[c], {c, 1/405 (-442 + 79 Sqrt[79]), 1}]
, PlotRange -> All]

I get the plot

enter image description here

in under 0.3 seconds on my laptop.

To plot $r(c)$, just use

Plot[Min[r[c]], {c, 0, 1}, Exclusions -> {1/405 (-442 + 79 Sqrt[79])}]

which yields

enter image description here

as one would expect.

  • Well, yes, but I would like it to be possible without having explicit information about $f$. I know that my $f$ behaves like that locally, and I want the smallest positive root. – tst Jun 12 '18 at 14:41
  • Also NSolve cannot deal with any function and sometimes does not work. – tst Jun 12 '18 at 14:45