1BADVALUES(1) User Contributed Perl Documentation BADVALUES(1)
2
3
4
6 PDL::BadValues - Discussion of bad value support in PDL
7
9 What are bad values and why should I bother with them?
10
11 Sometimes it's useful to be able to specify a certain value is 'bad' or
12 'missing'; for example CCDs used in astronomy produce 2D images which
13 are not perfect since certain areas contain invalid data due to imper‐
14 fections in the detector. Whilst PDL's powerful index routines and all
15 the complicated business with dataflow, slices, etc etc mean that these
16 regions can be ignored in processing, it's awkward to do. It would be
17 much easier to be able to say "$c = $a + $b" and leave all the hassle
18 to the computer.
19
20 If you're not interested in this, then you may (rightly) be concerned
21 with how this affects the speed of PDL, since the overhead of checking
22 for a bad value at each operation can be large. Because of this, the
23 code has been written to be as fast as possible - particularly when
24 operating on piddles which do not contain bad values. In fact, you
25 should notice essentially no speed difference when working with piddles
26 which do not contain bad values.
27
28 However, if you do not want bad values, then PDL's "WITH_BADVAL" con‐
29 figuration option comes to the rescue; if set to 0 or undef, the bad-
30 value support is ignored. About the only time I think you'll need to
31 use this - I admit, I'm biased ;) - is if you have limited disk or mem‐
32 ory space, since the size of the code is increased (see below).
33
34 You may also ask 'well, my computer supports IEEE NaN, so I already
35 have this'. Well, yes and no - many routines, such as "y=sin(x)", will
36 propogate NaN's without the user having to code differently, but rou‐
37 tines such as "qsort", or finding the median of an array, need to be
38 re-coded to handle bad values. For floating-point datatypes, "NaN" and
39 "Inf" are used to flag bad values IF the option "BADVAL_USENAN" is set
40 to 1 in your config file. Otherwise special values are used (Default
41 bad values). I do not have any benchmarks to see which option is
42 faster.
43
44 There is an experimental feadture "BADVAL_PER_PDL" which, if set,
45 allows you to have different bad values for separate piddles of the
46 same type. This currently does not work with the "BADVAL_USENAN"
47 option; if both are set then PDL will ignore the "BADVAL_USENAN" value.
48
49 Code increase due to bad values
50
51 The following comparison is out of date!
52
53 On an i386 machine running linux and perl 5.005_03, I measured the fol‐
54 lowing sizes (the Slatec code was compiled in, but none of the other
55 options: eg Karma, FFTW, GSL, and 3d were):
56
57 WITH_BADVAL = 0
58 Size of blib directory after a successful make = 4963 kb: blib/arch
59 = 2485 kb and blib/lib = 1587 kb.
60
61 WITH_BADVAL = 1
62 Size of blib directory after a successful make = 5723 kb: blib/arch
63 = 3178 kb and blib/lib = 1613 kb.
64
65 So, the overall increase is only 15% - not much to pay for all the won‐
66 ders that bad values provides ;)
67
68 The source code used for this test had the vast majority of the core
69 routines (eg those in Basic/) converted to use bad values, whilst very
70 few of the 'external' routines (ie everything else in the PDL distribu‐
71 tion) had been changed.
72
73 A quick overview
74
75 perldl> p $PDL::Bad::Status
76 1
77 perldl> $a = sequence(4,3);
78 perldl> p $a
79 [
80 [ 0 1 2 3]
81 [ 4 5 6 7]
82 [ 8 9 10 11]
83 ]
84 perldl> $a = $a->setbadif( $a % 3 == 2 )
85 perldl> p $a
86 [
87 [ 0 1 BAD 3]
88 [ 4 BAD 6 7]
89 [BAD 9 10 BAD]
90 ]
91 perldl> $a *= 3
92 perldl> p $a
93 [
94 [ 0 3 BAD 9]
95 [ 12 BAD 18 21]
96 [BAD 27 30 BAD]
97 ]
98 perldl> p $a->sum
99 120
100
101 "demo bad" and "demo bad2" within perldl gives a demonstration of some
102 of the things possible with bad values. These are also available on
103 PDL's web-site, at http://pdl.perl.org/demos/. See PDL::Bad for useful
104 routines for working with bad values and t/bad.t to see them in action.
105
106 The intention is to:
107
108 · not significantly affect PDL for users who don't need bad value
109 support
110
111 · be as fast as possible when bad value support is installed
112
113 If you never want bad value support, then you set "WITH_BADVAL" to 0 in
114 perldl.conf; PDL then has no bad value support compiled in, so will be
115 as fast as it used to be.
116
117 However, in most cases, the bad value support has a negligible affect
118 on speed, so you should set "WITH_CONFIG" to 1! One exception is if you
119 are low on memory, since the amount of code produced is larger (but
120 only by about 15% - see "Code increase due to bad values").
121
122 To find out if PDL has been compiled with bad value support, look at
123 the values of either $PDL::Config{WITH_BADVAL} or $PDL::Bad::Status -
124 if true then it has been.
125
126 To find out if a routine supports bad values, use the "badinfo" command
127 in perldl or the "-b" option to pdldoc. This facility is currently a
128 'proof of concept' (or, more realistically, a quick hack) so expect it
129 to be rough around the edges.
130
131 Each piddle contains a flag - accessible via "$pdl->badflag" - to say
132 whether there's any bad data present:
133
134 · If false/0, which means there's no bad data here, the code supplied
135 by the "Code" option to "pp_def()" is executed. This means that the
136 speed should be very close to that obtained with "WITH_BADVAL=0",
137 since the only overhead is several accesses to a bit in the piddles
138 state variable.
139
140 · If true/1, then this says there MAY be bad data in the piddle, so
141 use the code in the "BadCode" option (assuming that the "pp_def()"
142 for this routine has been updated to have a BadCode key). You get
143 all the advantages of threading, as with the "Code" option, but it
144 will run slower since you are going to have to handle the presence
145 of bad values.
146
147 If you create a piddle, it will have its bad-value flag set to 0. To
148 change this, use "$pdl->badflag($new_bad_status)", where $new_bad_sta‐
149 tus can be 0 or 1. When a routine creates a piddle, it's bad-value
150 flag will depend on the input piddles: unless over-ridden (see the
151 "CopyBadStatusCode" option to "pp_def"), the bad-value flag will be set
152 true if any of the input piddles contain bad values. To check that a
153 piddle really contains bad data, use the "check_badflag" method.
154
155 NOTE: propogation of the badflag
156
157 If you change the badflag of a piddle, this change is propogated to all
158 the children of a piddle, so
159
160 perldl> $a = zeroes(20,30);
161 perldl> $b = $a->slice('0:10,0:10');
162 perldl> $c = $b->slice(',(2)');
163 perldl> print ">>c: ", $c->badflag, "\n";
164 >>c: 0
165 perldl> $a->badflag(1);
166 perldl> print ">>c: ", $c->badflag, "\n";
167 >>c: 1
168
169 No change is made to the parents of a piddle, so
170
171 perldl> print ">>a: ", $a->badflag, "\n";
172 >>a: 1
173 perldl> $c->badflag(0);
174 perldl> print ">>a: ", $a->badflag, "\n";
175 >>a: 1
176
177 Thoughts:
178
179 · the badflag can ONLY be cleared IF a piddle has NO parents, and
180 that this change will propogate to all the children of that piddle.
181 I am not so keen on this anymore (too awkward to code, for one).
182
183 · "$a->badflag(1)" should propogate the badflag to BOTH parents and
184 children.
185
186 This shouldn't be hard to implement (although an initial attempt
187 failed!). Does it make sense though? There's also the issue of what
188 happens if you change the badvalue of a piddle - should these propogate
189 to children/parents (yes) or whether you should only be able to change
190 the badvalue at the 'top' level - ie those piddles which do not have
191 parents.
192
193 The "orig_badvalue()" method returns the compile-time value for a given
194 datatype. It works on piddles, PDL::Type objects, and numbers - eg
195
196 $pdl->orig_badvalue(), byte->orig_badvalue(), and orig_badvalue(4).
197
198 It also has a horrible name...
199
200 To get the current bad value, use the "badvalue()" method - it has the
201 same syntax as "orig_badvalue()".
202
203 To change the current bad value, supply the new number to badvalue - eg
204
205 $pdl->badvalue(2.3), byte->badvalue(2), badvalue(5,-3e34).
206
207 Note: the value is silently converted to the correct C type, and
208 returned - ie "byte->badvalue(-26)" returns 230 on my linux machine.
209 It is also a "nop" for floating-point types when "BADVAL_USENAN" is
210 true.
211
212 Note that changes to the bad value are NOT propogated to previously-
213 created piddles - they will still have the bad value set, but suddenly
214 the elements that were bad will become 'good', but containing the old
215 bad value. See discussion below. It's not a problem for floating-
216 point types which use NaN, since you can not change their badvalue.
217
218 Bad values and boolean operators
219
220 For those boolean operators in PDL::Ops, evaluation on a bad value
221 returns the bad value. Whilst this means that
222
223 $mask = $img > $thresh;
224
225 correctly propogates bad values, it will cause problems for checks such
226 as
227
228 do_something() if any( $img > $thresh );
229
230 which need to be re-written as something like
231
232 do_something() if any( setbadtoval( ($img > $thresh), 0 ) );
233
234 When using one of the 'projection' functions in PDL::Ufunc - such as
235 orover - bad values are skipped over (see the documentation of these
236 functions for the current (poor) handling of the case when all elements
237 are bad).
238
239 A bad value for each piddle, and related issues
240
241 An experimental option "BADVAL_PER_PDL" has been added to perldl.conf
242 to allow per-piddle bad values. The documentation has not been updated
243 to account for this change.
244
245 The following is relevant only for integer types, and for floating-
246 point types if "BADVAL_USENAN" was not set when PDL was built.
247
248 Currently, there is one bad value for each datatype. The code is writ‐
249 ten so that we could have a separate bad value for each piddle (stored
250 in the pdl structure) - this would then remove the current problem of:
251
252 perldl> $a = byte( 1, 2, byte->badvalue, 4, 5 );
253 perldl> p $a;
254 [1 2 255 4 5]
255 perldl> $a->badflag(1)
256 perldl> p $a;
257 [1 2 BAD 4 5]
258 perldl> byte->badvalue(0);
259 perldl> p $a;
260 [1 2 255 4 5]
261
262 ie the bad value in $a has lost its bad status using the current imple‐
263 mentation. It would almost certainly cause problems elsewhere though!
264
266 During a "perl Makefile.PL", the file Basic/Core/badsupport.p is cre‐
267 ated; this file contains the values of the "WITH_BADVAL", "BADVAL_USE‐
268 NAN" and "BADVAL_PER_PDL" variables, and should be used by code that is
269 executed before the PDL::Config file is created (e.g. Basic/Core/pdl‐
270 core.c.PL. However, most PDL code will just need to access the
271 %PDL::Config array (e.g. Basic/Bad/bad.pd) to find out whether bad-
272 value support is required.
273
274 A new flag has been added to the state of a piddle - "PDL_BADVAL". If
275 unset, then the piddle does not contain bad values, and so all the sup‐
276 port code can be ignored. If set, it does not guarantee that bad values
277 are present, just that they should be checked for. Thanks to Christian,
278 "badflag()" - which sets/clears this flag (see Basic/Bad/bad.pd) - will
279 update ALL the children/grandchildren/etc of a piddle if its state
280 changes (see "badflag" in Basic/Bad/bad.pd and "propogate_badflag" in
281 Basic/Core/Core.xs.PL). It's not clear what to do with parents: I can
282 see the reason for propogating a 'set badflag' request to parents, but
283 I think a child should NOT be able to clear the badflag of a parent.
284 There's also the issue of what happens when you change the bad value
285 for a piddle.
286
287 The "pdl_trans" structure has been extended to include an integer
288 value, "bvalflag", which acts as a switch to tell the code whether to
289 handle bad values or not. This value is set if any of the input piddles
290 have their "PDL_BADVAL" flag set (although this code can be replaced by
291 setting "FindBadStateCode" in pp_def). The logic of the check is going
292 to get a tad more complicated if I allow routines to fall back to using
293 the "Code" section for floating-point types (ie those routines with
294 "NoBadifNaN => 1" when "BADVAL_USENAN" is true).
295
296 The bad values for the integer types are now stored in a structure
297 within the Core PDL structure - "PDL.bvals" (eg Basic/Core/pdl‐
298 core.h.PL); see also "typedef badvals" in Basic/Core/pdl.h.PL and the
299 BOOT code of Basic/Core/Core.xs.PL where the values are initialised to
300 (hopefully) sensible values. See PDL/Bad/bad.pd for read/write rou‐
301 tines to the values.
302
303 The addition of the "BADVAL_PER_PDL" option has resulted in additional
304 changes to the internals of piddles. These changes are not documented
305 yet.
306
307 Why not make a PDL subclass?
308
309 The support for bad values could have been done as a PDL sub-class.
310 The advantage of this approach would be that you only load in the code
311 to handle bad values if you actually want to use them. The downside is
312 that the code then gets separated: any bug fixes/improvements have to
313 be done to the code in two different files. With the present approach
314 the code is in the same "pp_def" function (although there is still the
315 problem that both "Code" and "BadCode" sections need updating).
316
317 Default bad values
318
319 The default/original bad values are set to (taken from the Starlink
320 distribution):
321
322 #include <limits.h>
323
324 PDL_Byte == UCHAR_MAX
325 PDL_Short == SHRT_MIN
326 PDL_Ushort == USHRT_MAX
327 PDL_Long == INT_MIN
328
329 If "BADVAL_USENAN == 0", then we also have
330
331 PDL_Float == -FLT_MAX
332 PDL_Double == -DBL_MAX
333
334 otherwise all of "NaN", "+Inf", and "-Inf" are taken to be bad for
335 floating-point types. In this case, the bad value can't be changed,
336 unlike the integer types.
337
338 How do I change a routine to handle bad values?
339
340 Examples can be found in most of the *.pd files in Basic/ (and hope‐
341 fully many more places soon!). Some of the logic might appear a bit
342 unclear - that's probably because it is! Comments appreciated.
343
344 All routines should automatically propogate the bad status flag to out‐
345 put piddles, unless you declare otherwise.
346
347 If a routine explicitly deals with bad values, you must provide this
348 option to pp_def:
349
350 HandleBad => 1
351
352 This ensures that the correct variables are initialised for the $ISBAD
353 etc macros. It is also used by the automatic document-creation routines
354 to provide default information on the bad value support of a routine
355 without the user having to type it themselves (this is in its early
356 stages).
357
358 To flag a routine as NOT handling bad values, use
359
360 HandleBad => 0
361
362 This should cause the routine to print a warning if it's sent any pid‐
363 dles with the bad flag set. Primitive's "intover" has had this set -
364 since it would be awkward to convert - but I've not tried it out to see
365 if it works.
366
367 If you want to handle bad values but not set the state of all the out‐
368 put piddles, or if it's only one input piddle that's important, then
369 look at the PP rules "NewXSFindBadStatus" and "NewXSCopyBadStatus" and
370 the corresponding "pp_def" options:
371
372 FindBadStatusCode
373 By default, "FindBadStatusCode" creates code which sets
374 "$PRIV(bvalflag)" depending on the state of the bad flag of the
375 input piddles: see "findbadstatus" in Basic/Gen/PP.pm. User-
376 defined code should also store the value of "bvalflag" in the
377 "$BADFLAGCACHE()" variable.
378
379 CopyBadStatusCode
380 The default code here is a bit simpler than for "FindBadStatus‐
381 Code": the bad flag of the output piddles are set if "$BADFLAG‐
382 CACHE()" is true after the code has been evaluated. Sometimes
383 "CopyBadStatusCode" is set to an empty string, with the responsi‐
384 bility of setting the badflag of the output piddle left to the
385 "BadCode" section (e.g. the "xxxover" routines in Basic/Primi‐
386 tive/primitive.pd).
387
388 Prior to PDL 2.4.3 we used "$PRIV(bvalflag)" instead of "$BADFLAG‐
389 CACHE()". This is dangerous since the "$PRIV()" structure is not
390 guaranteed to be valid at this point in the code.
391
392 If you have a routine that you want to be able to use as inplace, look
393 at the routines in bad.pd (or ops.pd) which use the "Inplace" option to
394 see how the bad flag is propogated to children using the "xxxBadStatus‐
395 Code" options. I decided not to automate this as rules would be a lit‐
396 tle complex, since not every inplace op will need to propogate the bad‐
397 flag (eg unary functions).
398
399 If the option
400
401 HandleBad => 1
402
403 is given, then many things happen. For integer types, the readdata
404 code automatically creates a variable called "<pdl name>_badval", which
405 contains the bad value for that piddle (see "get_xsdatapdecl()" in
406 Basic/Gen/PP/PdlParObjs.pm). However, do not hard code this name into
407 your code! Instead use macros (thanks to Tuomas for the suggestion):
408
409 '$ISBAD(a(n=>1))' expands to '$a(n=>1) == a_badval'
410 '$ISGOOD(a())' '$a() != a_badval'
411 '$SETBAD(bob())' '$bob() = bob_badval'
412
413 well, the "$a(...)" is expanded as well. Also, you can use a "$" before
414 the pdl name, if you so wish, but it begins to look like line noise -
415 eg "$ISGOOD($a())".
416
417 If you cache a piddle value in a variable -- eg "index" in slices.pd --
418 the following routines are useful:
419
420 '$ISBADVAR(c_var,pdl)' 'c_var == pdl_badval'
421 '$ISGOODVAR(c_var,pdl)' 'c_var != pdl_badval'
422 '$SETBADVAR(c_var,pdl)' 'c_var = pdl_badval'
423
424 The following have been introduced, They may need playing around with
425 to improve their use.
426
427 '$PPISBAD(CHILD,[i]) 'CHILD_physdatap[i] == CHILD_badval'
428 '$PPISGOOD(CHILD,[i]) 'CHILD_physdatap[i] != CHILD_badval'
429 '$PPSETBAD(CHILD,[i]) 'CHILD_physdatap[i] = CHILD_badval'
430
431 If "BADVAL_USENAN" is set, then it's a bit different for "float" and
432 "double", where we consider "NaN", "+Inf", and "-Inf" all to be bad. In
433 this case:
434
435 ISBAD becomes finite(piddle) == 0
436 ISGOOD finite(piddle) != 0
437 SETBAD piddle = NaN
438
439 where the value for NaN is discussed below in Handling NaN values.
440
441 This all means that you can change
442
443 Code => '$a() = $b() + $c();'
444
445 to
446
447 BadCode => 'if ( $ISBAD(b()) ⎪⎪ $ISBAD(c()) ) {
448 $SETBAD(a());
449 } else {
450 $a() = $b() + $c();
451 }'
452
453 leaving Code as it is. PP::PDLCode will then create a loop something
454 like
455
456 if ( __trans->bvalflag ) {
457 threadloop over BadCode
458 } else {
459 threadloop over Code
460 }
461
462 (it's probably easier to just look at the .xs file to see what goes
463 on).
464
465 Going beyond the Code section
466
467 Similar to "BadCode", there's "BadBackCode", and "BadRedoDimsCode".
468
469 Handling "EquivCPOffsCode" is a bit different: under the assumption
470 that the only access to data is via the "$EQUIVCPOFFS(i,j)" macro, then
471 we can automatically create the 'bad' version of it; see the "[Equiv‐
472 CPOffsCode]" and "[Code]" rules in PDL::PP.
473
474 Macro access to the bad flag of a piddle
475
476 Macros have been provided to provide access to the bad-flag status of a
477 pdl:
478
479 '$PDLSTATEISBAD(a)' -> '($PDL(a)->state & PDL_BADVAL) > 0'
480 '$PDLSTATEISGOOD(a)' '($PDL(a)->state & PDL_BADVAL) == 0'
481
482 '$PDLSTATESETBAD(a)' '$PDL(a)->state ⎪= PDL_BADVAL'
483 '$PDLSTATESETGOOD(a)' '$PDL(a)->state &= ~PDL_BADVAL'
484
485 For use in "xxxxBadStatusCode" (+ other stuff that goes into the INIT:
486 section) there are:
487
488 '$SETPDLSTATEBAD(a)' -> 'a->state ⎪= PDL_BADVAL'
489 '$SETPDLSTATEGOOD(a)' -> 'a->state &= ~PDL_BADVAL'
490
491 '$ISPDLSTATEBAD(a)' -> '((a->state & PDL_BADVAL) > 0)'
492 '$ISPDLSTATEGOOD(a)' -> '((a->state & PDL_BADVAL) == 0)'
493
494 In PDL 2.4.3 the "$BADFLAGCACHE()" macro was introduced for use in
495 "FindBadStatusCode" and "CopyBadStatusCode".
496
497 Handling NaN values
498
499 There are two issues:
500
501 NaN as the bad value
502 which is done. To select, set "BADVAL_USENAN" to 1 in perldl.conf;
503 a value of 0 falls back to treating the floating-point types the
504 same as the integers. I need to do some benchmarks to see which is
505 faster, and whether it's dependent on machines (Linux seems to slow
506 down much more than my sparc machine in some very simple tests I
507 did).
508
509 Ignoring BadCode sections
510 which is not.
511
512 For simple routines processing floating-point numbers, we should let
513 the computer process the bad values (ie "NaN" and "Inf" values) instead
514 of using the code in the "BadCode" section. Many such routines have
515 been labelled using "NoBadifNaN => 1"; however this is currently
516 ignored by PDL::PP.
517
518 For these routines, we want to use the "Code" section if
519
520 the piddle does not have its bad flag set
521 the datatype is a float or double
522
523 otherwise we use the "BadCode" section. This is NOT IMPLEMENTED, as it
524 will require reasonable hacking of PP::PDLCode!
525
526 There's also the problem of how we handle 'exceptions' - since "$a =
527 pdl(2) / pdl(0)" produces a bad value but doesn't update the badflag
528 value of the piddle. Can we catch an exception, or do we have to trap
529 for this (e.g. search for "exception" in Basic/Ops/ops.pd)?
530
531 Checking for "Nan", and "Inf" is done by using the "finite()" system
532 call. If you want to set a value to the "NaN" value, the following bit
533 of code can be used (this can be found in both Basic/Core/Core.xs.PL
534 and Basic/Bad/bad.pd):
535
536 /* for big-endian machines */
537 static union { unsigned char __c[4]; float __d; }
538 __pdl_nan = { { 0x7f, 0xc0, 0, 0 } };
539
540 /* for little-endian machines */
541 static union { unsigned char __c[4]; float __d; }
542 __pdl_nan = { { 0, 0, 0xc0, 0x7f } };
543
544 This approach should probably be replaced by library routines such as
545 "nan("")" or "atof("NaN")".
546
547 To find out whether a particular machine is big endian, use the routine
548 "PDL::Core::Dev::isbigendian()".
549
551 One of the strengths of PDL is it's on-line documentation. The aim is
552 to use this system to provide informtion on how/if a routine supports
553 bad values: in many cases "pp_def()" contains all the information any‐
554 way, so the function-writer doesn't need to do anything at all! For the
555 cases when this is not sufficient, there's the "BadDoc" option. For
556 code written at the perl level - ie in a .pm file - use the "=for bad"
557 pod directive.
558
559 This information will be available via man/pod2man/html documenation.
560 It's also accessible from the "perldl" shell - using the "badinfo" com‐
561 mand - and the "pdldoc" shell command - using the "-b" option.
562
563 This support is at a very early stage - ie not much thought has gone
564 into it: comments are welcome; improvements to the code preferred ;)
565 One awkward problem is for *.pm code: you have to write a *.pm.PL file
566 which only inserts the "=for bad" directive (+ text) if bad value sup‐
567 port is compiled in. In fact, this is a pain when handling bad values
568 at the perl, rather than PDL::PP, level: perhaps I should just scrap
569 the "WITH_BADVAL" option...
570
572 There are a number of areas that need work, user input, or both! They
573 are mentioned elsewhere in this document, but this is just to make sure
574 they don't get lost.
575
576 Trapping invalid mathematical operations
577
578 Should we add exceptions to the functions in "PDL::Ops" to set the out‐
579 put bad for out-of-range input values?
580
581 perldl> p log10(pdl(10,100,-1))
582
583 I would like the above to produce "[1 2 BAD]", but this would slow down
584 operations on all piddles. We could check for "NaN"/"Inf" values after
585 the operation, but I doubt that would be any faster.
586
587 Integration with NaN
588
589 When "BADVAL_USENAN" is true, the routines in "PDL::Ops" should just
590 fall through to the "Code" section - ie don't use "BadCode" - for
591 "float" and "double" data types.
592
593 Global versus per-piddle bad values
594
595 I think all that's needed is to change the routines in "Basic/Core/pdl‐
596 conv.c.PL", although there's bound to be complications. It would also
597 mean that the pdl structure would need to have a variable to store its
598 bad value, which would mean binary incompatability with previous ver‐
599 sions of PDL with bad value support.
600
601 As of 17 March 2006, PDL contains the experimental "BADVAL_PER_PDL"
602 configuration option which, if selected, adds per-piddle bad values.
603
604 Dataflow of the badflag
605
606 Currently changes to the bad flag are propogated to the children of a
607 piddle, but perhaps they should also be passed on to the parents as
608 well. With the advent of per-piddle bad values we need to consider how
609 to handle changes to the value used to represent bad items too.
610
612 The build process has been affected. The following files are now cre‐
613 ated during the build:
614
615 Basic/Core/pdlcore.h pdlcore.h.PL
616 pdlcore.c pdlcore.c.PL
617 pdlapi.c pdlapi.c.PL
618 Core.xs Core.xs.PL
619 Core.pm Core.pm.PL
620
621 Several new files have been added:
622
623 Basic/Pod/Badvalues.pod (ie this file)
624
625 t/bad.t
626
627 Basic/Bad/
628 Basic/Bad/Makefile.PL
629 bad.pd
630
631 IO/NDF/NDF.xs.PL
632
633 etc
634
636 · Look at using per-piddle bad values. Would mean a change to the
637 pdl structure (ie binary incompatability) and the routines in
638 "Basic/Core/pdlconv.c.PL" would need changing to handle this. Most
639 other routines should not need to be changed ...
640
641 See the experimental "BADVAL_PER_PDL" option.
642
643 · what to do about "$b = pdl(-2); $a = log10($b)" - $a should be set
644 bad, but it currently isn't.
645
646 · Allow the operations in PDL::Ops to skip the check for bad values
647 when using NaN as a bad value and processing a floating-point pid‐
648 dle. Needs a fair bit of work to PDL::PP::PDLCode.
649
650 · "$pdl->baddata()" now updates all the children of this piddle as
651 well. However, not sure what to do with parents, since:
652
653 $b = $a->slice();
654 $b->baddata(0)
655
656 doesn't mean that $a shouldn't have it's badvalue cleared. how‐
657 ever, after
658
659 $b->baddata(1)
660
661 it's sensible to assume that the parents now get flagged as con‐
662 taining bad values.
663
664 PERHAPS you can only clear the bad value flag if you are NOT a
665 child of another piddle, whereas if you set the flag then all chil‐
666 dren AND parents should be set as well?
667
668 Similarly, if you change the bad value in a piddle, should this be
669 propogated to parent & children? Or should you only be able to do
670 this on the 'top-level' piddle? Nasty...
671
672 · get some code set up to do benchmarks to see how much things are
673 slowed down (and to check that I haven't messed things up if
674 "WITH_BADVAL" is 0/undef).
675
676 · some of the names aren't appealing - I'm thinking of "orig_bad‐
677 value()" in Basic/Bad/bad.pd in particular. Any suggestions appre‐
678 ciated.
679
681 Copyright (C) Doug Burke (djburke@cpan.org), 2000, 2006.
682
683 The per-piddle bad value support is by Heiko Klein (2006).
684
685 Commercial reproduction of this documentation in a different format is
686 forbidden.
687
688
689
690perl v5.8.8 2003-05-21 BADVALUES(1)