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

IMPLEMENTATION DETAILS

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

WHAT ABOUT DOCUMENTATION?

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

CURRENT ISSUES

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

EVERYTHING ELSE

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

TODO/SUGGESTIONS

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

AUTHOR

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