# Solve the interpolating function

I would have asked how to obtain the x given the y in an interpolating function, and I found the answer from here. But another question raised.

I was dealing with measurement of the spectral characteristics, and I had a set of data, where x is the wavelength, y is the light intensity.And I needed to find out the wavelength to which the half maximum light intensity corresponds. But the useful part of data was not enough. In order to more accurately, I used Interpolation to get a InterpolatingFunction.

When I used Solve to obtain the half maximum intensity corresponding to wavelength, it failed and told me:

Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information.


My codes including data are simple and as follows:

data = {{646.38, 2991}, {646.46, 3085}, {646.53, 3204}, {646.6,
3227}, {646.68, 3183}, {646.75, 3121}, {646.83, 3176}, {646.9,
3354}, {646.97, 3475}, {647.05, 3645}, {647.12,
3798}, {647.2, 4146}, {647.27, 4321}, {647.34, 5067}, {647.42,
5684}, {647.49, 6135}, {647.57, 7189}, {647.64,
8342}, {647.71, 9449}, {647.79, 10788}, {647.86,
12591}, {647.94, 15210}, {648.01, 19037}, {648.08,
22940}, {648.16, 26676}, {648.23, 31403}, {648.31,
36365}, {648.38, 41122}, {648.45, 45664}, {648.53,
50078}, {648.6, 49445}, {648.68, 45498}, {648.75,
37491}, {648.82, 29894}, {648.9, 22635}, {648.97,
15810}, {649.05, 10029}, {649.12, 6141}, {649.19,
5913}, {649.27, 5649}, {649.34, 4057}, {649.42,
3734}, {649.49, 3810}, {649.56, 3880}, {649.64,
2938}, {649.71, 3284}, {649.79, 3349}, {649.86,
3109}, {649.93, 3134}};
fun = Interpolation[data];
Solve[fun[x] == 50078/2, x]


where the maximum intensity is from data

From the document of Mathematica, I know that the algorithm of Interpolation is fitting polynomial curves between successive data points, and Solve is mainly used in linear and polynomial equations.

The question is why can't Solve solve the equation including InterpolatingFunction

• I would use FindRoot, although that doesn't answer your last question. – march Apr 19 '16 at 15:46
• Don't know why you cannot use Solve, but if you use FindRoot[fun[x] == 50078/2, {x, 649}] you get the answer. – tsuresuregusa Apr 19 '16 at 15:47
• But anyway, InterpolatingFunction isn't a polynomial but rather a sequence of pasted together polynomials, making it impossible for Solve to use nicely. – march Apr 19 '16 at 15:50
• Actually i don't understand the difference between the meanings of "a polynomial" and "a sequence of pasted together polynomials" – Kevin Xie Apr 19 '16 at 17:05
• What @march is referring to is conventionally called piecewise polynomial interpolation -- see also mathematica.stackexchange.com/a/59963 – Michael E2 Apr 19 '16 at 18:44

Here is an adaptation of my solution to Extracting the function from InterpolatingFunction object, which converts an InterpolatingFunction to a Piecewise polynomial interpolation.

pwf = Piecewise[
Map[{InterpolatingPolynomial[#1, x], x < #[[3, 1]]} &, Most[#]],
InterpolatingPolynomial[Last@#1, x]] &@Partition[data, 4, 1];

{x1, x2} = MinMax[data[[All, 1]]];

sol = Solve[pwf == 50078/2 && x1 <= x <= x2, x]
(*  {{x -> 648.126}, {x -> 648.873}}  *)


NSolve` works too.