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