# Fitting with Step Function (Beginner question) [duplicate]

I have data as below.

data = {{-83, 7.09531}, {-20, 1.65586}, {-10, 3.80134}, {0, 7.53841}, {0.2, 7.17162}, {0.3, 1.58444}, {0.8, 8.85609}, {2., 1.32255}, {8, 9.38444}, {20, 10}, {30, 40}, {25, 22}, {30, 50}, {40, 300}, {50, 550}, {80, 450}, {100, 400}, {150, 400}, {200, 431.727}, {240, 403.676}, {250, 442.495}, {312.2, 433.578}, {426.5, 410.929}, {480, 438.634}, {500, 447.573}, {550, 404.358}, {600, 429.312}}


I want to fit this data with Step function like this red line as below. I mean I want to get the parameters corresponding to numbers of 0 and 415 (y value of step function), and 20 and 100 (x range of step function). These numbers are just approximate value and not accurate.

g[x_] := Piecewise[{{0, x < 20}, {None, 20 < x < 100}, {415,
100 <= x}}];

fit = g[#] & /@ Range[-100, 600];
fitimage = Transpose[{Range[-100, 600], fit}];
Show[ListPlot[data], ListLinePlot[fitimage, PlotStyle -> Red]]


I tried

f[x_] := Piecewise[{{a, x < xa}, {None, xa <= x < xb}, {b, xb <= x}}]
NonlinearModelFit[data, f[x], {a, b, xa, xb}, x]


but just Error appeared.

If someone knows how to fit this data, please tell me.

– rani
Commented Apr 15 at 6:09

\$Version

(* "14.0.0 for Mac OS X ARM (64-bit) (December 13, 2023)" *)

Clear["Global*"]

data = {{-83, 7.09531}, {-20, 1.65586}, {-10, 3.80134}, {0, 7.53841}, {0.2,
7.17162}, {0.3, 1.58444}, {0.8, 8.85609}, {2., 1.32255}, {8,
9.38444}, {20, 10}, {30, 40}, {25, 22}, {30, 50}, {40, 300}, {50,
550}, {80, 450}, {100, 400}, {150, 400}, {200, 431.727}, {240,
403.676}, {250, 442.495}, {312.2, 433.578}, {426.5, 410.929}, {480,
438.634}, {500, 447.573}, {550, 404.358}, {600, 429.312}};


Define a linear transition between the levels

trans = m*x + c /. Solve[{a == m*xa + c, b == m*xb + c}, {m, c}][[1]] //
Simplify

(* (a x - b x + b xa - a xb)/(xa - xb) *)

f[x_] := Piecewise[{{a, x < xa}, {trans, xa <= x < xb}, {b, xb <= x}}]


Fit the data then suppress the transition

nlm[x_] = ReplacePart[
NonlinearModelFit[data, f[x], {{a, 0}, {b, 400}, {xa, 20}, {xb, 100}}, x] //
Normal, {1, 2, 1} -> None]


{xmin, xmax} = MinMax[data[[All, 1]]]

(* {-83, 600} *)

Show[
ListPlot[data],
Plot[nlm[x], {x, xmin, xmax},
PlotStyle -> Red]]
`