POV-Ray : Newsgroups : povray.advanced-users : <no subject> Server Time: 10 Dec 2018 06:16:12 GMT
  <no subject> (Message 1 to 10 of 18)  
Goto Latest 10 Messages Next 8 Messages >>>
From: Bald Eagle
Subject: <no subject>
Date: 13 Sep 2018 23:35:00
Message: <web.5b9af324c23a6d9458c7afe0@news.povray.org>
[Floating-point] math is hard.

You just wonít believe how vastly, hugely, mind-bogglingly hard it is. I mean,
you may think itís difficult to calculate when trains from Chicago and Los
Angeles will collide, but thatís just peanuts to floating-point math.

Seriously. Each time I think that Iíve wrapped my head around the subtleties and
implications of floating-point math I find that Iím wrong and that there is some
extra confounding factor that I had failed to consider. So, the lesson to
remember is that floating-point math is always more complex than you think it
is.

I may need something ... stronger than coffee, gin, bourbon, and Stephen's
proprietary family-secret Dried Frog Pills (TM) (R) (c)

I had ironed out some stupid errors and was homing in working out the wonkiness
of a function and, lo and behold, I'm getting an "...uninitialized array
element..." error - not because i was working outside the scope of my 2D array,
but because the comparison I was trying to perform - WAIT --- HAD been
performing for the last week - suddenly didn't like to successfully compare 0 to
.... "zero".

@#%$^&**

So I have an array of vectors with .y and .z values ranging from 0 to tau, or
2*pi, or whatever the #version's parser allows...

And I just want to see "where" in that range I am....



    #local Mult = 1000;

    #local _Patch = array [6];

    #for (U, 0, Usize)
        #debug concat ("Testing Y = ", Scalar (YVal, 3, 0), " vs ", Vector
(UArray [U], 3, 0), " \n")

(commmence anti-floating point calisthenics...)

        #if ( int(YVal*Mult) >= int(UArray [U].y*Mult) & int(YVal*Mult) <=
int(UArray [U].z*Mult) )

        #local _Patch [0] = UArray [U].x;
        #local _Patch [1] = UArray [U].y;
        #local _Patch [2] = UArray [U].z;
        #end
    #end





And I mean, it's ZERO, so what do I multiply by and round it with?
Is f'ing  _***INT***_ (0) not ZERO?!

:|


I would like a kind soul to attempt, again, in a practical way, to suggest an
effective algorithm that will allow "easy" and accurate comparison of numbers
derived in some way shape or form from floating point calculations.


Apparently #for (N, 0, ....
doesn't give me a zero that's equal to 0 * N2....


Post a reply to this message

From: Bald Eagle
Subject: Re: <no subject>
Date: 13 Sep 2018 23:40:01
Message: <web.5b9af4d46f92e856458c7afe0@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
> [Floating-point] math is hard.

.....

> So, the lesson to
> remember is that floating-point math is always more complex than you think it
> is.

Forgot to add wuotes and link and credit:
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/


Post a reply to this message

From: clipka
Subject: Re: <no subject>
Date: 14 Sep 2018 03:17:25
Message: <5b9b2845$1@news.povray.org>
Am 14.09.2018 um 01:30 schrieb Bald Eagle:

> So I have an array of vectors with .y and .z values ranging from 0 to tau, or
> 2*pi, or whatever the #version's parser allows...
> 
> And I just want to see "where" in that range I am....
> 
> 
> 
>     #local Mult = 1000;
> 
>     #local _Patch = array [6];
> 
>     #for (U, 0, Usize)
>         #debug concat ("Testing Y = ", Scalar (YVal, 3, 0), " vs ", Vector
> (UArray [U], 3, 0), " \n")
> 
> (commmence anti-floating point calisthenics...)
> 
>         #if ( int(YVal*Mult) >= int(UArray [U].y*Mult) & int(YVal*Mult) <=
> int(UArray [U].z*Mult) )
> 
>         #local _Patch [0] = UArray [U].x;
>         #local _Patch [1] = UArray [U].y;
>         #local _Patch [2] = UArray [U].z;
>         #end
>     #end
> 
> And I mean, it's ZERO, so what do I multiply by and round it with?
> Is f'ing  _***INT***_ (0) not ZERO?!
...
> Apparently #for (N, 0, ....
> doesn't give me a zero that's equal to 0 * N2....

