1
$\begingroup$

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}}
$\endgroup$
  • 2
    $\begingroup$ the problem is the constraint 50 <= w <= 50. Change it into e.g. 50 <= w <= 150 and it'll work just fine. $\endgroup$ – AccidentalFourierTransform Feb 15 at 17:11
  • $\begingroup$ @AccidentalFourierTransform to be fair to myself the contraints I used were much wider; the 50 was an editing error. So that alone did not actually cause the problem. The solution lies in reducing the data sample which is not obvious and not necessarily the only solution. $\endgroup$ – onepound Feb 16 at 10:24
  • $\begingroup$ I see. If you edit your post to fix that, I'll vote to reopen. $\endgroup$ – AccidentalFourierTransform Feb 16 at 12:42
  • $\begingroup$ @AccidentalFourierTransform okay w fixed. $\endgroup$ – onepound Feb 16 at 13:50
3
$\begingroup$
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.

$\endgroup$

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