Possibile? Sì. Utile? No. È improbabile che le ottimizzazioni che sto per elencare qui facciano più di una piccola frazione della differenza percentuale nel tempo di esecuzione. Un buon compilatore potrebbe già fare queste cose per te.
Ad ogni modo, guardando il tuo ciclo interiore:
for (s=0,j=a;j<b;j+=h){
func2 = func(j+h);
s = s + 0.5*(func1+func2)*h;
func1 = func2;
}
Ad ogni iterazione di loop esegui tre operazioni matematiche che possono essere portate all'esterno: aggiunta j + h
, moltiplicazione per 0.5
e moltiplicazione per h
. Il primo che puoi correggere avviando la tua variabile iteratore su a + h
, e gli altri prendendo in considerazione le moltiplicazioni:
for (s=0, j=a+h; j<=b; j+=h){
func2 = func(j);
s += func1+func2;
func1 = func2;
}
s *= 0.5 * h;
Anche se vorrei sottolineare che, facendo questo, a causa dell'errore di arrotondamento in virgola mobile è possibile perdere l'ultima iterazione del ciclo. (Anche questo era un problema nella tua implementazione originale.) Per aggirare il problema, usa un unsigned int
o un size_t
contatore:
size_t n;
for (s=0, n=0, j=a+h; n<N; n++, j+=h){
func2 = func(j);
s += func1+func2;
func1 = func2;
}
s *= 0.5 * h;
Come dice la risposta di Brian, il tuo tempo è meglio speso per ottimizzare la valutazione della funzione func
. Se l'accuratezza di questo metodo è sufficiente, dubito che troverai qualcosa di più veloce per lo stesso N
. (Sebbene sia possibile eseguire alcuni test per vedere se, ad esempio, Runge-Kutta ti consente di abbassare N
abbastanza da rendere l'integrazione complessiva che richiede meno tempo senza sacrificare la precisione.)
trapezoidal_integration
invece ditrap
,sum
orunning_total
invece dis
(e anche usare+=
invece dis = s +
),trapezoid_width
odx
invece dih
(o no, a seconda della notazione preferita per la regola trapezoidale), e cambiarefunc1
efunc2
riflettere il fatto che sono valori, non funzioni. Ad esempiofunc1
->previous_value
efunc2
->current_value
, o qualcosa del genere.