Wait.

What you're multiplying is YVal, not U.
What you're debug-outputting is YVal rounded to 0 decimals, not YVal
(nor U, for that matter).


And yes, that Random ASCII article is precise to the last digit:
Floating point arithmetics comes with 16 serious issues - and counting.


Post a reply to this message

From: Thomas de Groot
Subject: Re: <no subject>
Date: 14 Sep 2018 06:43:15
Message: <5b9b5883$1@news.povray.org>
On 14-9-2018 1:30, Bald Eagle wrote:
> I may need something ... stronger than coffee, gin, bourbon, and Stephen's
> proprietary family-secret Dried Frog Pills (TM) (R) (c)
> 

Be careful about those pills, especially in combination with fire water. 
Stephen certainly warned you about it (or he should have). They got me 
in the padded cell.

-- 
Thomas


Post a reply to this message

From: Bald Eagle
Subject: Re: <no subject>
Date: 14 Sep 2018 10:30:00
Message: <web.5b9b8d556f92e856458c7afe0@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:

> Wait.
>
> What you're multiplying is YVal, not U.
> What you're debug-outputting is YVal rounded to 0 decimals, not YVal
> (nor U, for that matter).

Well what I'm comparing the loop integer to is max(0, U*Ustep) [see far below],
and it's crapping out right out of the gate.

                     element  low   high
_X = 0.00000, _Y = 0.00000
Testing Y = 0.000 vs <0.000, 0.000, 1.047> // totally skips this  :(
Testing Y = 0.000 vs <1.000, 1.047, 2.094>
Testing Y = 0.000 vs <2.000, 2.094, 3.142>
Testing Y = 0.000 vs <3.000, 3.142, 4.189>
Testing Y = 0.000 vs <4.000, 4.189, 5.236>
Testing Y = 0.000 vs <5.000, 5.236, 6.283>
Testing Y = 0.000 vs <6.000, 6.283, 6.283>


My #debug output - those are macros - it's rounding to 3 decimals (see above),
the 0 is a flag for +/- "\n".



#declare Ustep = (U2-U1)/(UU);
#declare Vstep = (V2-V1)/(VV);

#debug concat ("UStep = U2 (", Scalar (U2, 5, 0), ") - U1 (", Scalar (U1, 5, 0),
") / Usize (", Scalar (Usize, 5, 0), ") = ", Scalar (Ustep, 5, 1))
#debug concat ("VStep = V2 (", Scalar (V2, 5, 0), ") - V1 (", Scalar (V1, 5, 0),
") / Vsize (", Scalar (Vsize, 5, 0), ") = ", Scalar (Vstep, 5, 1))

#debug "\n\n"

#for (U, 0, UU)     // must be UU because SitchedArray is only that big
 #declare UArray [U] = <U, max(0, U*Ustep), min((U+1)*Ustep, U2)>;
 //#debug concat ("UArray [", Scalar (U, 0, 0), "] = ", Vector (UArray [U], 5,
1))
#end

#for (V, 0, VV) // must be VV because SitchedArray is only that big
 #declare VArray [V] = <V, max(0, V*Vstep), min((V+1)*Vstep, V2)>;
 //#debug concat ("VArray [", Scalar (V, 0, 0), "] = ", Vector (VArray [V], 5,
1))
#end


Post a reply to this message

From: Bald Eagle
Subject: Re: <no subject>
Date: 14 Sep 2018 15:20:00
Message: <web.5b9bd08a6f92e856c437ac910@news.povray.org>
Thomas de Groot <tho### [at] degrootorg> wrote:
> On 14-9-2018 1:30, Bald Eagle wrote:
> > I may need something ... stronger than coffee, gin, bourbon, and Stephen's
> > proprietary family-secret Dried Frog Pills (TM) (R) (c)
> >
>
> Be careful about those pills, especially in combination with fire water.
> Stephen certainly warned you about it (or he should have). They got me
> in the padded cell.
>
> --
> Thomas

Lightweight.  :P

