Gestione dell'interpolazione lineare di funzioni periodiche

0

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?

    
posta leosenko 17.09.2016 - 00:47
fonte

1 risposta

1

My implementation works fine as long as I am within the first period but after that I run into problems.

Non dovresti mai usare valori al di fuori del primo periodo.

Conoscete il periodo T, quindi quando date un valore, memorizzate il suo equivalente nel primo periodo (resto della divisione per T). Quando chiesto per un valore in un punto X, si calcola il resto di X / T e si interpola il valore per quello . Poiché la funzione è periodica, sarà anche il valore in X.

    
risposta data 17.09.2016 - 13:07
fonte

Leggi altre domande sui tag