La NAN è adatta per comunicare che un parametro non valido è stato coinvolto in un calcolo?

8

Attualmente sto lavorando a un sistema di elaborazione numerica che verrà implementato in un ambiente critico per le prestazioni. Prende input sotto forma di array numerici (questi usano la libreria eigen , ma ai fini di questa domanda che è forse irrilevante), ed esegue alcuni range di calcoli numerici (prodotti matrix, concatenazioni, ecc.) Per produrre output.

Tutti gli array sono allocati staticamente e le loro dimensioni sono note al momento della compilazione. Tuttavia, alcuni degli ingressi potrebbero essere non validi. In questi casi eccezionali , vogliamo comunque che il codice sia calcolato e vogliamo comunque che le uscite non "inquinate" vengano utilizzate da valori non validi.

Per fare un esempio, prendiamo il seguente esempio banale (questo è pseudo-codice):

Matrix a = {1, 2, NAN, 4}; // this is the "input" matrix
Scalar b = 2;
Matrix output = b * a; // this results in {2, 4, NAN, 8}

L'idea qui è che 2, 4 e 8 sono valori utilizzabili, ma la NAN dovrebbe segnalare al destinatario dei dati che quella voce era coinvolta in un'operazione che comportava un valore non valido, e dovrebbe essere scartata (questo sarà rilevato tramite un controllo std::isfinite(value) prima che venga utilizzato il valore).

È un modo efficace di comunicare e propagare valori inutilizzabili, dato che le prestazioni sono critiche e l'allocazione dell'heap non è un'opzione (e nemmeno altri costrutti che consumano risorse come boost::optional o puntatori)?

Ci sono modi migliori per farlo? A questo punto sono abbastanza soddisfatto dell'attuale configurazione, ma speravo di ottenere nuove idee o critiche produttive all'attuale implementazione.

    
posta quant 20.08.2014 - 03:26
fonte

2 risposte

7

Questo è un modo assolutamente ragionevole per andare. Si noti inoltre che esistono più maschere di bit interpretate come NaN. Esistono due tipi principali di NaN: signaling (che può generare un'eccezione quando vengono creati, a seconda delle impostazioni) e quiet (che non fanno mai). Tuttavia, anche nei silenziosi NaN ci sono più maschere bit che corrispondono a NaN silenzioso. Se vuoi davvero entrarci, puoi creare i tuoi NaN che sono distinti dai normali NaN. Ad esempio, potresti usare uno schema di bit specifico che corrisponderebbe a NA (che è un concetto diverso da NaN).

Per quanto riguarda il punto sull'inquinamento. Questo diventa molto più complicato. Generalmente, qualsiasi operazione matematica che coinvolge NaN risulta in NaN. In altre parole, NaN è contagioso. In alcuni casi, questo è quello che vuoi. In altri, non lo è. Ad esempio, supponi che ti sia stata chiesta la media del vettore che hai dato. È NaN o 7/3? Il prodotto vettoriale scalare * che hai fornito, tuttavia, funzionerà esattamente come desideri e non dovrai eseguire alcun controllo di std::isfinite . Basta moltiplicare i numeri e il NaN si apre automaticamente, quindi è abbastanza performante. Se vuoi ottenere una media di 7/3, tuttavia, per il tuo vettore, devi essere più intelligente, perché farlo in modo ingenuo si tradurrà in NaN. Mentre non posso dirti come eseguire un'implementazione veloce di questo, numpy ne ha uno e il suo open source, quindi puoi guardarlo.

    
risposta data 20.08.2014 - 04:49
fonte
1

Mi suona bene finché hai il tuo modello in virgola mobile fisso, e hai detto la semantica di NaN.

IEEE 754 è sufficiente nel tuo caso.

link

link

    
risposta data 20.08.2014 - 04:27
fonte

Leggi altre domande sui tag