Next thing, you'll be telling me that the hookah he and I have been building to
smoke some imported dried Conraua goliath is ... "ill advised".

Now, be a good lad and fetch me a Winchester bottle of ether.


Post a reply to this message

From: clipka
Subject: Re: <no subject>
Date: 14 Sep 2018 17:13:08
Message: <5b9bec24$1@news.povray.org>
Am 14.09.2018 um 12:28 schrieb Bald Eagle:

>> What you're multiplying is YVal, not U.
>> What you're debug-outputting is YVal rounded to 0 decimals, not YVal
>> (nor U, for that matter).
> 
> Well what I'm comparing the loop integer to is max(0, U*Ustep) [see far below],
> and it's crapping out right out of the gate.

Well, that's not the code you posted.

...

> My #debug output - those are macros - it's rounding to 3 decimals (see above),
> the 0 is a flag for +/- "\n".

Sorry, my bad. Skimming over the code, I had recognized the structure
typical for a `#debug` with invocations of `str()`, not realizing you
invoked something else entirely.

Still, 3 decimals is far below the precision of POV-Ray's float equality
tests.


Given your code, I'm pretty confident UArray[0].y will be 0, but from
the salami slices(*) of code you've posted so far, I can't say the same
for YVal; no post in this thread shows me how that value is computed, so
I don't trust it.

(* I hate to provide support for salami code, by the way. It means that
all I have to go by is "dry" code review, which for a meaningful answer
requires high attention to detail, and even then false assumptions or
misunderstandings may creep in and interfere. Give me a minimal complete
scene file to toy around with anytime, where I can easily verify my
assumptions and understandings by adding more `#debug` lines as I go
along. Providing such a scene may be more work on your side, but
probably saves as much work on mine, leaving more time for me to do
other POV-Ray related stuff.)


Post a reply to this message

From: Bald Eagle
Subject: Re: <no subject>
Date: 14 Sep 2018 18:00:07
Message: <web.5b9bf6c26f92e856c437ac910@news.povray.org>
The wet and juicy version.

I prefer the bologna descriptor.

The offender is
#declare _Y = function (Angle, _M) {min(max(0, Angle * _M), _M)}

where "Angle" goes from 0 to 1.



#######################################################################

#version version;

// floating point comparison debug



#include "colors.inc"

light_source {
 <5, 10, -20>
 color White
 fade_distance 20
 fade_power 2
}

camera {
    location  <0, 2, -35>
    look_at   <0, 0, -10>

    right x*image_width/image_height
    up y
}

//###############################################

#macro Scalar (_Value, _P, _N)
 #local _Result = str(_Value, 0, _P);
 #if(_N) #local _Result = concat (_Result, " \n") #end
 _Result
#end

//###############################################

#macro Vector (_Value, _P, _N)
 #local _Result = concat ("<", vstr(3, _Value, ", ", 0, _P), ">");
 #if(_N) #local _Result = concat (_Result, " \n") #end
 _Result
#end

//###############################################
//------------------------------------------------------------------------------
#declare Round = function (Value) {ceil(Value - 0.5)}
//------------------------------------------------------------------------------
// Fast NChooseM
#declare FastNCM = function (n, k) {prod(i, k+1, n, i) / prod(i, 1, n-k, i)}

#declare PowerFn = function(s, p) { select(p, pow(s, p), 1, pow(s, p)) }
//------------------------------------------------------------------------------
#declare Bernstein = function (Deg, K, S)
{FastNCM(Deg, K) * PowerFn(S, K) * PowerFn (1 - S, Deg - K)}

//------------------------------------------------------------------------------
#macro Point (VG, UG, Uc, Vc)   // called during interpolation loop due to using
Current [V][U] array
 //#debug concat(Scalar(VG, 0, 0), ", ", Scalar(UG, 0, 1), "\n")
#local Degree = 3;
 #local P =
 #for (j, 0, 3)
  #for (i, 0, 3)
  //#debug concat(Scalar(VG, 0, 0), ", ", Scalar(UG, 0, 0), ", ", Scalar(i, 0,
0), ", ", Scalar(j, 0, 1), "\n")
  Bernstein(Degree, i, Vc) * Bernstein(Degree, j, Uc) * StitchedArray
