EnglischFranzösischSpanisch

OnWorks-Favicon

PDL::BadValuesp - Online in der Cloud

Führen Sie PDL::BadValuesp im kostenlosen OnWorks-Hosting-Anbieter über Ubuntu Online, Fedora Online, Windows-Online-Emulator oder MAC OS-Online-Emulator aus

Dies ist der Befehl PDL::BadValuesp, der im kostenlosen OnWorks-Hosting-Provider mit einer unserer zahlreichen kostenlosen Online-Workstations wie Ubuntu Online, Fedora Online, Windows-Online-Emulator oder MAC OS-Online-Emulator ausgeführt werden kann

PROGRAMM:

NAME/FUNKTION


PDL::BadValues ​​- Diskussion über die Unterstützung von schlechten Werten in PDL

BESCHREIBUNG


Was sind Badewanne Werte und warum sollte I Mühe mit Sie?
Manchmal ist es nützlich, einen bestimmten Wert als „schlecht“ oder „fehlend“ angeben zu können; zum
Beispiel CCDs, die in der Astronomie verwendet werden, erzeugen 2D-Bilder, die nicht perfekt sind, da bestimmte Bereiche
enthalten ungültige Daten aufgrund von Mängeln im Detektor. Während der leistungsstarke Index von PDL
Routinen und all die komplizierten Geschäfte mit Datenfluss, Slices usw. usw. bedeuten, dass diese
Regionen können bei der Verarbeitung ignoriert werden, was umständlich ist. Es wäre viel einfacher zu sein
in der Lage, "$c = $a + $b" zu sagen und den ganzen Ärger dem Computer zu überlassen.

Wenn Sie das nicht interessiert, können Sie sich (zu Recht) Gedanken darüber machen, wie das geht
wirkt sich auf die Geschwindigkeit von PDL aus, da der Aufwand für die Überprüfung auf einen falschen Wert bei jeder Operation
kann groß sein. Aus diesem Grund wurde der Code so schnell wie möglich geschrieben -
insbesondere beim Betrieb auf Piddles, die keine schlechten Werte enthalten. Tatsächlich bist du
sollte im Wesentlichen keinen Geschwindigkeitsunterschied feststellen, wenn mit Piddles gearbeitet wird, die dies nicht tun
enthalten schlechte Werte.

Wenn Sie jedoch keine schlechten Werte wünschen, dann ist die Konfigurationsoption "WITH_BADVAL" von PDL
kommt zur Rettung; wenn auf 0 oder undef gesetzt, wird die Unterstützung für ungültige Werte ignoriert. Über die
das einzige Mal, dass du das denke ich brauchst - ich gebe zu, ich bin voreingenommen ;) - ist, wenn du es hast
begrenzter Festplatten- oder Speicherplatz, da die Größe des Codes erhöht wird (siehe unten).

Sie können sich auch fragen: "Nun, mein Computer unterstützt IEEE NaN, also habe ich das bereits". Nun ja
und nein - viele Routinen, wie "y=sin(x)", werden NaNs verbreiten, ohne dass der Benutzer dies hat
anders codieren, aber Routinen wie "qsort" oder das Ermitteln des Medians eines Arrays benötigen
neu codiert werden, um mit schlechten Werten umzugehen. Für Gleitkomma-Datentypen sind "NaN" und "Inf"
verwendet, um schlechte Werte zu kennzeichnen IF die Option "BADVAL_USENAN" ist in Ihrer Konfigurationsdatei auf 1 gesetzt.
Andernfalls werden spezielle Werte verwendet (Default bad values). Ich habe keine Benchmarks zu
Sehen Sie, welche Option schneller ist.

Es gibt eine experimentelle Funktion "BADVAL_PER_PDL", die Ihnen, wenn sie gesetzt ist, ermöglicht,
verschiedene schlechte Werte für separate Piddles des gleichen Typs. Das geht derzeit nicht
mit der Option "BADVAL_USENAN"; wenn beide gesetzt sind, ignoriert PDL das "BADVAL_USENAN"
Wert.

Code Energie zwei zu Badewanne Werte
Der folgende Vergleich ist veraltet!

Auf einem i386-Rechner mit Linux und Perl 5.005_03 habe ich die folgenden Größen gemessen (die
Slatec-Code wurde einkompiliert, aber keine der anderen Optionen: zB FFTW, GSL und TriD
wurden):

WITH_BADVAL = 0
Größe des blib-Verzeichnisses nach erfolgreichem make = 4963 kb: blib/arch = 2485 kb und
blib/lib = 1587 KB.

WITH_BADVAL = 1
Größe des blib-Verzeichnisses nach erfolgreichem make = 5723 kb: blib/arch = 3178 kb und
blib/lib = 1613 KB.

