# List Manipulation- Find corresponding values

I have the next list :

  {{0.1, -15.3512}, {0.2, -115.194}, {0.3, -133.702}, {0.4, -140.201}, \
{0.5, -143.232}, {0.6, -144.903}, {0.7, -145.935}, {0.8, -146.63}, \{0.9,
-147.132}, {1., -147.518}, {1.1, -147.828}, {1.2, -148.089}, \{1.3,
-148.318}, {1.4, -148.523}, {1.5, -148.716}, {1.6, -148.893}, \{1.7,
-149.054}, {1.8, -149.223}, {1.9, -149.379}, {2., -149.528}, \{2.1,
-149.671}, {2.2, -149.804}, {2.3, -149.929}, {2.4, -150.043}, \{2.5,
-150.143}, {2.6, -150.225}, {2.7, -150.287}, {2.8, -150.324}, \{2.9,
-150.329}, {3., -150.298}, {3.1, -150.224}, {3.2, -150.098}, \{3.3,
-149.911}, {3.4, -149.653}, {3.5, -149.315}, {3.6, -148.88}, \{3.7,
-148.344}, {3.8, -147.686}, {3.9, -146.889}, {4., -145.937}, \
{4.1, -144.816}, {4.2, -143.509}, {4.3, -141.997}, {4.4, -140.263}, \{4.5,
-138.307}, {4.6, -136.061}, {4.7, -133.564}, {4.8, -130.786}, \{4.9,
-127.716}, {5., -124.349}, {5.1, -120.684}, {5.2, -116.715}, \{5.3,
-112.457}, {5.4, -107.914}, {5.5, -103.102}, {5.6, -98.0415}, \{5.7,
-92.7544}, {5.8, -87.273}, {5.9, -81.6295}, {6., -75.8572}, \{6.1,
-69.9991}, {6.2, -64.092}, {6.3, -58.1799}, {6.4, -52.3046}, \{6.5,
-46.5078}, {6.6, -40.827}, {6.7, -35.3016}, {6.8, -29.9653}, \{6.9,
-24.8465}, {7., -19.9717}, {7.1, -15.3617}, {7.2, -11.0341}, \{7.3,
-6.99813}, {7.4, -3.26171}, {7.5, 0.172043}, {7.6,
3.30803}, {7.7, 6.14966}, {7.8, 8.70572}, {7.9, 10.9888}, {8.,
13.0129}, {8.1, 14.7937}, {8.2, 16.3474}, {8.3, 17.6906}, {8.4,
18.8424}, {8.5, 19.8199}, {8.6, 20.6402}, {8.7, 21.3201}, {8.8,
21.8738}, {8.9, 22.317}, {9., 22.664}, {9.1, 22.926}, {9.2,
23.1148}, {9.3, 23.2406}, {9.4, 23.3121}, {9.5, 23.3539}, {9.6,
23.3247}, {9.7, 23.2789}, {9.8, 23.2081}, {9.9, 23.1102}, {10.,
22.9953}, {10.1, 22.866}, {10.2, 22.7242}, {10.3, 22.5727}, {10.4,
22.4149}, {10.5, 22.2485}, {10.6, 22.0785}, {10.7, 21.9067}, {10.8,
21.7264}, {10.9, 21.5564}, {11., 21.3797}, {11.1, 21.2037}, {11.2,
21.0281}, {11.3, 20.8535}, {11.4, 20.6802}, {11.5, 20.5083}, {11.6,
20.3377}, {11.7, 20.1697}, {11.8, 20.0034}, {11.9, 19.8403}, {12.,
19.6767}, {12.1, 19.5166}, {12.2, 19.3587}, {12.3, 19.2031}, {12.4,
19.0497}, {12.5, 18.8984}, {12.6, 18.7495}, {12.7, 18.6027}, {12.8,
18.4579}, {12.9, 18.3154}, {13., 18.1752}, {13.1, 18.0366}, {13.2,
17.9005}, {13.3, 17.7661}, {13.4, 17.6336}, {13.5, 17.5031}, {13.6,
17.3746}, {13.7, 17.2478}, {13.8, 17.1229}, {13.9, 16.9998}, {14.,
16.8767}, {14.1, 16.7583}, {14.2, 16.6403}, {14.3, 16.524}, {14.4,
16.4095}, {14.5, 16.2964}, {14.6, 16.1848}, {14.7, 16.0747}, {14.8,
15.966}, {14.9, 15.8598}, {15., 15.7531}, {15.1, 15.6488}, {15.2,
15.5469}, {15.3, 15.444}, {15.4, 15.3437}, {15.5, 15.2446}, {15.6,
15.147}, {15.7, 15.0505}, {15.8, 14.9559}, {15.9, 14.8611}, {16.,
14.7681}, {16.1, 14.6765}, {16.2, 14.5858}, {16.3, 14.4975}, {16.4,
14.4087}, {16.5, 14.3205}, {16.6, 14.2342}, {16.7, 14.149}, {16.8,
14.0647}, {16.9, 13.9818}, {17., 13.8992}, {17.1, 13.818}, {17.2,
13.7375}, {17.3, 13.6581}, {17.4, 13.5793}, {17.5, 13.5035}, {17.6,
13.4251}, {17.7, 13.3493}, {17.8, 13.2737}, {17.9, 13.2001}, {18.,
13.1268}, {18.1, 13.0542}, {18.2, 12.9826}, {18.3, 12.9122}, {18.4,
12.8414}, {18.5, 12.7719}, {18.6, 12.7034}, {18.7, 12.6354}, {18.8,
12.5681}, {18.9, 12.5015}, {19., 12.4358}, {19.1, 12.3707}, {19.2,
12.306}, {19.3, 12.2422}, {19.4, 12.1791}, {19.5, 12.1167}, {19.6,
12.0548}, {19.7, 11.9935}, {19.8, 11.9326}, {19.9, 11.873}, {20.,
11.8137}}