[VG][UG][i][j] +
  #end
 #end
 0;
 P
#end
//------------------------------------------------------------------------------

#declare Curve = true;

#declare R1 = 10;   //
#declare R2 = 4;   //
#declare Sum = R1+R2;  //

#declare U1 = 0;   // small radius
#declare U2 = 2*pi;   //
#declare V1 = 0;   // large radius
#declare V2 = 2*pi;   //
#declare r0 = R1;
#declare r1 = R2;
//#declare Phi = U1;
#declare   Phi_inc = (2*pi/360)*60;
#declare Theta_inc = (2*pi/360)*20;


#debug "Creating arrays... \n"

// Create an array to hold all of the Bezier patches to cover the surface
#declare Usize = Round ((U2-U1)/Phi_inc)+1;
#declare Vsize = Round((V2-V1)/Theta_inc);
#debug concat ("Usize = ", str(Usize, 0, 3), ",   Vsize = ", str(Vsize, 0, 3),
"\n")


#declare UU = Usize-1;
#declare VV = Vsize-1;

#debug concat ("UU = ", str(UU, 0, 3), ",   VV = ", str(VV, 0, 3), "\n")

#declare UArray = array [Usize+1];
#declare VArray = array [Vsize+1];

#debug concat ("UArray extends from 0 to ", str(dimension_size(UArray,1)-1, 0,
3), " \n")
#debug concat ("VArray extends from 0 to ", str(dimension_size(VArray,1)-1, 0,
3), " \n")

#declare StitchedArray = array[Vsize][Usize];

#for (U, 0, UU)
 #for (V, 0, VV)
  #local StitchedArray [V][U] = array[4][4];
 #end

#end

#debug concat ("StitchedArray is ", str(dimension_size(StitchedArray, 1)-1, 0,
3), " x ", str(dimension_size(StitchedArray, 2)-1, 0, 3), " elements \n\n")

//----------------------------------------------------


#declare Ustep = (U2-U1)/(UU);
#declare Vstep = (V2-V1)/(VV);

#debug concat ("UStep = U2 (", Scalar (U2, 5, 0), ") - U1 (", Scalar (U1, 5, 0),
") / Usize (", Scalar (Usize, 5, 0), ") = ", Scalar (Ustep, 5, 1))
#debug concat ("VStep = V2 (", Scalar (V2, 5, 0), ") - V1 (", Scalar (V1, 5, 0),
") / Vsize (", Scalar (Vsize, 5, 0), ") = ", Scalar (Vstep, 5, 1))

#debug "\n\n"

#for (U, 0, UU)     // must be UU because SitchedArray is only that big
 #declare UArray [U] = <U, max(0, U*Ustep), min((U+1)*Ustep, U2)>;
 //#debug concat ("UArray [", Scalar (U, 0, 0), "] = ", Vector (UArray [U], 5,
1))
#end

#for (V, 0, VV) // must be VV because SitchedArray is only that big
 #declare VArray [V] = <V, max(0, V*Vstep), min((V+1)*Vstep, V2)>;
 //#debug concat ("VArray [", Scalar (V, 0, 0), "] = ", Vector (VArray [V], 5,
1))
#end

//----------------------------------------------------

// Determines the Bezier patch in the 2D array that the function coordinates
fall on
#macro ThisPatch (XVal, YVal)
    #local Mult = 1000;

    //#local _Patch = <0, 0>;
    #local _Patch = array [6];

    #for (U, 0, Usize)
        #debug concat ("Testing Y = ", Scalar (YVal, 3, 0), " vs ", Vector
(UArray [U], 3, 0), " \n")
        #if ( int(YVal*Mult) >= int(UArray [U].y*Mult) & int(YVal*Mult) <=
int(UArray [U].z*Mult) )

        #local _Patch [0] = UArray [U].x;
        #local _Patch [1] = UArray [U].y;
        #local _Patch [2] = UArray [U].z;
        #end
    #end

    #ifndef (_Patch [0]) #debug "_Patch [0] U not defined \n" #end

    #for (V, 0, Vsize)
    #debug concat ("Testing X = ", Scalar (XVal, 3, 0), " vs ", Vector (VArray
