Ito ang command na PDL::BadValuesp na maaaring patakbuhin sa OnWorks na libreng hosting provider gamit ang isa sa aming maramihang libreng online na workstation gaya ng Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator
PROGRAMA:
NAME
PDL::BadValues - Pagtalakay sa masamang halaga ng suporta sa PDL
DESCRIPTION
Ano ay masama halaga at bakit dapat I mag-abala sa sila?
Minsan kapaki-pakinabang na matukoy ang isang tiyak na halaga ay 'masama' o 'nawawala'; para sa
halimbawa ang mga CCD na ginagamit sa astronomy ay gumagawa ng mga 2D na larawan na hindi perpekto mula noong ilang lugar
naglalaman ng di-wastong data dahil sa mga imperfections sa detector. Habang ang malakas na index ng PDL
mga gawain at lahat ng kumplikadong negosyo na may daloy ng data, mga hiwa, atbp atbp ay nangangahulugan na ang mga ito
maaaring hindi papansinin ang mga rehiyon sa pagproseso, mahirap gawin. Ito ay magiging lubhang mas madaling maging
kayang sabihin ang "$c = $a + $b" at ipaubaya sa computer ang lahat ng abala.
Kung hindi ka interesado dito, maaari kang (tama) mag-alala kung paano ito
nakakaapekto sa bilis ng PDL, dahil ang overhead ng pagsuri para sa isang masamang halaga sa bawat operasyon
maaaring malaki. Dahil dito, ang code ay naisulat nang mas mabilis hangga't maaari -
lalo na kapag nagpapatakbo sa mga piddle na walang masamang halaga. Sa katunayan, ikaw
dapat mapansin mahalagang walang pagkakaiba sa bilis kapag nagtatrabaho sa piddles na hindi
naglalaman ng masasamang halaga.
Gayunpaman, kung ayaw mo ng masamang halaga, ang opsyon sa pagsasaayos ng "WITH_BADVAL" ng PDL
dumating upang iligtas; kung nakatakda sa 0 o undef, babalewalain ang bad-value na suporta. Tungkol sa
only time I think you'll need to use this - I admit, I'm biased ;) - is if you have
limitado ang disk o memory space, dahil ang laki ng code ay tumaas (tingnan sa ibaba).
Maaari mo ring itanong 'mabuti, sinusuportahan ng aking computer ang IEEE NaN, kaya mayroon na ako nito'. Oo
at hindi - maraming mga gawain, tulad ng "y=sin(x)", ang magpapalaganap ng NaN nang walang gumagamit
upang mag-code nang naiiba, ngunit ang mga gawain tulad ng "qsort", o paghahanap ng median ng isang array, kailangan
na muling i-code upang mahawakan ang masasamang halaga. Para sa mga floating-point datatype, ang "NaN" at "Inf" ay
ginamit upang i-flag ang mga masasamang halaga IF ang opsyon na "BADVAL_USENAN" ay nakatakda sa 1 sa iyong config file.
Kung hindi, ginagamit ang mga espesyal na halaga (Default na masamang halaga). Wala akong anumang mga benchmark
tingnan kung aling opsyon ang mas mabilis.
Mayroong isang pang-eksperimentong tampok na "BADVAL_PER_PDL" na, kung nakatakda, ay nagbibigay-daan sa iyo na magkaroon
iba't ibang masamang halaga para sa magkahiwalay na mga piddle ng parehong uri. Ito ay kasalukuyang hindi gumagana
gamit ang opsyong "BADVAL_USENAN"; kung pareho ang nakatakda, babalewalain ng PDL ang "BADVAL_USENAN"
halaga.
kodigo dagdagan dalawa sa masama halaga
Luma na ang sumusunod na paghahambing!
Sa isang i386 machine na nagpapatakbo ng Linux at Perl 5.005_03, sinukat ko ang mga sumusunod na laki (ang
Ang Slatec code ay pinagsama-sama, ngunit wala sa iba pang mga opsyon: hal, FFTW, GSL, at TriD
ay):
WITH_BADVAL = 0
Sukat ng blib na direktoryo pagkatapos ng matagumpay na paggawa = 4963 kb: blib/arch = 2485 kb at
blib/lib = 1587 kb.
WITH_BADVAL = 1
Sukat ng blib na direktoryo pagkatapos ng matagumpay na paggawa = 5723 kb: blib/arch = 3178 kb at
blib/lib = 1613 kb.
Kaya, ang kabuuang pagtaas ay lamang 15% - hindi gaanong babayaran para sa lahat ng mga kababalaghan na hindi magandang halaga
nagbibigay ;)
Ang source code na ginamit para sa pagsubok na ito ay mayroong karamihan sa mga pangunahing gawain (hal
Ang Basic/) ay na-convert upang gumamit ng masasamang halaga, habang kakaunti sa mga 'panlabas' na gawain (hal
lahat ng iba pa sa pamamahagi ng PDL) ay nabago.
A mabilis pangkalahatang-ideya
pdl> p $PDL::Bad::Status
1
pdl> $a = sequence(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 MASAMA 3]
[ 4 MASAMA 6 7]
[BAD 9 10 BAD]
]
pdl> $a *= 3
pdl> p $a
[
[ 0 3 MASAMA 9]
[ 12 MASAMA 18 21]
[BAD 27 30 BAD]
]
pdl> p $a->sum
120
Ang "demo bad" at "demo bad2" sa loob ng perldl o pdl2 ay nagbibigay ng demonstrasyon ng ilan sa
mga bagay na posible na may masamang halaga. Available din ang mga ito sa web-site ng PDL, sa
http://pdl.perl.org/demos/. Tingnan ang PDL::Masama para sa mga kapaki-pakinabang na gawain para sa pagtatrabaho sa mga masamang halaga
at t/masamang.t upang makita ang mga ito sa pagkilos.
Ang layunin ay:
· hindi makabuluhang nakakaapekto sa PDL para sa mga user na hindi nangangailangan ng masamang halaga ng suporta
· maging mas mabilis hangga't maaari kapag naka-install ang masamang halaga ng suporta
Kung hindi mo gusto ang masamang halaga ng suporta, itakda mo ang "WITH_BADVAL" sa 0 in perldl.conf; PDL
pagkatapos ay walang masamang halaga ng suporta na pinagsama-sama, kaya magiging kasing bilis ng dati.
Gayunpaman, sa karamihan ng mga kaso, ang masamang halaga ng suporta ay may kaunting epekto sa bilis, kaya ikaw
dapat itakda ang "WITH_CONFIG" sa 1! Ang isang pagbubukod ay kung kulang ka sa memorya, dahil ang halaga
ng code na ginawa ay mas malaki (ngunit halos 15% lamang - tingnan ang "Pagtaas ng code dahil sa masama
mga halaga").
Upang malaman kung ang PDL ay pinagsama-sama na may masamang halaga ng suporta, tingnan ang mga halaga ng alinman
$PDL::Config{WITH_BADVAL} o $PDL::Bad::Status - kung totoo ito ay naging.
Upang malaman kung ang isang routine ay sumusuporta sa masamang halaga, gamitin ang "badinfo" na utos sa perldl o pdl2
o ang "-b" na opsyon sa pdldoc. Ang pasilidad na ito ay kasalukuyang isang 'patunay ng konsepto' (o, higit pa
realistically, isang mabilis na hack) kaya asahan na ito ay magaspang sa paligid ng mga gilid.
Ang bawat piddle ay naglalaman ng flag - naa-access sa pamamagitan ng "$pdl->badflag" - para sabihin kung mayroon
masamang data na naroroon:
· Kung mali/0, na nangangahulugang walang masamang data dito, ang code na ibinigay ng "Code"
ang opsyon sa "pp_def()" ay naisakatuparan. Nangangahulugan ito na ang bilis ay dapat na napakalapit sa
na nakuha gamit ang "WITH_BADVAL=0", dahil ang tanging overhead ay ilang access sa a
bit sa piddles state variable.
· Kung totoo/1, tapos sabi nito doon MAYO maging masamang data sa piddle, kaya gamitin ang code sa
"BadCode" na opsyon (ipagpalagay na ang "pp_def()" para sa routine na ito ay na-update sa
magkaroon ng isang BadCode key). Makukuha mo ang lahat ng mga pakinabang ng threading, tulad ng sa "Code"
opsyon, ngunit ito ay tatakbo nang mas mabagal dahil kakailanganin mong pangasiwaan ang presensya ng
masamang halaga.
Kung gagawa ka ng piddle, magkakaroon ito ng bad-value na flag na nakatakda sa 0. Para baguhin ito, gamitin
"$pdl->badflag($new_bad_status)", kung saan ang $new_bad_status ay maaaring maging 0 o 1. Kapag ang isang routine
lumilikha ng piddle, ang bad-value na flag nito ay magdedepende sa mga input piddle: maliban kung over-ridden
(tingnan ang "CopyBadStatusCode" na opsyon sa "pp_def"), ang bad-value na flag ay itatakdang totoo kung
alinman sa mga input piddle ay naglalaman ng masamang halaga. Upang suriin na ang isang piddle ay talagang naglalaman ng masama
data, gamitin ang "check_badflag" na paraan.
NOTA: pagpapalaganap ng badflag
Kung babaguhin mo ang badflag ng isang piddle, ipapalaganap ang pagbabagong ito sa lahat ng mga bata ng
piddle, kaya
pdl> $a = zeroes(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->badflag(1);
pdl> print ">>c: ", $c->badflag, "\n";
>>c: 1
Hindi pagbabago ay ginawa sa mga magulang ng isang piddle, kaya
pdl> print ">>a: ", $a->badflag, "\n";
>>a: 1
pdl> $c->badflag(0);
pdl> print ">>a: ", $a->badflag, "\n";
>>a: 1
Mga Saloobin:
· ang badflag ay maaari LAMANG tanggalin KUNG ang isang piddle ay WALANG mga magulang, at ang pagbabagong ito ay gagawin
palaganapin sa lahat ng anak ng piddle na iyon. Hindi na ako masyadong mahilig sa ganito (too
awkward sa code, para sa isa).
· "$a->badflag(1)" ay dapat magpalaganap ng badflag sa PAREHO sa mga magulang at mga anak.
Hindi ito dapat mahirap ipatupad (bagaman nabigo ang isang paunang pagtatangka!). Ginagawa ba nito
pakiramdam bagaman? Mayroon ding isyu kung ano ang mangyayari kung babaguhin mo ang masamang halaga ng a
piddle - dapat bang ipalaganap ang mga ito sa mga anak/magulang (oo) o kung dapat ka lang
magagawang baguhin ang masamang halaga sa 'itaas' na antas - ie iyong mga piddle na wala
mga magulang.
Ang "orig_badvalue()" na paraan ay nagbabalik ng compile-time na halaga para sa isang ibinigay na uri ng data. Gumagana siya
sa piddles, PDL::Type objects, at numero - hal
$pdl->orig_badvalue(), byte->orig_badvalue(), at orig_badvalueNa (4).
Mayroon din itong kakila-kilabot na pangalan ...
Upang makuha ang kasalukuyang masamang halaga, gamitin ang "badvalue()" na paraan - mayroon itong parehong syntax bilang
"orig_badvalue()".
Upang baguhin ang kasalukuyang masamang halaga, ibigay ang bagong numero sa masamang halaga - hal
$pdl->badvalue(2.3), byte->masamang halaga(2), masamang halaga(5,-3e34).
nota: ang halaga ay tahimik na na-convert sa tamang uri ng C, at ibinalik - ibig sabihin
Ang "byte->badvalue(-26)" ay nagbabalik ng 230 sa aking Linux machine. Isa rin itong "nop" para sa lumulutang-
mga uri ng punto kapag ang "BADVAL_USENAN" ay totoo.
Tandaan na ang mga pagbabago sa masamang halaga ay HINDI pinalaganap sa dati nang ginawang piddles - sila
magkakaroon pa rin ng masamang halaga, ngunit biglang magiging masama ang mga elemento
'mabuti', ngunit naglalaman ng lumang masamang halaga. Tingnan ang talakayan sa ibaba. Ito ay hindi isang problema para sa
mga uri ng floating-point na gumagamit ng NaN, dahil hindi mo mababago ang kanilang badvalue.
Masama halaga at boolean operator
Para sa mga boolean operator na iyon sa PDL::Ops, ang pagsusuri sa isang masamang halaga ay nagbabalik ng masamang halaga.
Habang ito ay nangangahulugan na
$mask = $img > $thresh;
wastong nagpapalaganap ng masamang halaga, ito habilin maging sanhi ng mga problema para sa mga tseke tulad ng
do_something() kung mayroon( $img > $thresh );
na kailangang muling isulat bilang isang bagay tulad ng
do_something() kung mayroon( setbadtoval( ($img > $thresh), 0 ) );
Kapag gumagamit ng isa sa mga function na 'projection' sa PDL::Ufunc - tulad ng orover - masamang halaga
ay nilaktawan (tingnan ang dokumentasyon ng mga function na ito para sa kasalukuyang (mahinang) paghawak
ng kaso kapag ang lahat ng mga elemento ay masama).
A masama halaga para bawat magliwaliw, at na may kaugnayan isyu
An pagsubok Ang opsyon na "BADVAL_PER_PDL" ay naidagdag sa perldl.conf upang payagan ang per-piddle
masamang halaga. Ang dokumentasyon ay hindi na-update para sa pagsasaalang-alang sa pagbabagong ito.
Ang sumusunod ay may kaugnayan lamang para sa mga uri ng integer, at para sa mga uri ng floating-point kung
Hindi naitakda ang "BADVAL_USENAN" noong ginawa ang PDL.
Sa kasalukuyan, mayroong isang masamang halaga para sa bawat uri ng data. Ang code ay isinulat upang magawa namin
magkaroon ng isang hiwalay na masamang halaga para sa bawat piddle (naka-imbak sa istraktura ng pdl) - ito ay pagkatapos
alisin ang kasalukuyang problema ng:
pdl> $a = byte( 1, 2, byte->badvalue, 4, 5 );
pdl> p $a;
[1 2 255 4 5]
pdl> $a->badflag(1)
pdl> p $a;
[1 2 MASAMA 4 5]
pdl> byte->masamang halaga(0);
pdl> p $a;
[1 2 255 4 5]
ibig sabihin, nawala ang masamang halaga sa $a masama katayuan gamit ang kasalukuyang pagpapatupad. Ito ay
halos tiyak na nagdudulot ng mga problema sa ibang lugar bagaman!
Pagpapatupad MGA DETALYE
Sa panahon ng "perl Makefile.PL", ang file Basic/Core/badsupport.p ay nilikha; ang file na ito
naglalaman ng mga halaga ng mga variable na "WITH_BADVAL", "BADVAL_USENAN" at "BADVAL_PER_PDL",
at dapat gamitin ng code na naisakatuparan bago ang PDL::Config Ang file ay nilikha (hal
Basic/Core/pdlcore.c.PL. Gayunpaman, ang karamihan sa PDL code ay kakailanganin lamang na i-access ang %PDL::Config
array (hal Basic/Bad/bad.pd) para malaman kung kailangan ng bad-value na suporta.
Isang bagong flag ang naidagdag sa estado ng isang piddle - "PDL_BADVAL". Kung hindi nakatakda, ang
Ang piddle ay hindi naglalaman ng masasamang halaga, at sa gayon ang lahat ng code ng suporta ay maaaring balewalain. Kung itinakda, ito
hindi ginagarantiyahan na ang mga masasamang halaga ay naroroon, na dapat lamang na suriin ang mga ito.
Salamat kay Christian, "badflag()" - na nagtatakda/nag-clear sa watawat na ito (tingnan Basic/Bad/bad.pd) -
ay i-update LAHAT ang mga anak/apo/atbp ng piddle kung magbago ang estado nito (tingnan ang
"badflag" sa Basic/Bad/bad.pd at "propagate_badflag" sa Basic/Core/Core.xs.PL). Hindi
malinaw kung ano ang gagawin sa mga magulang: Nakikita ko ang dahilan ng pagpapalaganap ng 'set badflag'
kahilingan sa mga magulang, ngunit sa palagay ko HINDI dapat ma-clear ng isang bata ang badflag ng a
magulang. Mayroon ding isyu kung ano ang mangyayari kapag binago mo ang masamang halaga para sa a
piddle.
Ang istraktura ng "pdl_trans" ay pinalawak upang isama ang isang integer na halaga, "bvalflag", na
nagsisilbing switch upang sabihin sa code kung hahawakan ang masasamang halaga o hindi. Nakatakda ang value na ito
kung alinman sa mga input piddle ang nakatakda ang kanilang flag na "PDL_BADVAL" (bagama't ang code na ito ay maaaring
pinalitan ng pagtatakda ng "FindBadStateCode" sa pp_def). Ang lohika ng tseke ay makukuha
medyo mas kumplikado kung papayagan ko ang mga gawain na bumalik sa paggamit ng seksyong "Code" para sa
mga uri ng floating-point (ibig sabihin, ang mga nakagawiang iyon na may "NoBadifNaN => 1" kapag ang "BADVAL_USENAN" ay
totoo).
Ang mga masamang halaga para sa mga uri ng integer ay naka-imbak na ngayon sa isang istraktura sa loob ng Core PDL
istraktura - "PDL.bvals" (hal Basic/Core/pdlcore.h.PL); tingnan din ang "typedef badvals" sa
Basic/Core/pdl.h.PL at ang BOOT code ng Basic/Core/Core.xs.PL kung saan ang mga halaga ay
nasimulan sa (sana) mga makabuluhang halaga. Tingnan mo PDL/Bad/bad.pd para sa read/write routines to
ang mga halaga.
Ang pagdaragdag ng opsyong "BADVAL_PER_PDL" ay nagresulta sa mga karagdagang pagbabago sa
panloob ng piddles. Ang mga pagbabagong ito ay hindi pa nakadokumento.
Bakit hindi gumawa a PDL subclass?
Ang suporta para sa masasamang halaga ay maaaring ginawa bilang isang sub-class ng PDL. Ang bentahe nito
Ang diskarte ay na naglo-load ka lamang sa code upang mahawakan ang mga masamang halaga kung gusto mo
upang gamitin ang mga ito. Ang downside ay na ang code pagkatapos ay makakakuha ng paghihiwalay: anumang bug
ang mga pag-aayos/pagpapabuti ay kailangang gawin sa code sa dalawang magkaibang mga file. Sa kasalukuyan
diskarte ang code ay nasa parehong function na "pp_def" (bagaman mayroon pa ring problema
na parehong "Code" at "BadCode" na mga seksyon ay kailangang i-update).
default masama halaga
Ang default/orihinal na masamang halaga ay nakatakda sa (kinuha mula sa pamamahagi ng Starlink):
#isama
PDL_Byte == UCHAR_MAX
PDL_Short == SHRT_MIN
PDL_Ushort == USHRT_MAX
PDL_Long == INT_MIN
Kung "BADVAL_USENAN == 0", mayroon din tayo
PDL_Float == -FLT_MAX
PDL_Double == -DBL_MAX
kung hindi, ang lahat ng "NaN", "+Inf", at "-Inf" ay itinuturing na masama para sa mga uri ng floating-point.
Sa kasong ito, hindi mababago ang masamang halaga, hindi katulad ng mga uri ng integer.
Gaano do I baguhin a karaniwan sa pangasiwaan masama mga halaga?
Ang mga halimbawa ay matatagpuan sa karamihan ng *.pd mga file sa Basic/ (at sana marami pang lugar
malapit na!). Ang ilan sa lohika ay maaaring mukhang medyo hindi malinaw - iyon ay marahil dahil ito ay!
Pinahahalagahan ang mga komento.
Ang lahat ng mga gawain ay dapat na awtomatikong magpalaganap ng masamang status na flag sa mga output piddle, maliban kung
idineklara mo kung hindi.
Kung ang isang routine ay tahasang tumatalakay sa masasamang halaga, dapat mong ibigay ang opsyong ito sa pp_def:
HandleBad => 1
Tinitiyak nito na ang mga tamang variable ay sinisimulan para sa mga macro na $ISBAD atbp. Ito ay
ginagamit din ng mga nakagawiang awtomatikong paggawa ng dokumento upang magbigay ng default na impormasyon sa
ang masamang halaga ng suporta ng isang gawain nang hindi kinakailangang i-type ito ng user mismo (ito ay
sa mga unang yugto nito).
Upang i-flag ang isang nakagawiang bilang HINDI humahawak ng masasamang halaga, gamitin
HandleBad => 0
ito dapat maging sanhi ng nakagawiang mag-print ng isang babala kung ito ay nagpadala ng anumang mga piddles na may masama
set ng bandila. Ang "inover" ng Primitive ay may ganitong set - dahil magiging awkward itong mag-convert -
ngunit hindi ko pa ito sinubukan upang makita kung ito ay gumagana.
Kung gusto mong pangasiwaan ang mga masamang halaga ngunit hindi itakda ang estado ng lahat ng mga piddle ng output, o kung
ito ay isa lamang input piddle na mahalaga, pagkatapos ay tingnan ang PP rules
"NewXSFindBadStatus" at "NewXSCopyBadStatus" at ang kaukulang "pp_def" na mga opsyon:
FindBadStatusCode
Bilang default, ang "FindBadStatusCode" ay gumagawa ng code na nagtatakda ng "$PRIV(bvalflag)" depende sa
ang estado ng masamang flag ng input piddles: tingnan ang "findbadstatus" sa
Basic/Gen/PP.pm. Ang code na tinukoy ng user ay dapat ding mag-imbak ng halaga ng "bvalflag" sa
"$BADFLAGCACHE()" variable.
CopyBadStatusCode
Ang default na code dito ay medyo mas simple kaysa sa "FindBadStatusCode": ang masamang bandila ng
ang mga output piddle ay nakatakda kung ang "$BADFLAGCACHE()" ay totoo pagkatapos ng code
sinusuri. Minsan ang "CopyBadStatusCode" ay nakatakda sa isang walang laman na string, na may
responsibilidad na itakda ang badflag ng output piddle na naiwan sa "BadCode"
seksyon (hal. ang "xxxover" na mga gawain sa Basic/Primitive/primitive.pd).
Bago ang PDL 2.4.3 ginamit namin ang "$PRIV(bvalflag)" sa halip na "$BADFLAGCACHE()". Ito ay
mapanganib dahil ang istraktura ng "$PRIV()" ay hindi garantisadong wasto sa puntong ito
ang code
Kung mayroon kang routine na gusto mong magamit bilang nasa lugar, tingnan ang mga routine
masama.pd (O ops.pd) na gumagamit ng opsyong "in-place" para makita kung paano ipinapalaganap ang masamang bandila
sa mga bata gamit ang mga opsyon na "xxxBadStatusCode". Nagpasya akong huwag i-automate ito bilang mga panuntunan
magiging medyo kumplikado, dahil hindi lahat ng in-place na op ay kailangang ipalaganap ang badflag
(hal unary functions).
Kung ang opsyon
HandleBad => 1
ay ibinigay, pagkatapos ay maraming bagay ang mangyayari. Para sa mga uri ng integer, awtomatiko ang readdata code
lumilikha ng variable na tinatawag na " _badval", na naglalaman ng masamang halaga para doon
piddle (tingnan ang "get_xsdatapdecl()" sa Basic/Gen/PP/PdlParObjs.pm). Gayunpaman, huwag hard code
ang pangalan na ito sa iyong code! Sa halip ay gumamit ng mga macro (salamat kay Tuomas para sa mungkahi):
Ang '$ISBAD(a(n=>1))' ay lumalawak sa '$a(n=>1) == a_badval'
'$ISGOOD(a())' '$a() != a_badval'
'$SETBAD(bob())' '$bob() = bob_badval'
well, ang "$a(...)" ay pinalawak din. Gayundin, maaari kang gumamit ng "$" bago ang pangalan ng pdl, kung
gusto mo, ngunit nagsisimula itong magmukhang ingay ng linya - hal. "$ISGOOD($a())".
Kung nag-cache ka ng piddle value sa isang variable -- hal. "index" in hiwa.pd -- ang mga sumusunod
Ang mga gawain ay kapaki-pakinabang:
'$ISBADVAR(c_var,pdl)' 'c_var == pdl_badval'
'$ISGOODVAR(c_var,pdl)' 'c_var != pdl_badval'
'$SETBADVAR(c_var,pdl)' 'c_var = pdl_badval'
Ang mga sumusunod ay ipinakilala, Maaaring kailanganin nilang makipaglaro upang mapabuti ang kanilang
Gamitin.
'$PPISBAD(CHILD,[i]) 'CHILD_physdatap[i] == CHILD_badval'
'$PPISGOOD(CHILD,[i]) 'CHILD_physdatap[i] != CHILD_badval'
'$PPSETBAD(CHILD,[i]) 'CHILD_physdatap[i] = CHILD_badval'
Kung nakatakda ang "BADVAL_USENAN", medyo iba ito para sa "float" at "double", kung saan kami
isaalang-alang ang "NaN", "+Inf", at "-Inf" na lahat ay masama. Sa kasong ito:
Ang ISBAD ay nagiging may hangganan(piddle) == 0
ISGOOD na may hangganan(piddle) != 0
SETBAD piddle = NaN
kung saan ang halaga para sa NaN ay tinalakay sa ibaba sa Paghawak ng mga halaga ng NaN.
Nangangahulugan ito na maaari kang magbago
Code => '$a() = $b() + $c();'
sa
BadCode => 'kung ($ISBAD(b()) || $ISBAD(c()) ) {
$SETBAD(a());
} Iba pa {
$a() = $b() + $c();
}'
iniiwan ang Code kung ano ito. PP::PDLCode ay lilikha ng isang loop na katulad nito
kung ( __trans->bvalflag ) {
threadloop sa BadCode
} Iba pa {
threadloop sa Code
}
(marahil mas madaling tingnan ang .xs file upang makita kung ano ang nangyayari).
Nagpapatuloy Lampas ang kodigo seksyon
Katulad ng "BadCode", mayroong "BadBackCode", at "BadRedoDimsCode".
Ang paghawak sa "EquivCPOffsCode" ay medyo naiiba: sa ilalim ng pagpapalagay na ang tanging access
sa data ay sa pamamagitan ng "$EQUIVCPOFFS(i,j)" na macro, pagkatapos ay awtomatiko nating magagawa ang 'masamang'
bersyon nito; tingnan ang "[EquivCPOffsCode]" at "[Code]" na mga panuntunan sa PDL::PP.
Macro daan sa ang masama bandila of a piddle
Ang mga macro ay ibinigay upang magbigay ng access sa bad-flag status ng isang pdl:
'$PDLSTATEISBAD(a)' -> '($PDL(a)->estado at PDL_BADVAL) > 0'
'$PDLSTATEISGOOD(a)' '($PDL(a)->estado at PDL_BADVAL) == 0'
'$PDLSTATESETBAD(a)' '$PDL(a)->state |= PDL_BADVAL'
'$PDLSTATESETGOOD(a)' '$PDL(a)->estado &= ~PDL_BADVAL'
Para sa paggamit sa "xxxxBadStatusCode" (+ iba pang bagay na napupunta sa INIT: seksyon) mayroong:
'$SETPDLSTATEBAD(a)' -> 'a->estado |= PDL_BADVAL'
'$SETPDLSTATEGOOD(a)' -> 'a->estado &= ~PDL_BADVAL'
'$ISPDLSTATEBAD(a)' -> '((a->estado at PDL_BADVAL) > 0)'
'$ISPDLSTATEGOOD(a)' -> '((a->estado at PDL_BADVAL) == 0)'
Sa PDL 2.4.3 ang "$BADFLAGCACHE()" macro ay ipinakilala para magamit sa "FindBadStatusCode" at
"CopyBadStatusCode".
Pag-asikaso NaN halaga
Mayroong dalawang isyu:
NaN bilang masamang halaga
na tapos na. Upang pumili, itakda ang "BADVAL_USENAN" sa 1 sa perldl.conf; bumaba ang halaga ng 0
bumalik sa pagtrato sa mga uri ng floating-point na kapareho ng mga integer. May kailangan akong gawin
mga benchmark upang makita kung alin ang mas mabilis, at kung ito ay nakasalalay sa mga makina (Linux ay tila
upang pabagalin nang higit pa kaysa sa aking Sparc machine sa ilang napakasimpleng pagsubok na ginawa ko).
Hindi pinapansin ang mga seksyon ng BadCode
na hindi.
para simple mga gawain sa pagpoproseso ng mga lumulutang-point na numero, dapat nating hayaan ang proseso ng computer
ang mga masamang halaga (ibig sabihin, "NaN" at "Inf" na mga halaga) sa halip na gamitin ang code sa "BadCode"
seksyon. Maraming ganoong mga gawain ang na-label gamit ang "NoBadifNaN => 1"; gayunpaman ito ay
sa kasalukuyan ignorado ng PDL::PP.
Para sa mga gawaing ito, gusto naming gamitin ang seksyong "Code" kung
ang piddle ay walang masamang flag set
ang datatype ay float o double
kung hindi, ginagamit namin ang seksyong "BadCode." Ito ay HINDI IPINATUPAD, gaya ng kakailanganin nito
makatwirang pag-hack ng PP::PDLCode!
Nariyan din ang problema kung paano namin pinangangasiwaan ang 'mga pagbubukod' - dahil "$a = pdl(2) / pdl(0) "
gumagawa ng masamang halaga ngunit hindi ina-update ang badflag na halaga ng piddle. Mahuli ba natin ang isang
exception, o kailangan ba natin itong bitag (hal. paghahanap para sa "exception" sa
Basic/Ops/ops.pd)?
Ang pagsuri para sa "Nan", at "Inf" ay ginagawa sa pamamagitan ng paggamit ng "finite()" system call. Kung gusto mo
magtakda ng halaga sa halaga ng "NaN", maaaring gamitin ang sumusunod na bit ng code (matatagpuan ito
sa pareho Basic/Core/Core.xs.PL at Basic/Bad/bad.pd):
/* para sa mga big-endian machine */
static na unyon { unsigned char __c[4]; lumutang __d; }
__pdl_nan = { { 0x7f, 0xc0, 0, 0 } };
/* para sa mga little-endian machine */
static na unyon { unsigned char __c[4]; lumutang __d; }
__pdl_nan = { { 0, 0, 0xc0, 0x7f } };
Ang diskarte na ito ay malamang na mapalitan ng mga gawain sa library tulad ng "nan("")" o
"atof("NaN")".
Para malaman kung malaking endian ang isang partikular na makina, gamitin ang routine
"PDL::Core::Dev::isbigendian()".
ANO TUNGKOL DOKUMENTASYON?
Isa sa mga lakas ng PDL ay ang on-line na dokumentasyon nito. Ang layunin ay gamitin ang sistemang ito upang
magbigay ng impormasyon kung paano/kung ang isang routine ay sumusuporta sa masasamang halaga: sa maraming kaso "pp_def()"
naglalaman pa rin ng lahat ng impormasyon, kaya hindi kailangang gumawa ng anuman ang function-writer
lahat! Para sa mga kaso kung kailan hindi ito sapat, mayroong opsyon na "BadDoc." Para sa code
nakasulat sa antas ng Perl - ibig sabihin sa isang .pm file - gamitin ang "=for bad" pod na direktiba.
Ang impormasyong ito ay makukuha sa pamamagitan ng man/pod2man/html na dokumentasyon. Ito rin
naa-access mula sa mga shell na "perldl" o "pdl2" - gamit ang command na "badinfo" - at ang
"pdldoc" shell command - gamit ang "-b" na opsyon.
Ang suportang ito ay nasa napakaagang yugto - ibig sabihin, hindi gaanong naisip ito: mga komento
ay malugod na tinatanggap; mga pagpapabuti sa code na ginustong ;) Isang mahirap na problema ay para sa *.pm code:
kailangan mong sumulat ng a *.pm.PL file na naglalagay lamang ng "=for bad" na direktiba (+ text) kung
Ang suporta sa masamang halaga ay pinagsama-sama. Sa katunayan, ito ay isang sakit kapag pinangangasiwaan ang mga masasamang halaga sa
Perl, sa halip na PDL::PP, level: marahil ay dapat ko na lang i-scrap ang opsyong "WITH_BADVAL"...
CURRENT MGA ISYU
Mayroong ilang mga lugar na nangangailangan ng trabaho, input ng user, o pareho! Sila ay nabanggit
sa ibang lugar sa dokumentong ito, ngunit ito ay para lamang matiyak na hindi sila maliligaw.
Tigil hindi wasto matematiko pagpapatakbo
Dapat ba tayong magdagdag ng mga pagbubukod sa mga function sa "PDL::Ops" upang itakda ang output na masama para sa out-of-
mga halaga ng input ng saklaw?
pdl> p log10(pdl(10,100,-1))
Gusto kong ang nasa itaas ay makagawa ng "[1 2 BAD]", ngunit ito ay magpapabagal sa mga operasyon sa lahat
piddles. Maaari naming suriin ang mga halaga ng "NaN"/"Inf" pagkatapos ng operasyon, ngunit duda ako na
magiging mas mabilis.
pagsasama-sama sa NaN
Kapag ang "BADVAL_USENAN" ay totoo, ang mga nakagawiang sa "PDL::Ops" ay dapat mapunta sa
Seksyon na "Code" - ibig sabihin, huwag gumamit ng "BadCode" - para sa "float" at "double" na mga uri ng data.
Global laban sa per-piddle masama halaga
Sa tingin ko ang kailangan lang ay baguhin ang mga gawain sa "Basic/Core/pdlconv.c.PL", bagaman
tiyak na magkakaroon ng mga komplikasyon. Nangangahulugan din ito na kakailanganin ng istruktura ng pdl
na magkaroon ng variable na mag-imbak ng masamang halaga nito, na nangangahulugang hindi pagkakatugma ng binary
mga nakaraang bersyon ng PDL na may suporta sa hindi magandang halaga.
Noong 17 Marso 2006, ang PDL ay naglalaman ng pagsubok "BADVAL_PER_PDL" na opsyon sa pagsasaayos
na, kung pipiliin, ay nagdaragdag ng per-piddle masamang halaga.
Daloy ng data of ang badflag
Sa kasalukuyan, ang mga pagbabago sa masamang bandila ay ipinapalaganap sa mga anak ng isang piddle, ngunit marahil
dapat din silang ipasa sa mga magulang. Sa pagdating ng per-piddle masama
mga value na kailangan nating isaalang-alang kung paano pangasiwaan ang mga pagbabago sa value na ginamit upang kumatawan sa mga masasamang item
masyadong.
Lahat ELSE
Naapektuhan ang proseso ng pagbuo. Ang mga sumusunod na file ay nilikha na ngayon sa panahon ng pagbuo:
Basic/Core/pdlcore.h pdlcore.h.PL
pdlcore.c pdlcore.c.PL
pdlapi.c pdlapi.c.PL
Core.xs Core.xs.PL
Core.pm Core.pm.PL
Ilang bagong file ang naidagdag:
Basic/Pod/BadValues.pod (ibig sabihin, ang file na ito)
t/masamang.t
Basic/Masama/
Basic/Bad/Makefile.PL
masama.pd
at iba pa
TODO/MUNGKAHI
· Tingnan ang paggamit ng per-piddle masamang halaga. Nangangahulugan ng pagbabago sa istruktura ng pdl (ibig sabihin
binary incompatibility) at ang mga gawain sa "Basic/Core/pdlconv.c.PL" ay kakailanganin
pagbabago upang mahawakan ito. Karamihan sa iba pang mga gawain dapat hindi kailangan baguhin...
Tingnan ang pagsubok "BADVAL_PER_PDL" na opsyon.
· ano ang gagawin tungkol sa "$b = pdl(-2); $a = log10($b)" - $a ay dapat itakdang masama, ngunit ito
sa kasalukuyan ay hindi.
· Payagan ang mga operasyon sa PDL::Ops na laktawan ang pagsusuri para sa mga masamang halaga kapag ginagamit ang NaN bilang isang
masamang halaga at pagproseso ng floating-point piddle. Nangangailangan ng kaunting trabaho
PDL::PP::PDLCode.
· Ina-update na ngayon ng "$pdl->baddata()" ang lahat ng mga anak ng piddle na ito. Gayunpaman, hindi
sigurado kung ano ang gagawin sa mga magulang, dahil:
$b = $a->slice();
$b->baddata(0)
ay hindi nangangahulugan na hindi dapat ma-clear ang badvalue ng $a. gayunpaman, pagkatapos
$b->baddata(1)
makatuwirang ipagpalagay na ang mga magulang ngayon ay na-flag bilang naglalaman ng masasamang halaga.
MARAHIL maaari mo lamang i-clear ang bad value flag kung HINDI ka anak ng iba
piddle, samantalang kung itatakda mo ang bandila kung gayon ang lahat ng mga bata AT magulang ay dapat itakda bilang
well?
Katulad nito, kung babaguhin mo ang masamang halaga sa isang piddle, dapat ba itong ipalaganap
magulang at anak? O dapat mo lang itong gawin sa 'top-level' piddle?
Pangit...
· kumuha ng ilang code na naka-set up upang gumawa ng mga benchmark upang makita kung gaano karaming bagay ang pinabagal (at sa
tingnan kung hindi ko ginulo ang mga bagay kung ang "WITH_BADVAL" ay 0/undef).
· ang ilan sa mga pangalan ay hindi nakakaakit - iniisip ko ang "orig_badvalue()" sa
Basic/Bad/bad.pd sa partikular. Ang anumang mga mungkahi ay pinahahalagahan.
Gamitin ang PDL::BadValuesp online gamit ang mga serbisyo ng onworks.net