# DifferentialRoot with parameters that "are not exact numbers"

In the course of developing an answer to 185859, I encountered the following difficulty. With

ss = DSolveValue[{D[(1 + z^2)*D[f[z, s], z], z] == (1 + z^2)^(-3)*s* f[z, s]},
f, {z, s}] /. {C[s] -> 1, C[s] -> 0};


the command

FindRoot[ss[5, s] == 3, {s, 3}]


produces two error messages,

DifferentialRoot::ieqn: The supplied equation in ... is not a linear differential equation with polynomial coefficients.

DifferentialRoot::ifprec: Parameters in ... are not exact numbers.

but nonetheless gives what appears to be the correct answer.

(* {s -> 2.83293} *)


However, if I attempt to substitute this result into ss,

N[ss[5, s] /. %]


I obtain these errors again but DifferentialRoot returns unevaluated. I would have expected 3. as the result.

My question is, since DifferentialRoot accepts parameters that "are not exact numbers" when used with FindRoot (or Plot, for that matter), how do I convince it to accept not-exact numbers more generally?

• Too hard for Mathematica. It will be easier to use  F = ParametricNDSolveValue[{D[(1 + z^2)*D[f[z], z], z] == (1 + z^2)^(-3)* s*f[z], f == 1, f' == 0}, f, {z, -10, 10}, {s}]; FindRoot[F[s] == 3, {s, 3}] Out[]= {s -> 2.83293} F[2.832929841106108] Out[]= 3. Nov 14, 2018 at 17:00
• @AlexTrounev I do not think it is too hard for Mathematica, because DifferentialRoot evaluates correctly when called from FindRoot, just not when called directly. Nov 14, 2018 at 18:34

Here's one way:

Block[{obj, z1, s1},
obj[z0_?NumericQ, s0_?NumericQ] := N[
{z1, s1} = SetPrecision[{z0, s0}, Infinity]; ss[z1, s1],
Precision@{z0, s0}];
sol = FindRoot[obj[5, s] == 3, {s, 3}]
]
(*  {s -> 2.83293}  *)


It takes about two minutes. With this approach, you can use the WorkingPrecision option and obj adjusts the precision automatically.

• This is very clever, although I need to think more about it. Note that I want to be able to substitute sol back into ss without errors. It appears that this can be done by replacing the second to the last line of your answer by {sol = FindRoot[obj[5, s] == 3, {s, 3}], tst = obj[5, s] /. sol}, which returns {{s -> 2.83293}, 3.}. Thanks. Nov 15, 2018 at 4:49