[V], 3, 0), " \n")
        #if (XVal >= VArray [V].y & XVal <= VArray [V].z)

        #local _Patch [3] = VArray [V].x;
        #local _Patch [4] = VArray [V].y;
        #local _Patch [5] = VArray [V].z;
        #end
    #end

    #ifndef (_Patch [3]) #debug "_Patch [3] V not defined \n" #end

    _Patch
#end

//-----------------------------------------------------------
#macro Vector4 (_Value, _P, _N)
 #local _Result = concat ("<", vstr(4, _Value, ", ", 0, _P), ">");
 #if(_N) #local _Result = concat (_Result, " \n") #end
 _Result
#end
//-----------------------------------------------------------

// Determines where on individual Bezier patch function coordinates are
#macro PatchUV (XVal, YVal)
    #local Range = ThisPatch (XVal, YVal);
    #local ThisU = (YVal - Range [1]) / (Range [2]- Range [1]);
    #local ThisV = (XVal - Range [4]) / (Range [5]- Range [4]);
    #local _Result = <Range [3], Range [0], ThisV, ThisU>;
    //#debug Vector4 (_Result, 3, 1)
 _Result

#end


#if (Curve)

    #declare N = 5;
 #declare _X = function (_N, Angle, _M) {min (_N*mod(Angle, 1/_N) * _M, _M)}
 #declare _Y = function (Angle, _M) {min(max(0, Angle * _M), _M)}


 #declare F = 1.0000001; // LastPoint multiplier to avoid [most] degenerate
cylinders
 #for (Theta, 0, 1, 0.001)

  #debug concat ("_X = ", Scalar (_X(N, Theta, Vsize), 5, 0), ", _Y = ", Scalar
(_Y(Theta, Usize), 5, 1))

  #local UV = PatchUV ( _X(N, Theta, Vsize), _Y(Theta, Usize) );
  // this converts the points to 'flat' UV, but now they need to be converted to
the interpolated Bezier coordinates
  #local CurrentPoint = Point (UV.x, UV.y, UV.z, UV.t);
  //#debug Vector (Point, 3, 1)
  //#debug Vector (UV, 3, 1)
  sphere {CurrentPoint Radius pigment {White*Theta}}
  #if (Theta > 0)
   cylinder {LastPoint*F, CurrentPoint, Radius texture {CurveTex} }
  #end
  #local LastPoint = CurrentPoint;
 #end

#end


Post a reply to this message

From: clipka
Subject: Re: <no subject>
Date: 14 Sep 2018 19:55:45
Message: <5b9c1241$1@news.povray.org>
Am 14.09.2018 um 19:58 schrieb Bald Eagle:
> The wet and juicy version.
> 
> I prefer the bologna descriptor.
> 
> The offender is
> #declare _Y = function (Angle, _M) {min(max(0, Angle * _M), _M)}
> 
> where "Angle" goes from 0 to 1.

That's not what i see.

What I see (after fixing some line-wrapped comments) is an error
encountering "srgb" before "assumed_gamma".

When that is fixed (by not including colors.inc and instead defining
"White" manually), I get an error in

    #debug concat ("Testing Y = ", Scalar (YVal, 3, 0), " vs ", Vector
(UArray [U], 3, 0), " \n")

where U reaches 7.

Which is not surprising, since you have

    #for (U, 0, Usize)

while the array is only Usize elements long, from 0 to Usize-1.


Post a reply to this message

From: clipka
Subject: Re: <no subject>
Date: 14 Sep 2018 20:03:02
Message: <5b9c13f6$1@news.povray.org>
Am 14.09.2018 um 21:55 schrieb clipka:

> Which is not surprising, since you have
> 
>     #for (U, 0, Usize)
> 
> while the array is only Usize elements long, from 0 to Usize-1.

Sorry, that's an imprecise observation; the array is Usize+1 elements
long, so it has space for elements from 0 to Usize. But you're only
initializing elements from 0 to UU, with UU = Usize-1, so element Usize
remains uninitialized.


Post a reply to this message

Goto Latest 10 Messages Next 8 Messages >>>

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