Ho una funzione periodica e ho i valori di questa funzione in punti discreti. Quindi ho:
f(t_i)
per alcuni t_i, i\el(0,n)
Ora tra questi punti discreti voglio linearizzare interpolare la funzione in modo tale che:
%codice%
per f(t) = f(t(i)) + (t - t(i)) ( f(t(i+1)) - f(t(i)) )/( t(i+1)-t(i) )
.
L'implementazione (sto usando la notazione di Fortran): Ho delle matrici t\el(t(i),t(i+1))
per rappresentare t_n(0:n + 1)
ai punti discreti dati, t(i)
per rappresentare i valori di funzione in quei punti e f_n(0:n)
che è solo un precalcolo del termine di interpolazione lineare --- f_lin(n + 1)
.
La mia implementazione funziona bene finché sono entro il primo periodo, ma dopo mi imbatto in problemi. Il codice funziona come:
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
Funziona solo per il primo periodo, per farlo funzionare anche in altri periodi, penso che funzionerebbe:
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
Non l'ho ancora provato perché sembra molto complicato. Credo che ci debba essere un modo semplice per gestire questo problema (probabilmente posso risolvere il problema con l'utilizzo di diverse dichiarazioni f_lin(i) = ( f(t(i)) - f(t(i - 1) )/( t(i)-t(i - 1) )
, ma penso che manchi qualcosa di veramente semplice). Il problema è che durante l'ultimo intervallo tra IF
e t(n)
, il modulo di t(0)
può essere sia maggiore di t
o minore.
Stavo anche pensando a cicli annidati in cui la parte superiore sarebbe passata attraverso i periodi, ma non mi piace molto nemmeno questa soluzione (soprattutto perché t(n)
non è generalmente un multiplo di tmax
).
Quale sarebbe la soluzione più semplice ma anche la più veloce (la velocità di esecuzione) per questo?