1

Taking as a starting point the advice given in this post I am trying to fit data to a staircase function as follows:

model = {h (1/2 + ((x - a)/w) - ArcTan[Tan[π (-(1/2) + ((x - a)/w))]]/π), 60 <= a <= 90, 50 <= h <= 150, 50 <= w <= 150};
nlm2 = FindFit[ptsech, model, {a, h, w}, x, Method -> "NMinimize"]

but now I'm wondering is it even possible to fit such data to a discontinous function? though it approximates the data as I wish. The problem is that code it not producing correct values for h, w and a even when manually bringing these values close. How can it be modified to work?

ptsech={{0, 0}, {30., 0}, {54.366, 0.00901776}, {67.0222, 
0.477768}, {70.7722, 4.22777}, {71.241, 16.884}, {71.25, 
41.25}, {71.25, 71.25}, {71.259, 95.616}, {71.7278, 
108.272}, {75.4778, 112.022}, {88.134, 112.491}, {112.5, 
112.5}, {142.5, 112.5}, {166.866, 112.509}, {179.522, 
112.978}, {183.272, 116.728}, {183.741, 129.384}, {183.75, 
153.75}, {183.75, 183.75}, {183.759, 208.116}, {184.228, 
220.772}, {187.978, 224.522}, {200.634, 224.991}, {225., 
225.}, {255., 225.}, {279.366, 225.009}, {292.022, 
225.478}, {295.772, 229.228}, {296.241, 241.884}, {296.25, 
266.25}, {296.25, 296.25}, {296.259, 320.616}, {296.728, 
333.272}, {300.478, 337.022}, {313.134, 337.491}, {337.5, 
337.5}, {367.5, 337.5}}
Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
onepound
  • 343
  • 1
  • 9

1 Answers1

4
ptsech = {{0, 0}, {30., 0}, {54.366, 0.00901776}, {67.0222, 
    0.477768}, {70.7722, 4.22777}, {71.241, 16.884}, {71.25, 41.25}, {71.25, 
    71.25}, {71.259, 95.616}, {71.7278, 108.272}, {75.4778, 112.022}, {88.134,
     112.491}, {112.5, 112.5}, {142.5, 112.5}, {166.866, 112.509}, {179.522, 
    112.978}, {183.272, 116.728}, {183.741, 129.384}, {183.75, 
    153.75}, {183.75, 183.75}, {183.759, 208.116}, {184.228, 
    220.772}, {187.978, 224.522}, {200.634, 224.991}, {225., 225.}, {255., 
    225.}, {279.366, 225.009}, {292.022, 225.478}, {295.772, 
    229.228}, {296.241, 241.884}, {296.25, 266.25}, {296.25, 
    296.25}, {296.259, 320.616}, {296.728, 333.272}, {300.478, 
    337.022}, {313.134, 337.491}, {337.5, 337.5}, {367.5, 337.5}};

{xmin, xmax} = MinMax@ptsech[[All, 1]];

As pointed out in a comment by AccidentalFourierTransform, the range of w should be widened.

model = {h (1/2 + ((x - a)/w) - 
      ArcTan[Tan[π (-(1/2) + ((x - a)/w))]]/π), 60 <= a <= 90, 
   50 <= h <= 150, 50 <= w <= 150};

nlm2 = FindFit[ptsech, model, {a, h, w}, x, Method -> "NMinimize"]

(* {a -> 70.8647, h -> 102.825, w -> 112.674} *)

Plot[Evaluate[model /. nlm2], {x, xmin, xmax},
 PlotRange -> {-10, 350},
 Epilog -> {Red, AbsolutePointSize[3],
   Point[ptsech]}]

enter image description here

Assuming that the near vertical runs are causing the offsets, reduce the data set prior to fitting.

ptsechr = Union[ptsech,
   SameTest -> (Abs[#1[[1]] - #2[[1]]] < 1 &)];

nlm2r = FindFit[ptsechr, model, {a, h, w}, x, Method -> "NMinimize"]

(* {a -> 71.5147, h -> 112.658, w -> 113.258} *)

Plot[Evaluate[model /. nlm2r], {x, xmin, xmax},
 Epilog -> {Red, AbsolutePointSize[3],
   Point[ptsech]}]

enter image description here

The offset has been corrected.

Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198