Which in turn can be plot, and I obtained this:

where y-coordinate is energy, and x-axis is distance. I have to find a value of distance for a given value of energy, and, as can be seen , for a given energy there can be several distances. For instance , I use an energy of y=18, which has, in fact, three corresponding distances, but I only can find one. I use interpolation first in the table and then use Solve but , I just obtained one value that is irrelevant for other calculations:

  itb = Interpolation[tbff];
Solve[itb[z]==z]

{*z=0.0854959*}


Can anybody help me ? Thanks in advance.

Let us denote the energy e. Try this:

dist[e_] :=
Map[Part[tbff, #][[1]] &, (Position[tbff, #] & /@
Nearest[Transpose[tbff][[2]], e, 2] /. {{x_, 2}} -> x)]


It gives you the list of x coordinates of the points most close to to the energy e. Then, say,

dist[18.3]

(* {12.9, 13.}  *)


and

dist[-71]

(*  {6.1, 6.}  *)


Have fun!

FindMinimum[(itb[z] - z)^2, {z, 5}]


{5.41175*10^-22, {z -> 7.76178}}

FindMinimum[(itb[z] - z)^2, {z, 15}]


{3.95819*10^-26, {z -> 15.3718}}

Plot[itb[z] - z, {z, 0, 18}] yielding

Update: Realized upon rereading that you may be asking for the solution to the interesting problem of trying to find all the values that match something within your data range, not just spot finding where $f(z)===z$.

There's actually a nice strategy we can borrow from here

