|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Hi folks,
I noticed a not correct value for clock in animation.
Test with version 3.7.0.RC3.msvc9.win64 running on Windows 7 (64bit).
ini-script:
Input_File_Name="clock_precision.pov"
Initial_Frame=1
Final_Frame=30
Cyclic_Animation=on
Subset_Start_Frame = 21
Subset_End_Frame = 21
Input_File_Name clock_precision.pov:
#version 3.7;
global_settings { assumed_gamma 1.0 }
camera {location <0,0,-1> look_at 0}
light_source {1500 color rgb<1,1,1>}
sky_sphere {pigment {color rgb<1,1,1>}}
#if (final_frame=0) // IMHO: The precision of clock on 64 bit system or version
3.7 is not correct
#declare g_Clock=0;
#else
#declare g_Clock=(frame_number-1)/(final_frame-initial_frame); // = clock ???
#end
#include "screen.inc"
Screen_Object(text{ttf "COURBD.TTF" concat( "initial_frame: " ,
str(initial_frame, 4,0)) 0.1 0 pigment{color 0} scale .08},<0.01,1-0.1*1>,0,0,1)
Screen_Object(text{ttf "COURBD.TTF" concat( "final_frame : " ,
str(final_frame , 4,0)) 0.1 0 pigment{color 0} scale .08},<0.01,1-0.1*2>,0,0,1)
Screen_Object(text{ttf "COURBD.TTF" concat( "frame_number : " ,
str(frame_number , 4,0)) 0.1 0 pigment{color 0} scale .08},<0.01,1-0.1*3>,0,0,1)
Screen_Object(text{ttf "COURBD.TTF" concat( "clock : " , str(clock
,12,9)) 0.1 0 pigment{color 0} scale .08},<0.01,1-0.1*5>,0,0,1)
Screen_Object(text{ttf "COURBD.TTF" concat( "g_Clock : " , str(g_Clock
,12,9)) 0.1 0 pigment{color 0} scale .08},<0.01,1-0.1*6>,0,0,1)
#debug concat( "frame_number: ", str(frame_number,4,0)," clock: ",
str(clock,12,9)," g_Clock: ", str(g_Clock,12,9),"\n")
Result: frame_number: 21 clock: 0.666666687 g_Clock: 0.666666667
There is a difference of 0.66666662
And I noticed a bigger difference with a larger amount of frames.
I just liked to mention this behaviour and may be I am overlooking something.
Regards, ErO
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
On 25.06.11 22:25, ErOssel wrote:
> Hi folks,
>
> I noticed a not correct value for clock in animation.
>
> Test with version 3.7.0.RC3.msvc9.win64 running on Windows 7 (64bit).
<snip>
> Result: frame_number: 21 clock: 0.666666687 g_Clock: 0.666666667
> There is a difference of 0.66666662
I guess you meant that the difference is 0.00000002, which is perfectly
normal for floating point numbers. The difference will vary depending on how
well a number can be represented, hence you will see slightly different
precision errors for different values.
This precision limit is normal and not a problem in POV-Ray.
Thorsten
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Thorsten Froehlich <tho### [at] trfde> wrote:
> On 25.06.11 22:25, ErOssel wrote:
> > Hi folks,
> >
> > I noticed a not correct value for clock in animation.
> >
> > Test with version 3.7.0.RC3.msvc9.win64 running on Windows 7 (64bit).
> <snip>
> > Result: frame_number: 21 clock: 0.666666687 g_Clock: 0.666666667
> > There is a difference of 0.66666662
>
> I guess you meant that the difference is 0.00000002, which is perfectly
> normal for floating point numbers. The difference will vary depending on how
> well a number can be represented, hence you will see slightly different
> precision errors for different values.
>
> This precision limit is normal and not a problem in POV-Ray.
>
> Thorsten
Hi Thorsten,
Yes, you're right, it should be with zero's.
I am not afraid that the result of calculation will be wrong, but with 3.6 is
goes as expected.
My animation is printing clock*48 with 2880 frames and on frame 2570 the
difference is already within 6 decimal digits.
frame_number: 2570 clock*48: 42.816668 g_Clock*48: 42.816667
Doing it by storing clock in a variable is okay for me.
I just do not understand the difference using the inbuilt float clock and an
user variable. And confused with the change between 3.6 and 3.7!
Anyway, thanks for your reaction.
Regards, ErO
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Am 26.06.2011 00:08, schrieb ErOssel:
> I just do not understand the difference using the inbuilt float clock and an
> user variable. And confused with the change between 3.6 and 3.7!
(1) You're computing the user variable with a single-step computation,
whereas POV-Ray first computes a "clock delta" and then increments the
clock variable by that delta every frame. As a result, any rounding
errors due to the division add up from frame to frame.
(2) The clock delta was stored using double precision in 3.6; this was
changed with the stricter separation of front- and back-end in POV-Ray:
Being computed in the front-end but used in the back-end, the value is
passed between the two parts in single precision. Therefore the rounding
errors in the delta are greater than they used to be in 3.6.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
clipka <ano### [at] anonymousorg> wrote:
> Am 26.06.2011 00:08, schrieb ErOssel:
>
> > I just do not understand the difference using the inbuilt float clock and an
> > user variable. And confused with the change between 3.6 and 3.7!
>
> (1) You're computing the user variable with a single-step computation,
> whereas POV-Ray first computes a "clock delta" and then increments the
> clock variable by that delta every frame. As a result, any rounding
> errors due to the division add up from frame to frame.
>
> (2) The clock delta was stored using double precision in 3.6; this was
> changed with the stricter separation of front- and back-end in POV-Ray:
> Being computed in the front-end but used in the back-end, the value is
> passed between the two parts in single precision. Therefore the rounding
> errors in the delta are greater than they used to be in 3.6.
Hi Clipka,
Wow, that's an answer.
It is all clear now.
Thank you very much.
Kind regards, ErO
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
clipka <ano### [at] anonymousorg> wrote:
> (1) You're computing the user variable with a single-step computation,
> whereas POV-Ray first computes a "clock delta" and then increments the
> clock variable by that delta every frame. As a result, any rounding
> errors due to the division add up from frame to frame.
Why does it do it like that?
Every programmer knows that if you want a certain amount of evenly
distributed floating point values within a given range, you don't do
it by adding the (floating point) delta value to an initial (floating
point) value because if you do that, in most cases any rounding errors
in the delta value will accumulate and you will get an ever increasing
rounding error as the loop progresses. Instead, you use an integer as
the loop variable and calculate the floating point value from it. This
way you will get the equal steps inside the range with as much precision
as the floating point format allows and there's no accumulating rounding
error.
(There are certain situations where high accuracy is not important, and
much more important is for the calculation to be as fast as possible, in
which case summation of a delta value is faster because it requires only
one addition per iteration, while the more exact method requires a lot
more operations per iteration, including conversion of an integer to
floating point and a division, which is a lot more. However, in this case
the efficiency is completely inconsequential because this is done once
per frame.)
> (2) The clock delta was stored using double precision in 3.6; this was
> changed with the stricter separation of front- and back-end in POV-Ray:
> Being computed in the front-end but used in the back-end, the value is
> passed between the two parts in single precision. Therefore the rounding
> errors in the delta are greater than they used to be in 3.6.
Is there any rational reason for it (or anything else, for that matter)
to be parsed as a float instead of a double?
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
On 26.06.11 13:27, Warp wrote:
> clipka<ano### [at] anonymousorg> wrote:
>> (1) You're computing the user variable with a single-step computation,
>> whereas POV-Ray first computes a "clock delta" and then increments the
>> clock variable by that delta every frame. As a result, any rounding
>> errors due to the division add up from frame to frame.
>
> Why does it do it like that?
>
> Every programmer knows<rant removed>
Because it is an explanation for non-programmers. Notice how he does *not*
say that errors of the addition add up - because there is no addition, it is
of course a multiplication.
Thorsten
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Am 26.06.2011 13:53, schrieb Thorsten Froehlich:
> Because it is an explanation for non-programmers. Notice how he does
> *not* say that errors of the addition add up - because there is no
> addition, it is of course a multiplication.
You're right here, Thorsten - my bad. Just checked the code again, and
it does indeed compute the clock using a non-iterative formula - based
on a low-precision clockDelta though.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Thorsten Froehlich <tho### [at] trfde> wrote:
> Because it is an explanation for non-programmers. Notice how he does *not*
> say that errors of the addition add up - because there is no addition, it is
> of course a multiplication.
A multiplication is the same thing as the series of additions, just done
in one single step. The end result will have the same accumulated rounding
error.
Although these are mathematically the same, programmatically they are not:
double timeDelta = (finalClock - initialClock) / totalFrames;
double currentClock = initialClock + currentFrame * timeDelta;
vs:
double currentClock = initialClock +
currentFrame * (finalClock - initialClock) / totalFrames;
The difference is subtle, but exists. The crucial difference is the
order in which the multiplication and the division are done. The problem
is that with a fixed amount of mantissa bits, the division loses more
information than the multiplication, hence if the division is done first,
it will cause a larger rounding error than if the multiplication is done
first. (Basically doing the division first and then the multiplication is
the same thing as iteratively adding the delta value as many times as the
current amount of frames, with the ensuing accumulated rounding error.)
This is also the reason why compilers won't make that kind of optimization
(eg. taking a division out of a loop), because the results may be different
(unless you specifically allow for such optimizations in some compilers).
And please don't read more to this post than there is. I know that many
programmers detest their work being criticized, but that's not what I'm
doing here (and in fact I haven't even checked how exactly is it that
povray is doing this). I'm just chatting. This might be interesting
information to someone.
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
On 27.06.11 08:14, Warp wrote:
> The difference is subtle, but exists.
Yes, at that point there will also be a difference in the computation. It
will be noticeable above 10 million frames (10**7), which is 46 hours for a
60 fps animation. This is due to the clock value being transmitted as 32-bit
float while the computation is done with 64-bit floats. Thus, to see the
error, you need to exceed the precision limit of the 64-bit float, which is
about eight decimal digits greater than that of a 32-bit float.
Due to the muliplication, this error will not accumulate though, hence you
can see it, but it requires rather extreme applications. I think most would
agree that the number of users that want to render 46 hour long animations
are extremely rare.
Thorsten
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|