Der Gesamtanstieg beträgt also einzige 15% - nicht viel zu bezahlen für all die Wunder, die schlechte Werte haben
bietet ;)

Der für diesen Test verwendete Quellcode enthielt die überwiegende Mehrheit der Kernroutinen (z
Basic/) konvertiert, um schlechte Werte zu verwenden, während nur sehr wenige der 'externen' Routinen (dh
alles andere in der PDL-Distribution) wurde geändert.

A schnell Überblick
pdl> p $PDL::Bad::Status
1
pdl> $a = Sequenz(4,3);
pdl> p $a
[
[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
]
pdl> $a = $a->setbadif( $a % 3 == 2 )
pdl> p $a
[
[ 0 1 SCHLECHT 3]
[ 4 SCHLECHTE 6 7]
[SCHLECHT 9 10 SCHLECHT]
]
pdl> $a *= 3
pdl> p $a
[
[ 0 3 SCHLECHT 9]
[ 12 SCHLECHTE 18 21]
[SCHLECHT 27 30 SCHLECHT]
]
pdl> p $a->sum
120

"demo bad" und "demo bad2" in perldl oder pdl2 demonstrieren einige der
Dinge möglich mit schlechten Werten. Diese sind auch auf der Website von PDL verfügbar unter
http://pdl.perl.org/demos/. Siehe PDL::Bad für nützliche Routinen zum Arbeiten mit schlechten Werten
und t/schlecht.t um sie in Aktion zu sehen.

Die Absicht ist:

· Beeinflusst PDL nicht wesentlich für Benutzer, die keinen Support mit schlechtem Wert benötigen

· so schnell wie möglich sein, wenn eine schlechte Wertunterstützung installiert ist

Wenn Sie keine Unterstützung für schlechte Werte wünschen, setzen Sie "WITH_BADVAL" auf 0 in perldl.conf; PDL
hat dann keine Unterstützung für schlechte Werte einkompiliert, ist also so schnell wie früher.

In den meisten Fällen hat die Unterstützung für einen schlechten Wert jedoch einen vernachlässigbaren Einfluss auf die Geschwindigkeit, sodass Sie
sollte "WITH_CONFIG" auf 1 setzen! Eine Ausnahme ist, wenn Sie wenig Arbeitsspeicher haben, da die Menge
des produzierten Codes ist größer (aber nur um etwa 15% - siehe "Codezunahme aufgrund von Fehlern"
Werte").

Um herauszufinden, ob PDL mit Unterstützung für schlechte Werte kompiliert wurde, sehen Sie sich die Werte von beiden an
$PDL::Config{WITH_BADVAL} oder $PDL::Bad::Status - wenn wahr, dann war dies der Fall.

Um herauszufinden, ob eine Routine schlechte Werte unterstützt, verwenden Sie den Befehl "badinfo" in perldl oder pdl2
oder die Option "-b" für pdldoc. Diese Einrichtung ist derzeit ein "Proof of Concept" (oder mehr
realistisch, ein schneller Hack), also erwarten Sie, dass es an den Rändern rau ist.

Jedes Piddle enthält ein Flag - erreichbar über "$pdl->badflag" - um anzuzeigen, ob es eines gibt
fehlerhafte Daten vorhanden:

· Wenn falsch/0, was bedeutet, dass es hier keine schlechten Daten gibt, der vom "Code" gelieferte Code
Option zu "pp_def()" wird ausgeführt. Dies bedeutet, dass die Geschwindigkeit sehr nahe bei liegen sollte
die mit "WITH_BADVAL=0" erhalten wird, da der einzige Overhead mehrere Zugriffe auf a
Bit in der Zustandsvariablen Piddles.

· Wenn wahr/1, dann steht das dort MAI seien Sie schlechte Daten in der Piddle, also verwenden Sie den Code in der
Option "BadCode" (vorausgesetzt, dass "pp_def()" für diese Routine aktualisiert wurde auf
einen BadCode-Schlüssel haben). Sie erhalten alle Vorteile des Einfädelns, wie beim "Code"
Option, aber es wird langsamer ausgeführt, da Sie mit der Anwesenheit von umgehen müssen
schlechte Werte.

Wenn Sie ein Piddle erstellen, wird das Flag für einen schlechten Wert auf 0 gesetzt. Um dies zu ändern, verwenden Sie
"$pdl->badflag($new_bad_status)", wobei $new_bad_status 0 oder 1 sein kann. Wenn eine Routine
erzeugt ein Piddle, sein Flag für einen schlechten Wert hängt von den eingegebenen Piddles ab: sofern nicht überschrieben
(siehe die Option "CopyBadStatusCode" zu "pp_def"), das Flag für ungültige Werte wird auf true gesetzt, wenn
irgendwelche der Eingabepiddles enthalten schlechte Werte. Um zu überprüfen, ob ein Piddle wirklich schlechtes enthält
Daten verwenden, verwenden Sie die Methode "check_badflag".

HINWEIS: Verbreitung der Badflag

Wenn Sie die Badflag eines Piddle ändern, wird diese Änderung an alle und Kindern einer
pudel, also

pdl> $a = Nullen(20,30);
pdl> $b = $a->slice('0:10,0:10');
pdl> $c = $b->slice(',(2)');
pdl> print ">>c: ", $c->badflag, "\n";
>>c: 0
pdl> $a->schlechte Flagge(1);
pdl> print ">>c: ", $c->badflag, "\n";
>>c: 1

Nein Die Eltern eines Pudels ändern sich, also

pdl> print ">>a: ", $a->badflag, "\n";
>>a: 1
pdl> $c->schlechte Flagge(0);
pdl> print ">>a: ", $a->badflag, "\n";
>>a: 1

Gedanken:

· die Badflag kann NUR gelöscht werden, WENN ein Piddle KEINE Eltern hat und diese Änderung dies tun wird
auf alle Kinder dieses Pudels ausbreiten. Ich bin nicht mehr so ​​scharf darauf (auch
zum einen umständlich zu codieren).

· "$a->schlechte Flagge(1)" sollte die Badflag sowohl an Eltern als auch an Kinder weitergeben.

Dies sollte nicht schwer zu implementieren sein (obwohl ein erster Versuch fehlgeschlagen ist!). Macht es
Sinn aber? Es gibt auch die Frage, was passiert, wenn Sie den schlechten Wert von a . ändern
piddle - sollen sich diese auf Kinder/Eltern ausbreiten (ja) oder ob du es nur sein solltest
in der Lage, den schlechten Wert auf der 'obersten' Ebene zu ändern - dh die Piddles, die keine haben
Eltern.

Die Methode "orig_badvalue()" gibt den Kompilierzeitwert für einen bestimmten Datentyp zurück. Es klappt
auf Piddles, PDL::Type-Objekten und Zahlen - zB

$pdl->orig_badvalue(), byte->orig_badvalue() und orig_badvalue(4).

Es hat auch einen schrecklichen Namen...

Um den aktuellen ungültigen Wert zu erhalten, verwenden Sie die Methode "badvalue()" - sie hat die gleiche Syntax wie
"orig_badvalue()".

Um den aktuellen ungültigen Wert zu ändern, geben Sie die neue Zahl an badvalue an - zB

$pdl->badvalue(2.3), byte->schlechter Wert(2), schlechter Wert(5,-3e34).

Note: Der Wert wird stillschweigend in den richtigen C-Typ konvertiert und zurückgegeben - dh
"byte->badvalue(-26)" gibt 230 auf meinem Linux-Rechner zurück. Es ist auch ein "Nop" für Floating-
Punkttypen, wenn "BADVAL_USENAN" wahr ist.

Beachten Sie, dass Änderungen des ungültigen Werts NICHT auf zuvor erstellte Piddles propagiert - sie
wird immer noch der schlechte Wert gesetzt, aber plötzlich werden die Elemente, die schlecht waren, zu
'gut', enthält aber den alten schlechten Wert. Siehe Diskussion unten. Es ist kein Problem für
Gleitkommatypen, die NaN verwenden, da Sie ihren schlechten Wert nicht ändern können.

Badewanne Werte und boolean durch
Bei diesen booleschen Operatoren in PDL::Ops gibt die Auswertung eines ungültigen Werts den ungültigen Wert zurück.
Dies bedeutet zwar, dass

$maske = $img > $thresh;

falsche Werte richtig propagiert, es werden wir Probleme bei Kontrollen verursachen, wie z

do_something() falls vorhanden ( $img > $thresh );

die als etwas wie umgeschrieben werden müssen

do_something() falls vorhanden( setbadtoval( ($img > $thresh), 0 ) );

Bei Verwendung einer der 'Projektion'-Funktionen in PDL::Ufunc - wie orover - schlechte Werte
werden übersprungen (aktuelle (schlechte) Handhabung siehe Dokumentation dieser Funktionen
der Fall, wenn alle Elemente schlecht sind).

A Badewanne Wert für jeder pinkeln, und bezogene Probleme
An experimentell Option "BADVAL_PER_PDL" wurde hinzugefügt perldl.conf pro Piddle zulassen
schlechte Werte. Die Dokumentation wurde nicht aktualisiert, um diese Änderung zu berücksichtigen.

Das Folgende ist nur für Integer-Typen und für Gleitkomma-Typen relevant, wenn
"BADVAL_USENAN" wurde beim Erstellen der PDL nicht gesetzt.

Derzeit gibt es für jeden Datentyp einen ungültigen Wert. Der Code ist so geschrieben, dass wir konnten
für jeden Piddle einen eigenen schlechten Wert haben (in der pdl-Struktur gespeichert) - das wäre dann
Entfernen Sie das aktuelle Problem von:

pdl> $a = byte( 1, 2, byte->badvalue, 4, 5 );
pdl> p$a;
[1 2 255 4 5]
pdl> $a->schlechte Flagge(1)
pdl> p$a;
[1 2 SCHLECHT 4 5]
pdl> byte->schlechter Wert(0);
pdl> p$a;
[1 2 255 4 5]

dh der schlechte Wert in $a hat seinen Wert verloren Badewanne Status mit der aktuellen Implementierung. Es würde
aber mit ziemlicher Sicherheit an anderer Stelle Probleme verursachen!

IMPLEMENTIERUNG DETAILS


Während eines "perl Makefile.PL" wird die Datei Basic/Core/badsupport.p geschaffen; Diese Datei
enthält die Werte der Variablen "WITH_BADVAL", "BADVAL_USENAN" und "BADVAL_PER_PDL",
und sollte von Code verwendet werden, der vor dem ausgeführt wird PDL::Config Datei wird erstellt (zB
Basic/Core/pdlcore.c.PL. Die meisten PDL-Codes müssen jedoch nur auf %PDL::Config zugreifen
Array (zB Einfach/Schlecht/schlecht.pd), um herauszufinden, ob eine Wertminderung erforderlich ist.

Dem Status eines Piddles wurde ein neues Flag hinzugefügt - "PDL_BADVAL". Wenn nicht gesetzt, dann
piddle enthält keine ungültigen Werte, sodass der gesamte Support-Code ignoriert werden kann. Wenn eingestellt, ist es
garantiert nicht, dass schlechte Werte vorhanden sind, sondern dass sie überprüft werden sollten.
Danke an Christian, "badflag()" - was dieses Flag setzt/löscht (siehe Einfach/Schlecht/schlecht.pd) -
wird aktualisiert ALLER die Kinder/Enkel/usw. eines Pudels, wenn sich sein Zustand ändert (siehe
"badflag" in Einfach/Schlecht/schlecht.pd und "propagate_badflag" in Basic/Core/Core.xs.PL). Es ist nicht
klar, was mit den Eltern zu tun ist: Ich kann den Grund für die Verbreitung einer 'set Badflag' sehen
Bitte an die Eltern, aber ich denke, ein Kind sollte NICHT in der Lage sein, die Badflag von a zu löschen
Elternteil. Es gibt auch die Frage, was passiert, wenn Sie den schlechten Wert für a change ändern
pinkeln.

Die Struktur "pdl_trans" wurde um einen Integer-Wert "bvalflag" erweitert, der
fungiert als Schalter, der dem Code mitteilt, ob er mit schlechten Werten umgehen soll oder nicht. Dieser Wert ist eingestellt
wenn bei einem der Eingabepiddles das Flag "PDL_BADVAL" gesetzt ist (obwohl dieser Code
ersetzt durch Einstellung von "FindBadStateCode" in pp_def). Die Logik der Prüfung wird erhalten
ein bisschen komplizierter, wenn ich zulasse, dass Routinen auf den Abschnitt "Code" zurückgreifen für
Gleitkommatypen (dh die Routinen mit "NoBadifNaN => 1" wenn "BADVAL_USENAN" ist
wahr).

Die schlechten Werte für die Integer-Typen werden jetzt in einer Struktur innerhalb der Core PDL gespeichert
Struktur - "PDL.bvals" (zB Basic/Core/pdlcore.h.PL); siehe auch "typedef badvals" in
Basic/Core/pdl.h.PL und der BOOT-Code von Basic/Core/Core.xs.PL wo die Werte sind
auf (hoffentlich) sinnvolle Werte initialisiert. Sehen PDL/Bad/Bad.pd für Lese-/Schreibroutinen an
die Werte.

Das Hinzufügen der Option "BADVAL_PER_PDL" hat zu weiteren Änderungen an der
Innereien von Pudel. Diese Änderungen sind noch nicht dokumentiert.

Warum nicht um a PDL Unterklasse?
Die Unterstützung für schlechte Werte hätte als PDL-Unterklasse erfolgen können. Der Vorteil davon
Ansatz wäre, dass Sie den Code nur dann laden, um mit schlechten Werten umzugehen, wenn Sie es wirklich wollen
sie zu benutzen. Der Nachteil ist, dass der Code dann getrennt wird: jeder Fehler
Korrekturen/Verbesserungen müssen am Code in zwei verschiedenen Dateien vorgenommen werden. Mit der Gegenwart
Ansatz ist der Code in der gleichen "pp_def" Funktion (obwohl es immer noch das Problem gibt
dass sowohl die Abschnitte "Code" als auch "BadCode" aktualisiert werden müssen).

Standard Badewanne Werte
Die standardmäßigen/ursprünglichen ungültigen Werte sind eingestellt auf (aus der Starlink-Distribution):

#enthalten

PDL_Byte == UCHAR_MAX
PDL_Kurz == SHRT_MIN
PDL_Ushort == USHRT_MAX
PDL_Long == INT_MIN

Wenn "BADVAL_USENAN == 0", dann haben wir auch

PDL_Float == -FLT_MAX
PDL_Double == -DBL_MAX

andernfalls werden alle "NaN", "+Inf" und "-Inf" als schlecht für Gleitkommatypen angesehen.
In diesem Fall kann der ungültige Wert im Gegensatz zu den Integer-Typen nicht geändert werden.

Wie do I Übernehmen a Routine zu Griff Badewanne Werte?
Beispiele finden sich in den meisten *.pd Dateien in Basic/ (und hoffentlich noch viele weitere Orte
demnächst!). Die Logik mag etwas unklar erscheinen - das liegt wahrscheinlich daran!
Kommentare erwünscht.

Alle Routinen sollten das Flag für den schlechten Status automatisch an die Ausgabepiddles weitergeben, es sei denn,
du erklärst etwas anderes.

Wenn eine Routine explizit mit ungültigen Werten umgeht, müssen Sie pp_def diese Option bereitstellen:

HandleBad => 1

Dadurch wird sichergestellt, dass die richtigen Variablen für die $ISBAD etc.-Makros initialisiert werden. es ist
wird auch von den automatischen Dokumenterstellungsroutinen verwendet, um Standardinformationen zu
die schlechte Wertunterstützung einer Routine, ohne dass der Benutzer sie selbst eingeben muss (das ist
im Anfangsstadium).

Um eine Routine so zu kennzeichnen, dass sie NICHT mit schlechten Werten umgeht, verwenden Sie

HandleBad => 0

Dieses sollte veranlassen, dass die Routine eine Warnung ausgibt, wenn sie irgendwelche Piddles mit dem Bad gesendet hat
Flagge gesetzt. Primitives "Intover" hatte dieses Set - da es umständlich wäre, es zu konvertieren -
aber ich habe es nicht ausprobiert, ob es funktioniert.

Wenn Sie mit schlechten Werten umgehen möchten, aber nicht den Status aller Ausgabepiddles festlegen möchten, oder wenn
Wichtig ist nur eine Eingabepflöcke, dann schau dir die PP-Regeln an
"NewXSFindBadStatus" und "NewXSCopyBadStatus" und die entsprechenden "pp_def"-Optionen:

FindBadStatusCode
Standardmäßig erstellt "FindBadStatusCode" Code, der "$PRIV(bvalflag)" abhängig von . setzt
der Zustand des Bad-Flags der Eingabepiddles: siehe "findbadstatus" in
Basic/Gen/PP.pm. Benutzerdefinierter Code sollte auch den Wert von "bvalflag" im
"$BADFLAGCACHE()"-Variable.

CopyBadStatusCode
Der Standardcode hier ist etwas einfacher als bei "FindBadStatusCode": das Bad-Flag von
die Ausgabepiddles werden gesetzt, wenn "$BADFLAGCACHE()" wahr ist, nachdem der Code erstellt wurde
bewertet. Manchmal wird "CopyBadStatusCode" auf einen leeren String gesetzt, mit dem
Verantwortung für das Setzen des Badflags des Ausgabepiddles links neben dem "BadCode"
Abschnitt (zB die "xxxover"-Routinen in Basic/Primitiv/Primitiv.pd).

Vor PDL 2.4.3 haben wir "$PRIV(bvalflag)" anstelle von "$BADFLAGCACHE()" verwendet. Das ist
gefährlich, da die Gültigkeit der Struktur "$PRIV()" zu diesem Zeitpunkt nicht garantiert ist
der Code.

Wenn Sie eine Routine haben, die Sie direkt verwenden möchten, sehen Sie sich die Routinen in an
schlecht.pd (oder ops.pd), die die Option "in-place" verwenden, um zu sehen, wie das Bad-Flag verbreitet wird
an Kinder mit den Optionen "xxxBadStatusCode". Ich habe mich entschieden, dies nicht als Regeln zu automatisieren
wäre etwas komplex, da nicht jede In-Place-Operation die Badflag verbreiten muss
(zB unäre Funktionen).

Wenn die Option

HandleBad => 1

gegeben ist, dann passieren viele Dinge. Bei Integer-Typen wird der Readdata-Code automatisch
erstellt eine Variable namens " _badval", was den schlechten Wert dafür enthält
piddle (siehe "get_xsdatapdecl()" in Basic/Gen/PP/PdlParObjs.pm). Jedoch nicht hart codieren
diesen Namen in Ihren Code! Verwenden Sie stattdessen Makros (danke an Tuomas für den Vorschlag):

'$ISBAD(a(n=>1))' wird zu '$a(n=>1) == a_badval'
'$ISGOOD(a())' '$a() != a_badval'
'$SETBAD(bob())' '$bob() = bob_badval'

gut, das "$a(...)" wird auch erweitert. Sie können auch ein "$" vor dem pdl-Namen verwenden, wenn
Sie es wünschen, aber es beginnt wie Linienrauschen auszusehen - zB "$ISGOOD($a())".

Wenn Sie einen Piddle-Wert in einer Variablen zwischenspeichern -- zB "index" in scheiben.pd -- folgende
Routinen sind nützlich:

'$ISBADVAR(c_var,pdl)' 'c_var == pdl_badval'
'$ISGOODVAR(c_var,pdl)' 'c_var != pdl_badval'
'$SETBADVAR(c_var,pdl)' 'c_var = pdl_badval'

Folgendes wurde eingeführt, Sie müssen möglicherweise mit ihnen herumspielen, um ihre zu verbessern
verwenden.

'$PPISBAD(CHILD,[i]) 'CHILD_physdatap[i] == CHILD_badval'
'$PPISGOOD(CHILD,[i]) 'CHILD_physdatap[i] != CHILD_badval'
'$PPSETBAD(CHILD,[i]) 'CHILD_physdatap[i] = CHILD_badval'

Wenn "BADVAL_USENAN" gesetzt ist, dann ist es für "float" und "double" etwas anders, wo wir
betrachten "NaN", "+Inf" und "-Inf" alle als schlecht. In diesem Fall:

ISBAD wird endlich(piddle) == 0
ISGOOD endlich(piddle) != 0
SETBAD piddle = NaN

wobei der Wert für NaN weiter unten in Umgang mit NaN-Werten besprochen wird.

Das alles bedeutet, dass Sie sich ändern können

Code => '$a() = $b() + $c();'

zu

BadCode => 'if ( $ISBAD(b()) || $ISBAD(c()) ) {
$SETBAD(a());
} Else {
$a() = $b() + $c();
}'

Code so lassen wie er ist. PP::PDLCode erstellt dann eine Schleife wie etwa

if ( __trans->bvalflag ) {
Threadloop über BadCode
} Else {
Threadloop über Code
}

(es ist wahrscheinlich einfacher, sich nur die anzuschauen .xs Datei, um zu sehen, was passiert).

Teilnehmen Darüber hinaus Code Abschnitt
Ähnlich wie bei "BadCode" gibt es "BadBackCode" und "BadRedoDimsCode".

Der Umgang mit "EquivCPOffsCode" ist etwas anders: unter der Annahme, dass der einzige Zugriff
zu Daten erfolgt über das Makro "$EQUIVCPOFFS(i,j)", dann können wir automatisch das 'bad' erstellen
Version davon; siehe die Regeln "[EquivCPOffsCode]" und "[Code]" in PDL::PP.

Makro Zugang zu Badewanne Flagge of a pinkeln
Es wurden Makros bereitgestellt, um den Zugriff auf den Bad-Flag-Status eines PDL zu ermöglichen:

'$PDLSTATEISBAD(a)' -> '($PDL(a)->Zustand & PDL_BADVAL) > 0'
'$PDLSTATEISGOOD(a)' '($PDL(a)->Zustand & PDL_BADVAL) == 0'

'$PDLSTATESETBAD(a)' '$PDL(a)->Zustand |= PDL_BADVAL'
'$PDLSTATESETGOOD(a)' '$PDL(a)->Zustand &= ~PDL_BADVAL'

Für die Verwendung in "xxxxBadStatusCode" (+ andere Sachen, die in den INIT:-Abschnitt gehen) gibt es:

'$SETPDLSTATEBAD(a)' -> 'a->Zustand |= PDL_BADVAL'
'$SETPDLSTATEGOOD(a)' -> 'a->Zustand &= ~PDL_BADVAL'

'$ISPDLSTATEBAD(a)' -> '((a->Zustand & PDL_BADVAL) > 0)'
'$ISPDLSTATEGOOD(a)' -> '((a->Zustand & PDL_BADVAL) == 0)'

In PDL 2.4.3 wurde das Makro "$BADFLAGCACHE()" zur Verwendung in "FindBadStatusCode" eingeführt und
"BadStatusCode kopieren".

Handling NaN Werte
Es gibt zwei Probleme:

NaN als schlechter Wert
was gemacht ist. Zur Auswahl setzen Sie "BADVAL_USENAN" in der perldl.conf auf 1; ein Wert von 0 fällt
zurück zur Behandlung der Gleitkommatypen wie der Ganzzahlen. ich muss was machen
Benchmarks, um zu sehen, was schneller ist und ob es von Maschinen abhängt (Linux scheint
in einigen sehr einfachen Tests, die ich durchgeführt habe, viel mehr verlangsamen als meine Sparc-Maschine).

Ignorieren von BadCode-Abschnitten
welches ist nicht.

Für einfach Routinen, die Gleitkommazahlen verarbeiten, sollten wir den Computer verarbeiten lassen
die schlechten Werte (dh "NaN" und "Inf" Werte) anstatt den Code im "BadCode" zu verwenden
Sektion. Viele dieser Routinen wurden mit "NoBadifNaN => 1" gekennzeichnet; aber das ist
zur Zeit ignoriert von PDL::PP.

Für diese Routinen möchten wir den Abschnitt "Code" verwenden, wenn

das Piddle hat sein schlechtes Flag nicht gesetzt
der Datentyp ist ein Float oder Double

andernfalls verwenden wir den Abschnitt "BadCode". Das ist NICHT UMSETZT, wie es erforderlich ist
vernünftiges Hacken von PP::PDLCode!

Es gibt auch das Problem, wie wir mit 'Ausnahmen' umgehen - da "$a = Herr(2) / Herr(0) "
erzeugt einen schlechten Wert, aktualisiert aber nicht den Badflag-Wert des Piddles. Können wir einen fangen?
Ausnahme, oder müssen wir dafür eine Falle stellen (zB Suche nach "Ausnahme" in
Basic/Ops/ops.pd)?

Die Überprüfung auf "Nan" und "Inf" erfolgt mit dem Systemaufruf "finite()". Wenn du möchtest
setze einen Wert auf den "NaN"-Wert, das folgende Code-Bit kann verwendet werden (dieses kann gefunden werden)
in beiden Basic/Core/Core.xs.PL und Einfach/Schlecht/schlecht.pd):

/* für Big-Endian-Maschinen */
statische Vereinigung { unsigned char __c[4]; schweben __d; }
__pdl_nan = { {0x7f, 0xc0, 0, 0}};

/* für Little-Endian-Maschinen */
statische Vereinigung { unsigned char __c[4]; schweben __d; }
__pdl_nan = { {0, 0, 0xc0, 0x7f}};

Dieser Ansatz sollte wahrscheinlich durch Bibliotheksroutinen wie "nan("")" oder
"atof("NaN")".

Um herauszufinden, ob eine bestimmte Maschine Big-Endian ist, verwenden Sie die Routine
"PDL::Core::Dev::isbigendian()".

WAS ÜBER UNS DOKUMENTATION?


Eine der Stärken von PDL ist die Online-Dokumentation. Ziel ist es, mit diesem System
geben Informationen darüber, wie/ob eine Routine schlechte Werte unterstützt: in vielen Fällen "pp_def()"
enthält sowieso alle Informationen, sodass der Funktionsschreiber nichts tun muss
alle! Für die Fälle, in denen dies nicht ausreicht, gibt es die Option "BadDoc". Für Code
auf Perl-Ebene geschrieben - dh in einer .pm-Datei - verwenden Sie die Pod-Direktive "=for bad".

Diese Informationen werden über die Dokumentation man/pod2man/html verfügbar sein. Es ist auch
Zugriff über die Shells "perldl" oder "pdl2" - mit dem Befehl "badinfo" - und die
Shell-Befehl "pdldoc" - unter Verwendung der Option "-b".

Diese Unterstützung befindet sich noch in einem sehr frühen Stadium - dh es wurde noch nicht viel darüber nachgedacht: Kommentare
sind willkommen; Verbesserungen am Code bevorzugt ;) Ein unangenehmes Problem ist für *.pm Code:
du musst a schreiben *.pm.PL Datei, die nur die Direktive "=for bad" (+ Text) einfügt, wenn
Unterstützung für schlechte Werte ist einkompiliert. Tatsächlich ist dies ein Schmerz beim Umgang mit schlechten Werten am
Perl, statt PDL::PP, level: vielleicht sollte ich einfach die Option "WITH_BADVAL" streichen...

