2013-04-10 12 views
20

In Python NumPy, c'è una funzione che unwrap:fronte di numpy.unwrap

Unwrap fase radian p cambiando assoluto passa superiore discont al loro 2 * pi complemento lungo l'asse determinato.

Ora, mi piacerebbe fare la funzione opposta. Come posso avvolgere una serie di fasi? Per esempio. come convertire tutti gli angoli per vincolarli tra -π e π?

Il modo più ovvio sarebbe quello di fare qualcosa di simile:

for i, a in enumerate(phases): 
    while a < pi: 
     a += 2 * pi 
    while a > pi: 
     a -= 2 * pi 
    phases[i] = a 

, ma c'è un modo più semplice/più veloce?

risposta

27
phases = (phases + np.pi) % (2 * np.pi) - np.pi 
+2

Non mi sono reso conto che potrei usare l'operatore% con valori in virgola mobile. Ma perché stai aggiungendo π prima di eseguire il modulo? –

+1

perché è necessario se è necessario che il risultato sia compreso tra (-np.pi, np.pi) anziché (0,2 * np.pi). Se non lo aggiungi, ma sottrai, 0 verrà mappato in -> -np.pi che non è corretto –

+0

È ovvio! Mi sento stupido ora ...Non me ne sono reso conto perché sono interessato solo alla fase relativa, e non stavo attirando l'attenzione sulla fase assoluta. –

8
import numpy as np 
phases = np.arctan2(np.sin(phases), np.cos(phases)) 

Questo funziona perché il peccato (fasi)/cos (fasi) == tan (fasi). Otteniamo le fasi indietro (modulo 2π) usando la funzione inversa-tangente. Matematicamente, la funzione inversa tangente è multivalore, quindi nei linguaggi di programmazione viene solitamente definita per restituire la fase in un intervallo fisso.

La funzione arcotangente a due parametri, ovvero np.arctan2(numerator, denominator), è la stessa della normale funzione arcotangente, tranne per il fatto che tiene traccia dei segni del numeratore e del denominatore e pertanto è in grado di restituire il modulo fase 2π, anziché il normale np.arctan(numerator/denominator) funzione che è solo in grado di restituire il modulo di fase π. L'implementazione di Numpy della funzione arctan2 è definita per restituire la fase nell'intervallo [-π, + π], che è l'intervallo richiesto dall'OP.

Ulteriori spiegazione: Questo metodo arctan2 deriva direttamente dalla rappresentazione complessa, ed è interamente matematicamente equivalente a:

phases = np.angle(np.exp(1j*phases)) 

che può essere più intuitivo. In effetti, la funzione angle di numpy utilizza arctan2 dietro le quinte per separare i componenti immaginari e reali dell'esponenziale, cioè il seno e il coseno.

+1

Per favore spiega le tue risposte. È più probabile che l'OP capisca la tua risposta con poche frasi. – Ratbert

+0

Interrompere, ma probabilmente molto inefficiente ... Ma ti do l'uptote per la risposta ben scritta. –

+2

Concordo sul fatto che sia più lento dell'utilizzo dell'operatore '%', ma per me è più intuitivo (ma forse sono l'unico) perché segue direttamente dalla rappresentazione del numero complesso, vedi modifica. Inoltre, non devo pensare seriamente se l'operatore '%' di python mantiene il segno del divisore o del dividendo e come questo influenza il risultato, o se devo aggiungere e quindi sottrarre una costante prima e dopo aver eseguito la mod operazione per mantenere la fase risultante nell'intervallo che voglio. – u55

3

Questa risposta è una leggera variazione di sega_sai risposta che è:

phases = (phases + np.pi) % (2 * np.pi) - np.pi 

Questa mappa fasi di [-pi, pi) -> che significa PI è mappato a -pi

Mostrato qui:

In [27]: phases = np.pi 

In [28]: phases = (phases + np.pi) % (2 * np.pi) - np.pi 

In [29]: print phases 
-3.14159265359 

che è perfettamente legittimo, ma se si vuole una mappatura (-pi, pi] quindi

Tempi l'input e l'output dell'operazione acquistare -1. Così:

phases = ((-phases + np.pi) % (2.0 * np.pi) - np.pi) * -1.0