Test di Hurwitz in Maxima
Inviato: 13 mag 2010, 12:55
Sono sempre rimasto abbastanza intrigato dai problemi di teoria delle reti elettriche. Spesso sono intimamente legati a problemi non banali di natura matematica, ed è una matematica applicata molto interessante.
Nei circuiti a parametri concentrati con un numero finito di elementi, le funzioni di rete sono del tipo:

dove
e
sono dei polinomi nella variabile complessa
. Una cosa importante da sapere è se gli zeri dei due polinomi hanno parte reale negativa oppure no, dato che queste informazioni sono di solito legate alla stabilità del sistema, oppure al fatto che la funzione è a fase minima oppure no. In campo reale le cose sono semplici da verificare utilizzando la regola di Cartesio, ma in campo complesso la situazione è molto più spinosa.
Diventa quindi importante verificare questa proprietà per un generico polinomio, se possibile senza calcolare esplicitamente gli zeri del polinomio, dato che questo potrebbe essere un problema non banale per un grado elevato del polinomio da studiare. Esiste un test algebrico chiamato prova di Hurwitz che permette di determinare se questa proprietà è verificata oppure no, senza calcolare esplicitamente gli zeri. Un polinomio è hurwitziano se tutti i suoi zeri hanno parte reale strettamente negativa, se ce n'é qualcuno immaginario è hurwitizano in senso lato.
Qualche anno fa, avevo messo a punto un piccolo script Maxima che permette di verificare se un polinomio è hurwitziano oppure no.
Ne ho già parlato sul mio sito:
http://davbucci.chez-alice.fr/index.php ... aliano#fun
ma mi sono detto che sarebbe stato carino proporlo nuovamente qui, per stimolare una discussione e perché magari potrebbe essere utile a qualcuno.
Una volta salvato lo script in un file, per esempio hurwitz.max, lo si può utilizzare all'interno di Maxima:
La funzione hurwitz(N,p) richiede il polinomio N nella variabile p ed effettua il test, che è basato su una serie di divisioni successive fra la parte pari e la parte dispari del poliniomio di partenza. Il programma restituisce una lista contenente i risultati delle divisioni.
Una cosa che mi piacerebbe fare una volta o l'altra è preparare altri script di questo tipo che applichino alcune procedure di sintesi empirica per le reti lineari passive. Che ne pensate?
Nei circuiti a parametri concentrati con un numero finito di elementi, le funzioni di rete sono del tipo:

dove
e
sono dei polinomi nella variabile complessa
. Una cosa importante da sapere è se gli zeri dei due polinomi hanno parte reale negativa oppure no, dato che queste informazioni sono di solito legate alla stabilità del sistema, oppure al fatto che la funzione è a fase minima oppure no. In campo reale le cose sono semplici da verificare utilizzando la regola di Cartesio, ma in campo complesso la situazione è molto più spinosa.Diventa quindi importante verificare questa proprietà per un generico polinomio, se possibile senza calcolare esplicitamente gli zeri del polinomio, dato che questo potrebbe essere un problema non banale per un grado elevato del polinomio da studiare. Esiste un test algebrico chiamato prova di Hurwitz che permette di determinare se questa proprietà è verificata oppure no, senza calcolare esplicitamente gli zeri. Un polinomio è hurwitziano se tutti i suoi zeri hanno parte reale strettamente negativa, se ce n'é qualcuno immaginario è hurwitizano in senso lato.
Qualche anno fa, avevo messo a punto un piccolo script Maxima che permette di verificare se un polinomio è hurwitziano oppure no.
Ne ho già parlato sul mio sito:
http://davbucci.chez-alice.fr/index.php ... aliano#fun
ma mi sono detto che sarebbe stato carino proporlo nuovamente qui, per stimolare una discussione e perché magari potrebbe essere utile a qualcuno.
Codice: Seleziona tutto
/* Perform the Hurwitz test on the M(p) polynomials using Maxima
Version 1.0
Written by Davide Bucci, March-April 2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Qualche esempio di polinomio hurwitziano e non:
-----------------------------------------------
56*p^5+7*p^4+161*p^3+18*p^2+98*p+8, Hurwitziano in senso lato
p^3+2*p^2+4*p+3, Strettamente hurwitziano
p^5+2*p^4+2*p^3+4*p^2+11*p+10, Non hurwitziano
p^3+2*p^2+4*p+9, Non hurwitziano
*/
hurwitz(poly,var):=block ([M,p],
/* Definiamo una funzione che ci permettera' di lavorare sul nostro
polinomio in maniera generale, utilizzando la variabile var */
define(M(var),poly),
if(debugmode) then print(M(p)),
print("Prova di Hurwitz per un polinomio"),
/* Otteniamo parte pari e dispari del polinomio */
Pa(p):=expand(1/2*(M(p)+M(-p))),
Di(p):=expand(1/2*(M(p)-M(-p))),
/* Abbiamo bisogno di ottenere il grado piu' elevato al numeratore */
pg:hipow(Pa(p), p),
dg:hipow(Di(p), p),
num:Di(p),
den:Pa(p),
nm:dg,
if (pg>dg) then
(num:Pa(p), den:Di(p), nm:pg),
res:divide(num,den,p),
/* Adesso possiamo effettuare le divisioni successive */
hasdivided: (second(res)#0),
print(hasdivided),
/* This list will contain the results of the successive divisions */
reslist:[],
ishurwitz:true,
print("Calcolo delle divisioni successive"),
for i:0 thru nm while (hasdivided and ishurwitz) do (
if(debugmode) then (
print("nuova iterazione"),
print(i),
print("divide"),
print(num),
print("by"),
print(den)
),
res:divide(num,den,p),
if(debugmode) then (
print("resulting"),
print(res)
),
hasdivided: (second(res)#0),
reslist:append(reslist,[first(res)]),
num:expand(den),
den:second(res),
/* Si controlla se il risultato della divisione e' un monomio di grado 1
con coefficiente positivo */
if (hipow(first(res),p)>1) then (
ishurwitz:false
),
if (coeff(first(res),p,1)<0) then (
ishurwitz:false
)
),
if (length(reslist)=nm and ishurwitz) then
print("Polinomio strettamente hurwitziano")
elseif (ishurwitz) then
print("Polinomio hurwitziano in senso lato")
else
print("Polinomio non hurwiztiano"),
print(reslist),
reslist
)$
Una volta salvato lo script in un file, per esempio hurwitz.max, lo si può utilizzare all'interno di Maxima:
Codice: Seleziona tutto
(%i5) load("hurwitz.max");
(%o5) Hurwitz.max
(%i6) hurwitz(56*p^5+7*p^4+161*p^3+18*p^2+98*p+8,p);
Prova di Hurwitz per un polinomio
3
17 p + 34 p # 0
Calcolo delle divisioni successive
Polinomio hurwitziano in senso lato
7 p 17 p
[8 p, ---, ----]
17 4
7 p 17 p
(%o6) [8 p, ---, ----]
17 4
(%i7)
La funzione hurwitz(N,p) richiede il polinomio N nella variabile p ed effettua il test, che è basato su una serie di divisioni successive fra la parte pari e la parte dispari del poliniomio di partenza. Il programma restituisce una lista contenente i risultati delle divisioni.
Una cosa che mi piacerebbe fare una volta o l'altra è preparare altri script di questo tipo che applichino alcune procedure di sintesi empirica per le reti lineari passive. Che ne pensate?