AKTUELLER PROBLEME


Es gibt eine Reihe von Bereichen, die Arbeit, Benutzereingaben oder beides erfordern! Sie werden erwähnt
an anderer Stelle in diesem Dokument, aber dies dient nur dazu, sicherzustellen, dass sie nicht verloren gehen.

Fang ungültig mathematisch Geschäftstätigkeit
Sollten wir Ausnahmen zu den Funktionen in "PDL::Ops" hinzufügen, um die Ausgabe für Out-of-
Bereichseingabewerte?

pdl> p log10(pdl(10,100,-1))

Ich möchte, dass das obige "[1 2 BAD]" erzeugt, aber dies würde den Betrieb verlangsamen alle
Pudel. Wir könnten nach der Operation nach "NaN"/"Inf"-Werten suchen, aber das bezweifle ich
wäre noch schneller.

Integration mit NaN
Wenn "BADVAL_USENAN" wahr ist, sollten die Routinen in "PDL::Ops" einfach auf die
Abschnitt "Code" - dh "BadCode" nicht verwenden - für die Datentypen "float" und "double".

Global gegen pro piddle Badewanne Werte
Ich denke, man muss nur die Routinen in "Basic/Core/pdlconv.c.PL" ändern, obwohl
es wird bestimmt zu komplikationen kommen. Es würde auch bedeuten, dass die pdl-Struktur benötigt
eine Variable zu haben, um ihren falschen Wert zu speichern, was eine binäre Inkompatibilität mit bedeuten würde
frühere Versionen von PDL mit Unterstützung für schlechte Werte.

