2011-11-18 31 views
13

Ho raggiunto il punto in un progetto in cui ha più senso iniziare a costruire alcune classi di supporto per i vettori e la trigonometria multipla che continuare a utilizzare funzioni ad-hoc. Mi aspetto che ci siano molte librerie C++ per questo, ma non voglio sacrificare la velocità e le funzionalità a cui sono abituato.Libreria C++ per la trigonometria di interi, velocità ottimizzata con approssimazioni opzionali?

In particolare, voglio essere in grado di utilizzare gli angoli interi, e voglio mantenere la velocità sorprendente offerta da approssimazioni come questo:

static inline int32_t sin_approx(int32_t angle) 
//Angle is -32768 to 32767: Return -32768 to 32767 
{ 
    return (angle<<1) - ((angle*abs(angle))>>14); 
} 

Quindi, prima che io inutilmente rotolare il mio, c'è qualche sono davvero veloci librerie a virgola fissa per C++ con classi template come vettori in cui posso specificare la larghezza del numero intero usato e che ha approssimazioni rapide come quella sopra che dovrei guardare?

+0

Come è un'approssimazione per il peccato? – TonyK

+0

Sinceramente non lo so. L'ho scritto un anno fa basandomi sull'approssimazione del peccato in virgola mobile usando, credo, una funzione parabolica. Dopo averlo diviso in numero intero, ne risultava. Avendo dimenticato la funzione originale, non ho idea di come funzioni più. Disegna però un cerchio quasi perfetto. – porgarmingduod

+2

Oh, lo vedo ora. Si approssima a ciascuna metà dell'intervallo come una parabola con zero a 0 e 2 e valore massimo/minimo +/- 1. Bello! – TonyK

risposta

4

Ho seguito questo percorso alcuni anni fa quando ho dovuto convertire un codice di impronte digitali audio da virgola mobile a virgola fissa. Le parti difficili erano il DCT (che utilizzava una tabella coseno di grandi dimensioni) e un logaritmo di alta precisione. Ho trovato sorprendentemente piccolo nel modo di librerie esistenti. Da allora, ho sentito che l'originale Sony PlayStation (PS1) non aveva supporto a virgola mobile, quindi i forum di sviluppo (fori?) Per esso, se ancora esistono, potrebbero avere quello che stai cercando.

Alcune persone con cui ho lavorato hanno avuto fortuna con la libreria NewMat, sebbene sia orientata all'algebra lineare piuttosto che alla trigonometria e sembra concentrarsi su numeri in virgola mobile. Ancora, il suo sito porta a this list, che sembra valere la pena di verificare. Ho anche trovato spuc, una libreria di elaborazione del segnale che potrebbe essere utile per il supporto a punto fisso. E anni fa ho visto una libreria modello di elaborazione del segnale (sptl) di Fraunhofer. Penso che fosse proprietario, ma potrebbe essere disponibile in qualche modo.

Tutto ciò detto, penso che tu sia molto vicino a quello che hai già. Dato che hai una funzione seno, in pratica hai anche una funzione coseno, a patto di trasformare l'input in modo appropriato (cos(x) == sin(x + pi/2)). Poiché la tangente è il quoziente del seno e del coseno (tan(x) = sin(x)/cos(x)), sei fondamentalmente lì per la trigonometria.

Per quanto riguarda i vettori, le classi vettoriali STL e valarray combinate con gli algoritmi STL non ti sembrano abbastanza vicini? In caso contrario, c'è sempre il math libraries di Boost.

Scusa, non posso indicarti il ​​proiettile d'argento che stai cercando, ma quello che stai cercando di fare è piuttosto raro in questi giorni. Le persone che vogliono la precisione di solito vanno dritte al punto di virgola mobile, con prestazioni decenti su processori moderni e un sacco di supporto per le librerie. Coloro che vogliono velocità su hardware con risorse limitate di solito non hanno bisogno di precisione e non stanno facendo trig da parte del vettore, e probabilmente non stanno facendo neanche C++. Penso che la tua migliore opzione sia quella di tirare il tuo. Prova a pensare ad esso applicando il modello di progettazione delle ruote in un nuovo contesto, piuttosto che reinventarlo. :)

+0

Un sacco di buone informazioni, davvero. Sono scioccato nel vedere che ho perso la libreria geometrica di boost (anche se potrebbe essere eccessivo in ogni caso) – porgarmingduod