I need to find a piecewise linear function that is a proper approximation for sunrise/sunset times of each day of year. Due to some limitations, I cannot use any trigonometric functions. So the sine-looking function has to be approximated by a piecewise linear one. Here is the code to generate data:
location = GeoPosition[{30, 60}];
year = DateRange["2022/3/21", "2023/3/21"];
sunrises = DateDifference[#, Sunrise[location, #], "Minute"] & /@ year;
sunsets = DateDifference[#, Sunset[location, #], "Minute"] & /@ year;
The sunrise data looks like this
I want to approximate this function by $8$ straight lines. Thus the proposed function is defined as
r[x_] := Piecewise[{
{393 + ((-393 + b)*(-1 + x))/(-1 + x2), x <= x2},
{b + ((-b + c)*(x - x2))/(-x2 + x3), x2 < x && x <= x3},
{c + ((-c + d)*(x - x3))/(-x3 + x4), x3 < x && x <= x4},
{d + ((-d + e)*(x - x4))/(-x4 + x5), x4 < x && x <= x5},
{e + ((-e + f)*(x - x5))/(-x5 + x6), x5 < x && x <= x6},
{f + ((-f + g)*(x - x6))/(-x6 + x7), x6 < x && x <= x7},
{g + ((393 - g)*(x - x7))/(-x7 + x8), x7 < x && x <= x8}},
393 + ((-393 + i)*(x - x8))/(366 - x8)]
Now the problem is, I cannot find such fit using any functions that I have tried. The closest thing that I have found was This question, whose proposed method failed with this error:
FindFit::nrlnum: The function value {0.,0.0204082,<<364>>} is not a list of real numbers with dimensions {366} at {b,c,d,e,f,g,h,x2,x3,x4,<<4>>} = {370.,350.,<<12>>}.
FWIW, I did set the initial values, as suggested there
init = {{b, 340}, {c, 320}, {d, 340}, {e, 390}, {f, 430}, {g, 450}, {h, 430},
{x2, 50}, {x3, 80}, {x4, 120}, {x5, 200}, {x6, 270}, {x7, 300}, {x8, 330}};
NonlinearModelFit[First /@ sunrises, r[x], init, x]
Is there any way to do this?
ListInterpolation[sunrises, InterpolationOrder -> 1]
work? Also, Extracting the function from InterpolatingFunction object $\endgroup$a0+x(a1+x(a2+x(a3+a4 x)))
. Too expensive? $\endgroup$i
ininit
, but it doesn't really fix things, althoughNonLinearModelFit
will give an answer if you include it. $\endgroup$