1BADVALUES(1)          User Contributed Perl Documentation         BADVALUES(1)
2
3
4

NAME

6       PDL::BadValues - Discussion of bad value support in PDL
7

DESCRIPTION

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

IMPLEMENTATION DETAILS

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

WHAT ABOUT DOCUMENTATION?

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

CURRENT ISSUES

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

EVERYTHING ELSE

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

TODO/SUGGESTIONS

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

AUTHOR

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)
Impressum