Regressione Sinusoidale e Visual Basic – Parte 3
Regressione Sinusoidale: un breve riepilogo e implementazione in Visual Basic. NET – (PARTE 3: Ricerca della convergenza del parametro w0 in VB.NET).
Una volta trovati a0, b0, c0 con il valore inziale di w0 si passa a cercare la sua convergenza (o meglio: si cercherà il valore di w0 tale per cui lo scarto quadratico medio è minimo). Prima di poter fare questo però occorre passare in visual basic la derivata:
∂F/∂w = 0 (vedi parte 1)
che esplicitata diventa:
∂F/∂w = 2 {(a2-b2)∑xk sin(wxk)cos(wxk) +
+ 2ab∑xk cos2(wxk) – ab∑xk +
+ a[c∑cos(wxk) – ∑xkykcos(wxk)] +
– b[c∑sin(wxk) -∑xkyksin(wxk)]} = 0
(ogni sommatoria è su k =1,2…n)
In questa derivata vengono sostituite le soluzioni del precedente sistema, ottenendo quindi un valore numerico. Ci prepariamo le sommatorie attraverso la funzione Calcola_Sommatorie_dFdw()
:
[codesyntax lang=”vbnet”]
Function Calcola_Sommatorie_dFdw(w0 As Single) As Single() Dim SS(9) As Single For i = 0 To Numero_Punti - 1 ' ∑xk sin(wxk)cos(wxk) SS(0) += Math.Sin(w0 * Vettore_Ax(i)) * Math.Cos(w0 * Vettore_Ax(i)) ' ∑xk cos2(wxk) SS(1) += (Math.Cos(w0 * Vettore_Ax(i))) ^ 2 ' ∑xk SS(2) += Vettore_Ax(i) ' ∑cos(wxk) SS(3) += Math.Cos(w0 * Vettore_Ax(i)) ' ∑xkykcos(wxk) SS(4) += Vettore_Ax(i) * Vettore_Ay(i) * Math.Cos(w0 * Vettore_Ax(i)) ' ∑sin(wxk) SS(5) += Math.Sin(w0 * Vettore_Ax(i)) ' ∑xkyksin(wxk) SS(6) += Vettore_Ax(i) * Vettore_Ay(i) * Math.Sin(w0 * Vettore_Ax(i)) Next Return SS End Function
[/codesyntax]
con la quale calcoliamo i valore numerico della derivata ∂F/∂w. (In realtà anche questo calcolo serve a ben poco: inizialmente si era pensato di trovare il valore di w0 che rendeva più vicina a zero proprio questa derivata).
[codesyntax lang=”vbnet”]
Function dFdw(a0 As Single, b0 As Single, c0 As Single, w0 As Single) As Single '∂F/∂w = 2 {(a2-b2)∑xk sin(wxk)cos(wxk) + '+ 2ab∑xk cos2(wxk) - ab∑xk + '+ a[c∑cos(wxk) - ∑xkykcos(wxk)] + '- b[c∑sin(wxk) -∑xkyksin(wxk)]} Dim SS() As Single = Calcola_Sommatorie_dFdw(w0) dFdw = 2 * ( (a0 ^ 2 - b0 ^ 2) * SS(0) + 2 * a0 * b0 * SS(1) - a0 * b0 * SS(2) + a0 * (c0 * SS(3) - SS(4)) - b0 * (c0 * SS(5) - SS(6)) ) End Function
[/codesyntax]
A questo punto ci occorre conoscere a quale valore di w0 dobbiamo prendere per far si che l’uguaglianza a zero della derivata sia verificata o comunque molto piccola. Ci sviluppiamo il calcolo dello Scarto Quadratico Medio con la funzione Calcola_SQM()
:
[codesyntax lang=”vbnet”]
Function Calcola_SQM(a0 As Single, b0 As Single, c0 As Single, w0 As Single) As Single 'F(a,b,c,w) = ∑[( a sen(wx) + b cos(wx) + c) - yk]2 Dim s As Single = 0 For i = 0 To Numero_Punti - 1 s += (((a0 * Math.Sin(w0 * Vettore_Ax(i)) + b0 * Math.Cos(w0 * Vettore_Ax(i)) + c0 - Vettore_Ay(i))) ^ 2) Next s = (s / Numero_Punti) ^ 0.5 Return s End Function
[/codesyntax]
Più piccolo è lo SQM maggiore sarà la corrispondenza della sinusoide ai punti. Ora è possibile procedere su un intervallo di valori [-π,+π] fino a trovare il valore che si avvicina di più zero. Trovato questo valore si procederà alla ulteriore scansione nell’intorno di tale valore. La funzione è la dFdw_Min_VAss()
che restituisce un vettore con i minimi legati allo SQM: dF/dw0, w0, a, b, c, sqm.
[codesyntax lang=”vbnet”]
Function dFdw_Err_Min() As Single() Dim TabMinimi(5) As Single TabMinimi(0) = 10 ^ 20 TabMinimi(1) = 10 ^ 20 TabMinimi(2) = 10 ^ 20 TabMinimi(3) = 10 ^ 20 TabMinimi(4) = 10 ^ 20 TabMinimi(5) = 10 ^ 20 For w0 = -Math.PI To Math.PI Step 0.01 Dim sol() = Risolvi_Sistema_Lineare(w0) If sol IsNot Nothing Then Dim df = dFdw(sol(0), sol(1), sol(2), w0) Dim SqM = Calcola_SQM(sol(0), sol(1), sol(2), w0) 'trova l'errore standard minimo If SqM < TabMinimi(5) Then TabMinimi(0) = df TabMinimi(1) = w0 TabMinimi(2) = sol(0) TabMinimi(3) = sol(1) TabMinimi(4) = sol(2) TabMinimi(5) = SqM End If End If Next Return TabMinimi End Function
[/codesyntax]
Nella terza parte implementeremo in VB.NET l’affinamento della soluzione trovata. Nel frattempo se vuoi approfondire la questione, eccoti alcuni link utili:
- Scarto quadratico medio (Wikipedia);
- Torna alla parte 1 o alla parte 2 o vai alla parte 4 o vai alla parte 5.
- Eseguibile e alcune serie di punti qui: Regressione Sinusoidale