Ist NAN geeignet, um mitzuteilen, dass ein ungültiger Parameter an einer Berechnung beteiligt war?


9

Ich arbeite derzeit an einem numerischen Verarbeitungssystem, das in einer leistungskritischen Umgebung bereitgestellt wird. Es verwendet Eingaben in Form von numerischen Arrays (diese verwenden die eigenBibliothek, aber für den Zweck dieser Frage ist dies möglicherweise unerheblich) und führt eine Reihe von numerischen Berechnungen (Matrixprodukte, Verkettungen usw.) durch, um Ausgaben zu erzeugen.

Alle Arrays werden statisch zugeordnet und ihre Größen sind zur Kompilierungszeit bekannt. Einige der Eingaben sind jedoch möglicherweise ungültig. In diesen Ausnahmefällen möchten wir weiterhin, dass der Code berechnet wird, und wir möchten weiterhin, dass Ausgaben verwendet werden, die nicht durch ungültige Werte "verschmutzt" werden.

Nehmen wir als Beispiel das folgende einfache Beispiel (dies ist Pseudocode):

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}

Die Idee hier ist, dass 2, 4 und 8 verwendbare Werte sind, aber das NAN sollte dem Empfänger der Daten signalisieren, dass dieser Eintrag an einer Operation beteiligt war, die einen ungültigen Wert beinhaltete, und verworfen werden sollte (dies wird über a erkannt std::isfinite(value)prüfen, bevor der Wert verwendet wird).

Ist dies eine gute Möglichkeit, unbrauchbare Werte zu kommunizieren und zu verbreiten, da die Leistung kritisch ist und die Heap-Zuweisung keine Option ist (und andere ressourcenintensive Konstrukte wie boost::optionaloder Zeiger auch nicht)?

Gibt es dafür bessere Möglichkeiten? Zu diesem Zeitpunkt bin ich ziemlich zufrieden mit dem aktuellen Setup, aber ich hatte gehofft, einige neue Ideen oder produktive Kritik an der aktuellen Implementierung zu bekommen.


6
IMHO ist dies nur ein perfekter Anwendungsfall für ein nicht signalisierendes NAN.
david.pfx

Antworten:


8

Dies ist ein völlig vernünftiger Weg. Beachten Sie auch, dass es mehrere Bitmasken gibt, die als NaN interpretiert werden. Es gibt zwei Haupttypen von NaN: Signalisierung (die je nach Ihren Einstellungen eine Ausnahme auslösen kann, wenn sie erstellt wird) und leise (die niemals auftreten). Selbst innerhalb leiser NaNs gibt es jedoch mehrere Bitmasken, die leisem NaN entsprechen. Wenn Sie sich wirklich darauf einlassen möchten, können Sie Ihre eigenen NaNs erstellen, die sich von den regulären NaNs unterscheiden. Beispielsweise könnten Sie ein bestimmtes Bitmuster verwenden, das NA entspricht (was ein anderes Konzept als NaN ist).

Was Ihren Standpunkt zur Umweltverschmutzung betrifft. Das wird viel schwieriger. Im Allgemeinen führt jede mathematische Operation mit NaN zu NaN. Mit anderen Worten, NaN ist ansteckend. In einigen Fällen ist dies das, was Sie wollen. In anderen ist es nicht. Angenommen, Sie wurden nach dem Mittelwert des von Ihnen angegebenen Vektors gefragt. Ist es NaN oder 7/3? Das von Ihnen angegebene skalare * Vektorprodukt funktioniert jedoch genau so, wie Sie es möchten, und Sie müssen auch keine std::isfiniteÜberprüfung durchführen. Multiplizieren Sie einfach die Zahlen und das NaN erscheint automatisch, so dass es ziemlich performant ist. Wenn Sie jedoch für Ihren Vektor einen Mittelwert von 7/3 erhalten möchten, müssen Sie klüger sein, da eine naive Ausführung zu NaN führt. Ich kann Ihnen zwar nicht sagen, wie Sie dies schnell implementieren können, aber numpy hat eine und Open Source, also können Sie sich das ansehen.


1

Klingt für mich gut, solange Sie Ihr Gleitkommamodell repariert haben und NaN-Semantik gesagt haben.

IEEE 754 ist in Ihrem Fall ausreichend.

http://en.m.wikipedia.org/wiki/Single-precision_floating-point_format

/programming/5777484/how-to-check-if-c-compiler-uses-ieee-754-floating-point-standard


2
Würde es Ihnen etwas ausmachen, die Ressourcen dieser Ressourcen ein wenig zu erweitern, und warum empfehlen Sie diese als Antwort auf die gestellte Frage? "Nur-Link-Antworten" sind bei Stack Exchange nicht ganz willkommen
Mücke
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.