POV-Ray : Newsgroups : povray.pov4.discussion.general : Parser checking. Pitfalls of float, (5d) color vector. (povr play) : Parser checking. Pitfalls of float, (5d) color vector. (povr play) Server Time
28 Mar 2024 16:37:38 EDT (-0400)
  Parser checking. Pitfalls of float, (5d) color vector. (povr play)  
From: William F Pokorny
Date: 12 Jun 2021 13:18:03
Message: <60c4ec4b@news.povray.org>
I'd been posting about some of the povr branch stuff I thought perhaps 
useful to an eventual v3.8 or V4.0 elsewhere, but given it looks like 
v4.0 will be starting up as an actual development branch I'm going to 
start to posting the potential 'povr ideas' for v4.0 here.

--- On better parser checking
An idea I've recently started to code up in the povr branch is better 
parser SDL checking around function and vectors. It's been the case that 
not nearly everything which could be checked by the parser is so a lot 
can slip by. As the example which comes to mind the pow() function only 
parser domain check is whether both input values are zero.

Checking everything is a not insignificant expense at parse time. So, 
the approach I've taken is the introduction of a compile time 
configuration called POV_PARSER_SDL_DEBUG. By default the few parse time 
checks are now off. When POV_PARSER_SDL_DEBUG the old checks and many 
more are enabled.

POV_PARSER_SDL_DEBUG is also activated when the more general POV_DEBUG 
is set which itself activates a bunch of internal code assertions. When 
I looked at the standard POV-Ray debian packaging on my move to Ubuntu 
20.04, I noticed in the debian developer space private work around 
providing debug versions of POV-Ray in addition to the standard version 
(probably with debug symbols too). Providing a normal version of 
POV-Ray, and a debug version, I think it a good idea.

So, it would be that on seeing something funky happening, a standard 
practice would be to run the debug version of POV-Ray over the normal. 
If lucky, the 'POV_DEBUG' version will point directly to the issue 
where, POV-Ray today, mostly lets numerical stuff go - slightly more 
true on unix/linux where compiling with -ffast-math.

--- The new parser checking and the color vector being at float.
While checking some of the new POV_PARSER_SDL_DEBUG I stumbled my way to 
the following test / test results. First, what one gets from the 
particular tests today in v3.7 or v3.8.

    ---
V2.x*1 -->  3e38 300000000000000012135895401846682943488.000000
V2.y*1 -->  5e38 499999999999999969854583185801589293056.000000
    <==
V3.x*1 -->  3e38 300000000000000012135895401846682943488.000000
V3.y*1 -->  3e38 300000000000000012135895401846682943488.000000
V3.z*1 -->  5e38 499999999999999969854583185801589293056.000000
    <==
V4.x*1 -->  3e38 300000000000000012135895401846682943488.000000
V4.y*1 -->  3e38 300000000000000012135895401846682943488.000000
V4.z*1 -->  3e38 300000000000000012135895401846682943488.000000
V4.t*1 -->  5e38 499999999999999969854583185801589293056.000000
    <==
V5.x*1 -->  3e38 300000000549775575777803994281145270272.000000
V5.y*1 -->  3e38 300000000549775575777803994281145270272.000000
V5.z*1 -->  3e38 300000000549775575777803994281145270272.000000
V5.t*1 -->  3e38 300000000549775575777803994281145270272.000000
V5.transmit*1 -->  5e38       inf
    <==

The current POV-Ray offerings never let you know about that last 
internal bad infinite value due the double to single type conversion 
going from the parser double specification to the internal 5d color 
float vector. Further, that bad color vect, float, 'HUGE_VAL' gets 
carried into downstream calculations, which are nearly all at double, no 
matter whether the original parse value would have been a valid double 
or not. At run time propagating that HUGE_VAL is all that can be done on 
the float to double conversion.


My updated POV_PARSER_SDL_DEBUG version of povr dies with:

---
V2.x*1 -->  3e38 300000000000000012135895401846682943488.000000
V2.y*1 -->  5e38 499999999999999969854583185801589293056.000000
    <==
V3.x*1 -->  3e38 300000000000000012135895401846682943488.000000
V3.y*1 -->  3e38 300000000000000012135895401846682943488.000000
V3.z*1 -->  3e38 499999999999999969854583185801589293056.000000
    <==
V4.x*1 -->  3e38 300000000000000012135895401846682943488.000000
V4.y*1 -->  3e38 300000000000000012135895401846682943488.000000
V4.z*1 -->  3e38 300000000000000012135895401846682943488.000000
V4.t*1 -->  3e38 499999999999999969854583185801589293056.000000
    <==
V5.x*1 -->  3e38 300000000549775575777803994281145270272.000000
V5.y*1 -->  3e38 300000000549775575777803994281145270272.000000
V5.z*1 -->  3e38 300000000549775575777803994281145270272.000000
V5.t*1 -->  3e38 300000000549775575777803994281145270272.000000
File 'vtests.inc' line 63:
Parse Error:
Value or return from vector expression.
Term 1 is too large.

The new checking sees the double HUGE_VAl value and dies.

--- On color vector components being only floats.
When just storing colors say for image display this OK.

In calculations - especially of the kind we might be doing where color 
vectors are being used in isosurfaces say, it's mostly bad news. Note 
this more affects the resulting number of significant digits than there 
be any issue with occasional infinite(inf) or not a number(nan) results. 
It's a numerical situation bad enough I'm strongly considering a move to 
double color more or less everywhere - no matter the storage hit.

Aside: Today in the source code there are internal precise color 
calculations which calculate at double, but stored colors are all at 
floats as far I know. float -> double -> calculate -> double -> float.

Bill P.

P.S. But Bill! If color floats are a numerical concern what about all 
those other settings we store for patterns say which are at single 
floats. Well, I've long been moving most of those to doubles when I run 
across them.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.