2
$\begingroup$

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

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

1 Answer 1

3
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.