I have a periodic functions and I have the values of this function at discrete points. So I have:
f(t_i)
for some t_i, i\el(0,n)
Now between these discrete points I want to lineary interpolate the function such that:
f(t) = f(t(i)) + (t - t(i)) ( f(t(i+1)) - f(t(i)) )/( t(i+1)-t(i) )
for t\el(t(i),t(i+1))
.
The implementation (I am using Fortran notation): I have arrays t_n(0:n + 1)
to represent t(i)
at the given discrete points, f_n(0:n)
to represent the function values at those points, and f_lin(n + 1)
which is just a precalculation of the linear interpolation term --- f_lin(i) = ( f(t(i)) - f(t(i - 1) )/( t(i)-t(i - 1) )
.
My implementation works fine as long as I am within the first period but after that I run into problems. The code goes as:
ALLOCATE ( t_n(0:n + 1), f_n(0:n + 1), f_lin(n + 1) )
t_n(0) = 0.D0
t = 0.D0
f_n(0) = f(t)
DO WHILE i = 1, n
t_n(i) = t*dt
! some other code that calculates f_n(i) actually
f_lin(i) = ( f_n(i) - f_n(i - 1) )/( t_n(i) - t_n(i - 1) )
END DO
t_n(n + 1) = period
f_lin(n + 1) = ( f_n(0) - f_n(n) )/( t_n(n + 1) - t_n(n) )
i = 0
j = 0
DO WHILE (t .LT. tmax)
! this tests whether I go to the higher interval where I have the discrete values
IF ( t_n(i + 1) .LE. MOD(t, period) ) i = i + 1
f_t = f_n(i) + ( t - t_n(i) )*f_lin(i + 1)
j = j + 1
t = t + dt
! some other code
END DO
This only works for the first period, to make it work in other periods as well, I think this would work:
DO WHILE (t .LT. tmax)
! this tests whether I go to the higher interval where I have the discrete values
IF ( MOD(t, period) .GE. t_n(i + 1) ) THEN
i = i + 1
ELSE IF ( (MOD(t, period) .LT. t_n(i)) .AND. ( i .EQ. n ) ) THEN
i = 0
END IF
f_t = f_n(i) + ( t - t_n(i) )*f_lin(i + 1)
j = j + 1
t = t + dt
! some other code
END DO
I have not tried it yet because it looks very complicated. I believe that there must be a simple way to handle this issue (I can probably solve the problem with using several IF
statements but I think I am missing something really simple). The problem is that during the last interval between t(n)
and t(0)
, modulus of t
can be both larger than t(n)
or smaller.
I was also thinking about nested loops the top would be going through periods but I do not like that solution much either (especially because tmax
is not generally a multiple of period
).
What would the easiest but also the fastest (the execution speed) solution to this be?