Ab dem 17. März 2006 enthält PDL die experimentell Konfigurationsoption "BADVAL_PER_PDL"
die, wenn ausgewählt, schlechte Werte pro Piddle hinzufügt.

Datenfluss of schlechte Flagge
Derzeit werden Änderungen an der schlechten Flagge an die Kinder eines Piddles weitergegeben, aber vielleicht
sie sollten auch an die Eltern weitergegeben werden. Mit dem Aufkommen von Per-Piddle-Bad
Werte, die wir berücksichtigen müssen, wie mit Änderungen des Wertes umzugehen ist, der verwendet wird, um fehlerhafte Elemente darzustellen
Auch.

ALLES ELSE


Der Build-Prozess ist betroffen. Folgende Dateien werden nun während des Builds erstellt:

Basic/Core/pdlcore.h pdlcore.h.PL
pdlcore.c pdlcore.c.PL
pdlapi.c pdlapi.c.PL
Core.xs Core.xs.PL
Kern.pm Kern.pm.PL

Mehrere neue Dateien wurden hinzugefügt:

Basic/Pod/BadValues.pod (dh diese Datei)

t/schlecht.t

Einfach/Schlecht/
Basic/Bad/Makefile.PL
schlecht.pd

etc

TODO/VORSCHLÄGE


