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