findSomeVals[f_, min_, max_] :=
Reap[soln =
y[x] /. First[
NDSolve[{y'[x] == Evaluate[D[f[x], x]], y[min] == (f[min])},
y[x], {x, min, max},
Method -> {"EventLocator", "Event" -> y'[x],
"EventAction" :> Sow[{x, y[x]}]}]]][[2, 1]];

findLocsForValZ[xx_,
interpFunc_] := (z /. Flatten[#[[2]]]) & /@
Select[ FindMinimum[(interpFunc[z] - xx)^2 &&
z >= interpFunc[[1, 1, 1]] &&
z <= interpFunc[[1, 1, 2]], {z, #[[1]]}] & /@
findSomeVals[(interpFunc[#] - xx /. z -> #)^2 &,
interpFunc[[1, 1, 1]], interpFunc[[1, 1, 2]]],
Abs[#[[1]]] < 10^-4 &] //
Union[#, SameTest -> (0 === Chop[#1 - #2, 10^-6] &)] &


Usage:

findLocsForValZ[z,itb]  (* to find z where f[z]===z *)


{7.76178, 15.3718}

findLocsForValZ[14,itb] (* to find z where f[z]===14 *)


{8.05379, 16.878}

findLocsForValZ[23.2,itb] (* to find z where f[z]===23.2 *)


{9.26228, 9.80928}

Is that suspicious? Ie. to find such close args to get itb[z]==23.2?
Let's take a look:

Plot[itb[z] - 23.2, {z, itb[[1, 1, 1]], itb[[1, 1, 2]]},
PlotPoints -> 400, PlotRange -> {-1/2, 1/2}]


yields:

Indeed, finding these values {9.26228, 9.80928} where f[z] was equiv to 23.2 was interpolated from the following progression within the original data:

{ ... , {9.2, 23.1148}, {9.3, 23.2406}, {9.4, 23.3121}, {9.5, 23.3539}, {9.6, 23.3247}, {9.7, 23.2789}, {9.8, 23.2081}, {9.9, 23.1102}, ...}

## ----

Fun example:

itpSin = Interpolation[Table[{x, Sin[x]}, {x, -6.5 \[Pi], 6.5 \[Pi], 1/10}]];
findLocsForValZ[0, itpSin]/\[Pi] // Chop[#, 10^-6] & // Rationalize


{-6., -5., -4., -3., -2., -1., 0, 1., 2., 3., 4., 5., 6.}

• Thank you very much for your help. I will try to analize your code because I have to use it later for another calculation :D Commented Sep 4, 2017 at 1:11

If the underlying function got sampled sufficiently fine, so that each interval between x-values contains at most one y-root, one can use

data = DeveloperToPackedArray@{{0.1, -15.3512}, {0.2, -115.194}, {0.3, -133.702}, {0.4, -140.201}, {0.5, -143.232}, {0.6, -144.903}, {0.7, -145.935}, {0.8, -146.63}, {0.9, -147.132}, {1., -147.518}, {1.1, -147.828}, {1.2, -148.089}, {1.3, -148.318}, {1.4, -148.523}, {1.5, -148.716}, {1.6, -148.893}, {1.7, -149.054}, {1.8, -149.223}, {1.9, -149.379}, {2., -149.528}, {2.1, -149.671}, {2.2, -149.804}, {2.3, -149.929}, {2.4, -150.043}, {2.5, -150.143}, {2.6, -150.225}, {2.7, -150.287}, {2.8, -150.324}, {2.9, -150.329}, {3., -150.298}, {3.1, -150.224}, {3.2, -150.098}, {3.3, -149.911}, {3.4, -149.653}, {3.5, -149.315}, {3.6, -148.88}, {3.7, -148.344}, {3.8, -147.686}, {3.9, -146.889}, {4., -145.937}, {4.1, -144.816}, {4.2, -143.509}, {4.3, -141.997}, {4.4, -140.263}, {4.5, -138.307}, {4.6, -136.061}, {4.7, -133.564}, {4.8, -130.786}, {4.9, -127.716}, {5., -124.349}, {5.1, -120.684}, {5.2, -116.715}, {5.3, -112.457}, {5.4, -107.914}, {5.5, -103.102}, {5.6, -98.0415}, {5.7, -92.7544}, {5.8, -87.273}, {5.9, -81.6295}, {6., -75.8572}, {6.1, -69.9991}, {6.2, -64.092}, {6.3, -58.1799}, {6.4, -52.3046}, {6.5, -46.5078}, {6.6, -40.827}, {6.7, -35.3016}, {6.8, -29.9653}, {6.9, -24.8465}, {7., -19.9717}, {7.1, -15.3617}, {7.2, -11.0341}, {7.3, -6.99813}, {7.4, -3.26171}, {7.5, 0.172043}, {7.6, 3.30803}, {7.7, 6.14966}, {7.8, 8.70572}, {7.9, 10.9888}, {8., 13.0129}, {8.1, 14.7937}, {8.2, 16.3474}, {8.3, 17.6906}, {8.4, 18.8424}, {8.5, 19.8199}, {8.6, 20.6402}, {8.7, 21.3201}, {8.8, 21.8738}, {8.9, 22.317}, {9., 22.664}, {9.1, 22.926}, {9.2, 23.1148}, {9.3, 23.2406}, {9.4, 23.3121}, {9.5, 23.3539}, {9.6, 23.3247}, {9.7, 23.2789}, {9.8, 23.2081}, {9.9, 23.1102}, {10., 22.9953}, {10.1, 22.866}, {10.2, 22.7242}, {10.3, 22.5727}, {10.4, 22.4149}, {10.5, 22.2485}, {10.6, 22.0785}, {10.7, 21.9067}, {10.8, 21.7264}, {10.9, 21.5564}, {11., 21.3797}, {11.1, 21.2037}, {11.2, 21.0281}, {11.3, 20.8535}, {11.4, 20.6802}, {11.5, 20.5083}, {11.6, 20.3377}, {11.7, 20.1697}, {11.8, 20.0034}, {11.9, 19.8403}, {12., 19.6767}, {12.1, 19.5166}, {12.2, 19.3587}, {12.3, 19.2031}, {12.4, 19.0497}, {12.5, 18.8984}, {12.6, 18.7495}, {12.7, 18.6027}, {12.8, 18.4579}, {12.9, 18.3154}, {13., 18.1752}, {13.1, 18.0366}, {13.2, 17.9005}, {13.3, 17.7661}, {13.4, 17.6336}, {13.5, 17.5031}, {13.6, 17.3746}, {13.7, 17.2478}, {13.8, 17.1229}, {13.9, 16.9998}, {14., 16.8767}, {14.1, 16.7583}, {14.2, 16.6403}, {14.3, 16.524}, {14.4, 16.4095}, {14.5, 16.2964}, {14.6, 16.1848}, {14.7, 16.0747}, {14.8, 15.966}, {14.9, 15.8598}, {15., 15.7531}, {15.1, 15.6488}, {15.2, 15.5469}, {15.3, 15.444}, {15.4, 15.3437}, {15.5, 15.2446}, {15.6, 15.147}, {15.7, 15.0505}, {15.8, 14.9559}, {15.9, 14.8611}, {16., 14.7681}, {16.1, 14.6765}, {16.2, 14.5858}, {16.3, 14.4975}, {16.4, 14.4087}, {16.5, 14.3205}, {16.6, 14.2342}, {16.7, 14.149}, {16.8, 14.0647}, {16.9, 13.9818}, {17., 13.8992}, {17.1, 13.818}, {17.2, 13.7375}, {17.3, 13.6581}, {17.4, 13.5793}, {17.5, 13.5035}, {17.6, 13.4251}, {17.7, 13.3493}, {17.8, 13.2737}, {17.9, 13.2001}, {18., 13.1268}, {18.1, 13.0542}, {18.2, 12.9826}, {18.3, 12.9122}, {18.4, 12.8414}, {18.5, 12.7719}, {18.6, 12.7034}, {18.7, 12.6354}, {18.8, 12.5681}, {18.9, 12.5015}, {19., 12.4358}, {19.1, 12.3707}, {19.2, 12.306}, {19.3, 12.2422}, {19.4, 12.1791}, {19.5, 12.1167}, {19.6, 12.0548}, {19.7, 11.9935}, {19.8, 11.9326}, {19.9, 11.873}, {20., 11.8137}};

itb = Interpolation[data];
pos = Join[Flatten[Position[Abs[Differences[Sign[data[[All,2]] - y]]], 2]], {1, -1}];
y = 18.;
roots = DeleteDuplicates[Table[t /. FindRoot[itb[t] == y, {t, data[[p, 1]]}], {p, pos}]]

(* {8.32535, 13.1267, 0.0812768} *)


Note that this throws several errors as you extrapolated from a InterpolationFunction`, something that is quite questionable...