· Betrachten Sie die Verwendung von schlechten Werten pro Piddle. Würde eine Änderung der pdl-Struktur bedeuten (dh
binäre Inkompatibilität) und die Routinen in "Basic/Core/pdlconv.c.PL" benötigen
ändern, um damit umzugehen. Die meisten anderen Routinen sollte nicht muss geändert werden...

Weitere Informationen im experimentell Option "BADVAL_PER_PDL".

· was zu tun ist mit "$b = pdl(-2); $a = log10($b)" - $a sollte schlecht gesetzt werden, aber es
derzeit nicht.

· Erlauben Sie den Operationen in PDL::Ops, die Prüfung auf fehlerhafte Werte zu überspringen, wenn NaN als a . verwendet wird
schlechter Wert und Verarbeitung eines Gleitkomma-Piddles. Braucht ein bisschen Arbeit, um
PDL::PP::PDLCode.

· "$pdl->baddata()" aktualisiert nun auch alle Kinder dieses Piddles. Allerdings nicht
sicher, was mit den Eltern zu tun ist, denn:

$b = $a->scheibe();
$b->schlechte Daten(0)

bedeutet nicht, dass der schlechte Wert von $a nicht gelöscht werden sollte. jedoch nach

$b->schlechte Daten(1)

Es ist vernünftig anzunehmen, dass die Eltern jetzt als ungültige Werte enthaltend gekennzeichnet werden.

VIELLEICHT können Sie das Flag "falscher Wert" nur löschen, wenn Sie KEIN Kind eines anderen sind
piddle, wohingegen, wenn Sie das Flag setzen, alle Kinder UND Eltern als gesetzt werden sollten
Gut?

Wenn Sie den schlechten Wert in einem Piddle ändern, sollte dies auf ähnliche Weise übertragen werden
Eltern und Kinder? Oder sollten Sie dies nur auf dem "Top-Level"-Piddle tun können?
Böse...

· etwas Code einrichten, um Benchmarks durchzuführen, um zu sehen, wie stark die Dinge verlangsamt werden (und um zu
überprüfen Sie, ob ich die Dinge nicht vermasselt habe, wenn "WITH_BADVAL" 0/undef ist).

· einige der Namen sind nicht ansprechend - ich denke an "orig_badvalue()" in
Einfach/Schlecht/schlecht.pd bestimmtes. Alle Vorschläge geschätzt.

Verwenden Sie PDL::BadValuesp online mit den onworks.net-Diensten


Kostenlose Server & Workstations

Laden Sie Windows- und Linux-Apps herunter

Linux-Befehle

Ad