I have a set of data points given as x and y values for which I like to find a fit (using FindFit
). However, the fit shall not be made over the complete data range, only a small subset. The criterium which range shall be considered to be fitted depends on the fitting itself - in other words, it is an iterative process.
For demonstration purposes, consider the following structure (in reality I load this from a file which makes the use of Flatten
necessary):
x = Table[j, {j, 1, 100}];
y = Table[(j - 40.25)^2 + 5, {j, 1, 100}];
data = Table[{x[[j]], y[[j]]}, {j, 1, 100}];
dx = Max[x]/2;
Do[
dxOld = dx;
(* ? 1) Compute minimal y value and according x *)
minY = Min[data];
(* Fit *)
fitResults := FindFit[data, a + b*z*c*z^2, {a, b, c}, z];
(* 2) Compute criterium *)
dx = a/10 /. fitResults;
(* ? 4) Change data so that it only holds x values (and y
accordingly) +- dx around the minimum minY *)
(* 5) Stop once dx changes are small enough *)
If[(dxOld - dx)/dx < 10^-3, Break[]];
, {l, 0, 50}
];
I am having trouble with Steps #1 and #4. In #1, I really like to use data
instead of y
since then I do not have to overwrite y
as well in each loop. In #4, I have no idea on how to achieve this. Can someone point me in the right direction?
minY=First@MinimalBy[data,Last]
. Step 4:newData=Cases[data,{x_,_}/;Abs[x-First@minY]<dx]
. I don't have time to write up a full answer, but that may help you figure it out. Also, check outNestWhile
it's a much more idiomatic way to handle this kind of conditional iteration. $\endgroup$data
with something likedata=Transpose@{x,y}
. $\endgroup$