È valido aumentare l'ampiezza (e presumibilmente la qualità FFT) semplicemente ridimensionando i dati?


10

Sto usando una versione di "KISS FFT" di Mark Borgerding. Accetta una matrice di valori di input a punto fisso a 16 bit e produce una matrice di risultati float a 32 bit.

Ho scoperto che se le ampiezze di input sono basse, molti dei valori del risultato float risultano zero, ma se ridimensiono semplicemente gli input (per esempio, il fattore 16), allora un minor numero di valori di output è zero e quindi l'output sembra contenere più dettaglio. (Non che sia molto importante per i miei scopi, ma per coerenza divido quindi i valori float risultanti per lo stesso fattore di ridimensionamento.)

Ad ogni modo, questo sembra funzionare, in termini di produzione di un risultato quando in precedenza avrei appena ottenuto un buffer di praticamente tutti gli zeri, ma mi chiedo se c'è qualche ragione per cui potrebbe non essere un approccio valido.

(Si noti che questo approccio significa che c'è molta più "grossolanità" / granularità nei dati e, in particolare, il rumore di basso livello che sarebbe normalmente presente non lo è. Mi sto quasi chiedendo se sarebbe saggio iniettare del rumore di basso livello per sostituire i valori zero nell'ingresso.)


"Mi sto quasi chiedendo se sarebbe saggio iniettare un po 'di rumore di basso livello per sostituire i valori zero nell'input." = en.wikipedia.org/wiki/Dither
endolith

Risposte:


7

Questo può essere un approccio valido. Stai osservando un problema molto pratico che si presenta spesso quando usi l'aritmetica a punto fisso (cioè intero) (anche se può accadere anche in virgola mobile). Quando il formato numerico che si sta utilizzando per eseguire i calcoli non ha una precisione sufficiente per esprimere l'intera gamma di valori che possono derivare dai calcoli, è necessaria una forma di arrotondamento (ad esempio troncamento, arrotondamento al più vicino e così via su). Questo è spesso modellato come un errore di quantizzazione additiva al tuo segnale.

Tuttavia, per alcune combinazioni di algoritmo e schema di arrotondamento, quando l'entità del segnale di ingresso è molto bassa, è possibile ottenere ciò che è stato osservato: un gran numero di zero uscite. Fondamentalmente, da qualche parte nella sequenza delle operazioni, i risultati intermedi stanno diventando abbastanza piccoli da non rompere la soglia richiesta per quantizzare a un livello diverso da zero. Il valore viene quindi arrotondato a zero, che spesso può propagarsi in avanti verso l'output. Il risultato è, come hai notato, un algoritmo che genera molti zeri di output.

Quindi puoi aggirare questo ridimensionando i dati? A volte (ci sono pochissime tecniche che funzionano sempre!). Se il segnale di input è limitato in grandezza a un valore inferiore al fondo scala del formato numerico (numeri interi con segno a 16 bit vanno da -32768 a +32767), è possibile ridimensionare il segnale di input fino a utilizzare più completamente l'intervallo disponibile per esso. Ciò può aiutare a mitigare gli effetti dell'errore di arrotondamento, poiché l'entità di qualsiasi errore di arrotondamento diminuisce rispetto al segnale di interesse. Quindi, nel caso in cui tutti gli output vengano arrotondati agli zeri internamente all'algoritmo, questo può aiutare.

Quando una tale tecnica può farti del male? A seconda della struttura dei calcoli dell'algoritmo, il ridimensionamento del segnale di ingresso può esporre a overflow numerici. Inoltre, se il segnale contiene rumore di fondo o interferenze di entità maggiore dell'errore di arrotondamento dell'algoritmo, la qualità di ciò che si ottiene in uscita sarà generalmente limitata dall'ambiente, non dall'errore introdotto nel calcolo.


Sto usando una tecnica dinamica per il ridimensionamento che sembra funzionare abbastanza bene. E, per fortuna, i transitori estremi sono trattati come rumore e comunque ritagliati, quindi il ritaglio occasionale non dovrebbe essere un problema. Pensi che sia valido "decalcificare" l'output dividendo per il fattore di scala dell'input?
Daniel R Hicks,

1

Il modo più semplice e più semplice per risolvere questo problema è convertire i dati in virgola mobile PRIMA della FFT e utilizzare una FFT a virgola mobile. L'unico aspetto negativo di questo approccio sarebbe che potresti consumare più processore e memoria. Dato che l'output è comunque in virgola mobile, probabilmente c'è poca differenza pratica.


Mi è stato consegnato questo progetto con l'attuale algoritmo FFT già in atto, e sono riluttante a lasciar perdere a questo punto. E tutto sta succedendo su un telefono, in tempo reale, quindi le prestazioni sono sicuramente un problema.
Daniel R Hicks,

Inteso. Sai se l'interno FFT è fisso o in virgola mobile? Se è stato risolto, devi preoccuparti di ritaglio, overflow e underflow
Hilmar,

La documentazione e il commento sono eccezionali in sua assenza, ma vedo molti input nel codice e pochi float e doppi preziosi. Sembra includere il framework #ifdef grezzo per passare da 16-bit a 32-bit o float, ma il framework è apparentemente disabilitato da tempo.
Daniel R Hicks,

Un iPhone (ARM + NEON CPU) può eseguire un float FFT più velocemente (tramite il framework Accelerate) di un intero FFT in C.
hotpaw2
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.