1. New proposal for math.e

This is my new proposal for a "math.e" standard include file,
according to the recent discussion on this forum.

Changes compared to the previous version:
- All constant values are now truncated after the 17th digit
  (according to Matt's explanation about precision).
- Double-checked all constant values by using a third-party
  calculator (--> no changes).
- No user-defined type checking of the last parameter anymore in
  functions find_least(), find_greatest(), least(), greatest()
  ( with an invalid parameter, the functions will crash anyway --
    with or without type-checking smile ).
  Removed the concerning user-defined type.
- Simplified function log10() by using sequence operations.
- Changed the names deg() and rad() to radians_to_degrees() and
  degrees_to_radians(), respectively.

global constant
   LN2        = 0.6931471805599453,
   LN10       = 2.3025850929940456,
   E          = 2.7182818284590452,
   SQRT2      = 1.4142135623730950,
   HALF_SQRT2 = 0.7071067811865475,
   PI         = 3.1415926535897932,
   HALF_PI    = 1.5707963267948966,
   QUARTER_PI = 0.7853981633974483,
   TWO_PI     = 6.2831853071795864


global function log2 (object x)
   -- logarithm base 2
   -- in : (sequence of) real number(s) > 0
   -- out: (sequence of) real number(s)
   -- Note: This function returns _exact_ results for all integral
   --       powers of 2 in the half-closed interval ]0,#FFFFFFFF]

   if atom(x) then
      if x = #20000000 then
         return 29
      elsif x = #80000000 then
         return 31
      else 
         return log(x)/LN2
      end if
   end if

   for i = 1 to length(x) do
      x[i] = log2(x[i])
   end for
   return x
end function

global function log10 (object x)
   -- logarithm base 10
   -- in : (sequence of) real number(s) > 0
   -- out: (sequence of) real number(s)

   return log(x)/LN10
end function

global function exp (object x)
   return power(E, x)
end function

global function sinh (object x)
   return (exp(x) - exp(-x)) / 2
end function

global function cosh (object x)
   return (exp(x) + exp(-x)) / 2
end function

global function tanh (object x)
   return sinh(x) / cosh(x)
end function

global function arcsinh (object x)
   return log(x + sqrt(x*x+1))
end function

type not_below_1 (object x)
   if atom(x) then
      return x >= 1.0
   end if

   for i = 1 to length(x) do
      if not not_below_1(x[i]) then
         return 0
      end if
   end for
   return 1
end type

global function arccosh (not_below_1 x)
   return log(x + sqrt(x*x-1))
end function

type abs_below_1 (object x)
   if atom(x) then
      return x > -1.0 and x < 1.0
   end if

   for i = 1 to length(x) do
      if not abs_below_1(x[i]) then
         return 0
      end if
   end for
   return 1
end type

global function arctanh (abs_below_1 x)
   return log((1+x)/(1-x)) / 2
end function

global function abs (object x)
   -- return the absolute value of (all elements of) x

   if atom(x) then
      if x < 0 then
         return -x
      else
         return x
      end if
   end if

   for i = 1 to length(x) do
      x[i] = abs(x[i])
   end for
   return x
end function

global function sign (object x)
   --  x < 0  ==>  -1
   --  x = 0  ==>   0
   --  x > 0  ==>  +1

   if atom(x) then
      return compare(x, 0)
   end if

   for i = 1 to length(x) do
      x[i] = sign(x[i])
   end for
   return x
end function

global function ceil (object x)
   -- the opposite of floor()
   -- Examples: ? ceil(3.2)          --> 4
   --           ? ceil({-3.2,7,1.6}) --> {-3,7,2}

   return -floor(-x)
end function

global function sum (sequence list)
   -- Return the sum of all elements in 'list'.
   -- Note: This does not do a recursive sum of sub-sequences.
   atom ret

   ret = 0
   for i = 1 to length(list) do
      ret += list[i]
   end for
   return ret
end function

global function find_least (sequence list, integer start)
   -- Search for the lowest value in 'list', beginning at index 'start'.
   -- Return the index of that element.
   -- Notes: This does not do a recursive compare on sub-sequences.
   --        An empty sequence will cause a runtime error.
   object temp
   integer ret

   temp = list[start]
   ret = start
   for i = start+1 to length(list) do
      if compare(temp, list[i]) = 1 then
         temp = list[i]
         ret = i
      end if
   end for
   return ret
end function

global function find_greatest (sequence list, integer start)
   -- Search for the greatest value in 'list', beginning at index 'start'.
   -- Return the index of that element.
   -- Notes: This does not do a recursive compare on sub-sequences.
   --        An empty sequence will cause a runtime error.
   object temp
   integer ret

   temp = list[start]
   ret = start
   for i = start+1 to length(list) do
      if compare(temp, list[i]) = -1 then
         temp = list[i]
         ret = i
      end if
   end for
   return ret
end function

global function least (sequence list, integer start)
   -- Search for the lowest value in 'list', beginning at index 'start'.
   -- Return the value of that element.
   -- Notes: This does not do a recursive compare on sub-sequences.
   --        An empty sequence will cause a runtime error.
   object ret

   ret = list[start]
   for i = start+1 to length(list) do
      if compare(ret, list[i]) = 1 then
         ret = list[i]
      end if
   end for
   return ret
end function

global function greatest (sequence list, integer start)
   -- Search for the greatest value in 'list', beginning at index 'start'.
   -- Return the value of that element.
   -- Notes: This does not do a recursive compare on sub-sequences.
   --        An empty sequence will cause a runtime error.
   object ret

   ret = list[start]
   for i = start+1 to length(list) do
      if compare(ret, list[i]) = -1 then
         ret = list[i]
      end if
   end for
   return ret
end function

global function lesser (object x1, object x2)
   -- Return the argument with the lesser value.
   -- Note: This does not do a recursive compare on sub-sequences.

   if compare(x1, x2) <= 0 then
      return x1
   else
      return x2
   end if
end function

global function greater (object x1, object x2)
   -- Return the argument with the greater value.
   -- Note: This does not do a recursive compare on sub-sequences.

   if compare(x1, x2) >= 0 then
      return x1
   else
      return x2
   end if
end function

global function radians_to_degrees (object x)
   -- in : (sequence of) angle(s) in radians
   -- out: (sequence of) angle(s) in degrees

   return x/PI * 180.0
end function

global function degrees_to_radians (object x)
   -- in : (sequence of) angle(s) in degrees
   -- out: (sequence of) angle(s) in radians

   return x/180.0 * PI
end function

type trig_range (object x)
   --  values passed to arccos and arcsin must be [-1,+1]
   if atom(x) then
      return x >= -1 and x <= 1
   end if

   for i = 1 to length(x) do
      if not trig_range(x[i]) then
         return 0
      end if
   end for
   return 1
end type

global function arcsin (trig_range x)
   -- returns angle in radians
   return 2 * arctan(x / (1.0 + sqrt(1.0 - x * x)))
end function

global function arccos (trig_range x)
   -- returns angle in radians
   return HALF_PI - 2 * arctan(x / (1.0 + sqrt(1.0 - x * x)))
end function

Regards,
   Juergen

new topic     » topic index » view message » categorize

2. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> This is my new proposal for a "math.e" standard include file,
> according to the recent discussion on this forum.

<snip>

global function log2 (object x)
   -- logarithm base 2
   -- in : (sequence of) real number(s) > 0
   -- out: (sequence of) real number(s)
   -- Note: This function returns _exact_ results for all integral
   --       powers of 2 in the half-closed interval ]0,#FFFFFFFF]

   if atom(x) then
      if x = #20000000 then
         return 29
      elsif x = #80000000 then
         return 31
      else 
         return log(x)/LN2
      end if
   end if

   for i = 1 to length(x) do
      x[i] = log2(x[i])
   end for
   return x
end function

 

I'm curious about the special treatment of #20000000 and #80000000 in log2.
I assume that rounding errors give you imprecise answers?  However, I
get the following imprecise results when taking out the special cases:
for i = 0 to 32 do
	printf(1, "%d: %0.16g\n", i & log2( power( 2, i ) ))
end for


0: 0
1: 1
2: 2
3: 3
4: 4.000000000000001
5: 5.000000000000001
6: 6.000000000000001
7: 7.000000000000001
8: 8.000000000000002
9: 9.000000000000002
10: 10
11: 11
12: 12
13: 13
14: 14
15: 15
16: 16
17: 17
18: 18
19: 19
20: 20
21: 21
22: 22
23: 23
24: 24
25: 25.00000000000001
26: 26
27: 27.00000000000001
28: 28
29: 29.00000000000001
30: 30
31: 31.00000000000001
32: 32.00000000000001

new topic     » goto parent     » topic index » view message » categorize

3. Re: New proposal for math.e

Matt Lewis wrote:

> Juergen Luethje wrote:
> > 
> > This is my new proposal for a "math.e" standard include file,
> > according to the recent discussion on this forum.
> 
> <snip>
> 
> }}}
<eucode>
> global function log2 (object x)
>    -- logarithm base 2
>    -- in : (sequence of) real number(s) > 0
>    -- out: (sequence of) real number(s)
>    -- Note: This function returns _exact_ results for all integral
>    --       powers of 2 in the half-closed interval ]0,#FFFFFFFF]
> 
>    if atom(x) then
>       if x = #20000000 then
>          return 29
>       elsif x = #80000000 then
>          return 31
>       else 
>          return log(x)/LN2
>       end if
>    end if
> 
>    for i = 1 to length(x) do
>       x[i] = log2(x[i])
>    end for
>    return x
> end function
> </eucode>
{{{
 
> 
> I'm curious about the special treatment of #20000000 and #80000000 in log2.
> I assume that rounding errors give you imprecise answers?

Yes. When I wrote the function some time ago, only these two x values gave
me imprecise answers, so I was happy that there were not so many special
cases.

> However, I
> get the following imprecise results when taking out the special cases:
> }}}
<eucode>
> for i = 0 to 32 do
> 	printf(1, "%d: %0.16g\n", i & log2( power( 2, i ) ))
> end for
> </eucode>
{{{


[snipped list of values that contains 11 imprecise results]

I think I've found the answer. I have this function since a rather long
time in my private math library, and I copied it into the code proposed
for the Euphoria "math.e" file. In my original code which I had used for
testing, it read
   return log(x)/log(2)

Now, since we had
   constant LN2 = 0.6931471805599453

in "math.e" anyway, I thought it was a good idea to write
   return log(x)/LN2

instead. And as you showed here, that doesn't work as expected.

When I again use
   return log(x)/log(2)
in function log2(), then
for i = 0 to 32 do
	printf(1, "%d: %0.16g\n", i & log2( power( 2, i ) ))
end for

prints
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
10: 10
11: 11
12: 12
13: 13
14: 14
15: 15
16: 16
17: 17
18: 18
19: 19
20: 20
21: 21
22: 22
23: 23
24: 24
25: 25
26: 26
27: 27
28: 28
29: 29
30: 30
31: 31
32: 32

even when I take out the special cases!! smile
I can't exactly remember anymore, but probably I wrote and tested the
function log2() on my old PC (Windows 98, Pentium II processor).
Now I have Windows XP and a Centrino Duo Processor. Is it possible that
the new system makes disappear the imprecise results? At least I currently
have no other idea.

And since in this case it's much better to use log(2) rather than LN2,
maybe that means that it would be better not to provide such constants
in "math.e"? I'm sorry. I have more questions than answers. smile
Thanks for finding this.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

4. Re: New proposal for math.e

Me wrote:

<snip>

> I can't exactly remember anymore, but probably I wrote and tested the
> function log2() on my old PC (Windows 98, Pentium II processor).
> Now I have Windows XP and a Centrino Duo Processor. Is it possible that
> the new system makes disappear the imprecise results? At least I currently
> have no other idea.

<snip>

This doesn't seem to be the reason why. Using the code:
function log2 (atom x)
   return log(x)/log(2)
end function
 
for i = 0 to 32 do
   printf(1, "%d: %0.16g\n", i & log2( power( 2, i ) ))
end for

with the EXW.EXE interpreter 3.0.2, I can't manage to get imprecise results
anymore, neither on my old system nor on my new system.  *LOL*

Maybe I made the tests with an older version of the interpreter, and
something has changed regarding this point (e.g. a different version of
the Watcom compiler was used to build the interpreter)? I only can guess.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

5. Re: New proposal for math.e

Hi Juergen,

As I mentionned it in previous unoticed post, a math.e library should only deal
with numbers. So why find_least() use compare() to compare elements of sequence?
Those elements should be atoms and the relational operator '<' should be used.
You may argue that list may contain sub-sequence of atom, but can you give
exemples were this would be usefull?

What i propose is this:

function find_least(sequence list,integer start)
-- return the smallest element of list where list is sequence of atoms.
-- list must have length(list)>=2
-- but what should we do if length(list)<2, crash!!! ?
atom temp
ineger ret

   temp = s[start]
   ret = start
   for i = start+1 to length(list) do
     if s[i]<temp then
        temp = s[i] 
        ret = i    
     end if
   end for
   return ret
end function

same thing for find_greatest()

regards,
Jacques Deschênes


Juergen Luethje wrote:
> 
> This is my new proposal for a "math.e" standard include file,
> according to the recent discussion on this forum.
> 
> Changes compared to the previous version:
> - All constant values are now truncated after the 17th digit
>   (according to Matt's explanation about precision).
> - Double-checked all constant values by using a third-party
>   calculator (--> no changes).
> - No user-defined type checking of the last parameter anymore in
>   functions find_least(), find_greatest(), least(), greatest()
>   ( with an invalid parameter, the functions will crash anyway --
>     with or without type-checking smile ).
>   Removed the concerning user-defined type.
> - Simplified function log10() by using sequence operations.
> - Changed the names deg() and rad() to radians_to_degrees() and
>   degrees_to_radians(), respectively.
> 
> }}}
<eucode>
> global constant
>    LN2        = 0.6931471805599453,
>    LN10       = 2.3025850929940456,
>    E          = 2.7182818284590452,
>    SQRT2      = 1.4142135623730950,
>    HALF_SQRT2 = 0.7071067811865475,
>    PI         = 3.1415926535897932,
>    HALF_PI    = 1.5707963267948966,
>    QUARTER_PI = 0.7853981633974483,
>    TWO_PI     = 6.2831853071795864
> 
> 
> global function log2 (object x)
>    -- logarithm base 2
>    -- in : (sequence of) real number(s) > 0
>    -- out: (sequence of) real number(s)
>    -- Note: This function returns _exact_ results for all integral
>    --       powers of 2 in the half-closed interval ]0,#FFFFFFFF]
> 
>    if atom(x) then
>       if x = #20000000 then
>          return 29
>       elsif x = #80000000 then
>          return 31
>       else 
>          return log(x)/LN2
>       end if
>    end if
> 
>    for i = 1 to length(x) do
>       x[i] = log2(x[i])
>    end for
>    return x
> end function
> 
> global function log10 (object x)
>    -- logarithm base 10
>    -- in : (sequence of) real number(s) > 0
>    -- out: (sequence of) real number(s)
> 
>    return log(x)/LN10
> end function
> 
> global function exp (object x)
>    return power(E, x)
> end function
> 
> global function sinh (object x)
>    return (exp(x) - exp(-x)) / 2
> end function
> 
> global function cosh (object x)
>    return (exp(x) + exp(-x)) / 2
> end function
> 
> global function tanh (object x)
>    return sinh(x) / cosh(x)
> end function
> 
> global function arcsinh (object x)
>    return log(x + sqrt(x*x+1))
> end function
> 
> type not_below_1 (object x)
>    if atom(x) then
>       return x >= 1.0
>    end if
> 
>    for i = 1 to length(x) do
>       if not not_below_1(x[i]) then
>          return 0
>       end if
>    end for
>    return 1
> end type
> 
> global function arccosh (not_below_1 x)
>    return log(x + sqrt(x*x-1))
> end function
> 
> type abs_below_1 (object x)
>    if atom(x) then
>       return x > -1.0 and x < 1.0
>    end if
> 
>    for i = 1 to length(x) do
>       if not abs_below_1(x[i]) then
>          return 0
>       end if
>    end for
>    return 1
> end type
> 
> global function arctanh (abs_below_1 x)
>    return log((1+x)/(1-x)) / 2
> end function
> 
> global function abs (object x)
>    -- return the absolute value of (all elements of) x
> 
>    if atom(x) then
>       if x < 0 then
>          return -x
>       else
>          return x
>       end if
>    end if
> 
>    for i = 1 to length(x) do
>       x[i] = abs(x[i])
>    end for
>    return x
> end function
> 
> global function sign (object x)
>    --  x < 0  ==>  -1
>    --  x = 0  ==>   0
>    --  x > 0  ==>  +1
> 
>    if atom(x) then
>       return compare(x, 0)
>    end if
> 
>    for i = 1 to length(x) do
>       x[i] = sign(x[i])
>    end for
>    return x
> end function
> 
> global function ceil (object x)
>    -- the opposite of floor()
>    -- Examples: ? ceil(3.2)          --> 4
>    --           ? ceil({-3.2,7,1.6}) --> {-3,7,2}
> 
>    return -floor(-x)
> end function
> 
> global function sum (sequence list)
>    -- Return the sum of all elements in 'list'.
>    -- Note: This does not do a recursive sum of sub-sequences.
>    atom ret
> 
>    ret = 0
>    for i = 1 to length(list) do
>       ret += list[i]
>    end for
>    return ret
> end function
> 
> global function find_least (sequence list, integer start)
>    -- Search for the lowest value in 'list', beginning at index 'start'.
>    -- Return the index of that element.
>    -- Notes: This does not do a recursive compare on sub-sequences.
>    --        An empty sequence will cause a runtime error.
>    object temp
>    integer ret
> 
>    temp = list[start]
>    ret = start
>    for i = start+1 to length(list) do
>       if compare(temp, list[i]) = 1 then
>          temp = list[i]
>          ret = i
>       end if
>    end for
>    return ret
> end function
> 
> global function find_greatest (sequence list, integer start)
>    -- Search for the greatest value in 'list', beginning at index 'start'.
>    -- Return the index of that element.
>    -- Notes: This does not do a recursive compare on sub-sequences.
>    --        An empty sequence will cause a runtime error.
>    object temp
>    integer ret
> 
>    temp = list[start]
>    ret = start
>    for i = start+1 to length(list) do
>       if compare(temp, list[i]) = -1 then
>          temp = list[i]
<snip>

new topic     » goto parent     » topic index » view message » categorize

6. Re: New proposal for math.e

my new version of find_least() and find_greatest()

global function find_least(sequence list, integer start)
-- return the index of the smallest element of flat sequence list
-- starting comparison at index start
-- if start<1 or start > length(list) generate a runtime error.
atom temp
integer ret
  
   temp = list[start]
   ret = start
   for i = start+1 to length(list) do
     if list[i] < temp then
       temp = list[i]
       ret = i
     end if
   end for
   return ret
end function

function find_greatest(sequence list, integer start)
-- return the index of largest element of flat sequence list
-- begin comparison at start position.
-- if start < 1 or start > length(list) generate a runtime error
atom temp
integer ret

   temp = list[start]
   ret = start
   for i = start+1 to length(list) do
     if list[i]>temp then
       temp = list[i]
       ret = i
     end if
   end for
   return ret
end function









jacques deschênes wrote:
> 
> Hi Juergen,
> 
> As I mentionned it in previous unoticed post, a math.e library should only
> deal
> with numbers. So why find_least() use compare() to compare elements of
> sequence?
> Those elements should be atoms and the relational operator '<' should be
> used.
> You may argue that list may contain sub-sequence of atom, but can you give
> exemples
> were this would be usefull?
> 
> What i propose is this:
> 
> }}}
<eucode>
> function find_least(sequence list,integer start) 
> -- return the smallest element of list where list is sequence of atoms.
> -- list must have length(list)>=2
> -- but what should we do if length(list)<2, crash!!! ?
> atom temp
> ineger ret
> 
>    temp = s[start]
>    ret = start
>    for i = start+1 to length(list) do
>      if s[i]<temp then
>         temp = s[i] 
>         ret = i    
>      end if
>    end for
>    return ret
> end function
> </eucode>
{{{

> same thing for find_greatest()
> 
> regards,
> Jacques Deschênes
> 
> 
> Juergen Luethje wrote:
> > 
> > This is my new proposal for a "math.e" standard include file,
> > according to the recent discussion on this forum.
> > 
> > Changes compared to the previous version:
> > - All constant values are now truncated after the 17th digit
> >   (according to Matt's explanation about precision).
> > - Double-checked all constant values by using a third-party
> >   calculator (--> no changes).
> > - No user-defined type checking of the last parameter anymore in
> >   functions find_least(), find_greatest(), least(), greatest()
> >   ( with an invalid parameter, the functions will crash anyway --
> >     with or without type-checking smile ).
> >   Removed the concerning user-defined type.
> > - Simplified function log10() by using sequence operations.
> > - Changed the names deg() and rad() to radians_to_degrees() and
> >   degrees_to_radians(), respectively.
> > 
> > }}}
<eucode>
> > global constant
> >    LN2        = 0.6931471805599453,
> >    LN10       = 2.3025850929940456,
> >    E          = 2.7182818284590452,
> >    SQRT2      = 1.4142135623730950,
> >    HALF_SQRT2 = 0.7071067811865475,
> >    PI         = 3.1415926535897932,
> >    HALF_PI    = 1.5707963267948966,
> >    QUARTER_PI = 0.7853981633974483,
> >    TWO_PI     = 6.2831853071795864
> > 
> > 
> > global function log2 (object x)
> >    -- logarithm base 2
> >    -- in : (sequence of) real number(s) > 0
> >    -- out: (sequence of) real number(s)
> >    -- Note: This function returns _exact_ results for all integral
> >    --       powers of 2 in the half-closed interval ]0,#FFFFFFFF]
> > 
> >    if atom(x) then
> >       if x = #20000000 then
> >          return 29
> >       elsif x = #80000000 then
> >          return 31
> >       else 
> >          return log(x)/LN2
> >       end if
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       x[i] = log2(x[i])
> >    end for
> >    return x
> > end function
> > 
> > global function log10 (object x)
> >    -- logarithm base 10
> >    -- in : (sequence of) real number(s) > 0
> >    -- out: (sequence of) real number(s)
> > 
> >    return log(x)/LN10
> > end function
> > 
> > global function exp (object x)
> >    return power(E, x)
> > end function
> > 
> > global function sinh (object x)
> >    return (exp(x) - exp(-x)) / 2
> > end function
> > 
> > global function cosh (object x)
> >    return (exp(x) + exp(-x)) / 2
> > end function
> > 
> > global function tanh (object x)
> >    return sinh(x) / cosh(x)
> > end function
> > 
> > global function arcsinh (object x)
> >    return log(x + sqrt(x*x+1))
> > end function
> > 
> > type not_below_1 (object x)
> >    if atom(x) then
> >       return x >= 1.0
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       if not not_below_1(x[i]) then
> >          return 0
> >       end if
> >    end for
> >    return 1
> > end type
> > 
> > global function arccosh (not_below_1 x)
> >    return log(x + sqrt(x*x-1))
> > end function
> > 
> > type abs_below_1 (object x)
> >    if atom(x) then
> >       return x > -1.0 and x < 1.0
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       if not abs_below_1(x[i]) then
> >          return 0
> >       end if
> >    end for
> >    return 1
> > end type
> > 
> > global function arctanh (abs_below_1 x)
> >    return log((1+x)/(1-x)) / 2
> > end function
> > 
> > global function abs (object x)
> >    -- return the absolute value of (all elements of) x
> > 
> >    if atom(x) then
> >       if x < 0 then
> >          return -x
> >       else
> >          return x
> >       end if
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       x[i] = abs(x[i])
> >    end for
> >    return x
> > end function
> > 
> > global function sign (object x)
> >    --  x < 0  ==>  -1
> >    --  x = 0  ==>   0
> >    --  x > 0  ==>  +1
> > 
> >    if atom(x) then
> >       return compare(x, 0)
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       x[i] = sign(x[i])
> >    end for
> >    return x
> > end function
> > 
> > global function ceil (object x)
> >    -- the opposite of floor()
> >    -- Examples: ? ceil(3.2)          --> 4
> >    --           ? ceil({-3.2,7,1.6}) --> {-3,7,2}
> > 
> >    return -floor(-x)
> > end function
> > 
> > global function sum (sequence list)
> >    -- Return the sum of all elements in 'list'.
> >    -- Note: This does not do a recursive sum of sub-sequences.
> >    atom ret
> > 
> >    ret = 0
<snip>

new topic     » goto parent     » topic index » view message » categorize

7. Re: New proposal for math.e

Hi All,

I would like that Euphoria could be easily used by all programmers in the world,
in particular, not only for English speakers. To minimize the learning
effort to non-English speakers, I suggest to take into consideration:

1) Choose the most international known word that can be used to describe its
  intention;
  2) Use the minimum quantity of characters that still makes sense;

In particular, I think the functions "greatest", "greater", "lesser", etc. are
much less international than "max", "max2", "min2" proposed initially by
Juergen. Also, in many equipments, datasheets, specifications, even in other
languages, use the same words: min, max, ...
In case of mathematical functions, I think a good source is electronic
calculators and other computer languages.
The item 2, improves the efficiency in reading, writing and debugging the code,
reducing several costs and helps the item 1 in increasing
the probability that several languages start with (or have) the same letters
(Ex.: maximum = maximo(Portuguese), maximum (French), ...)

Regards,
   Fernando

new topic     » goto parent     » topic index » view message » categorize

8. Re: New proposal for math.e

jacques deschênes wrote:
> 
> Hi Juergen,
> 
> As I mentionned it in previous unoticed post, a math.e library should only
> deal
> with numbers. 

I completely disagree as a professional mathematician.

> So why find_least() use compare() to compare elements of sequence?
> Those elements should be atoms and the relational operator '<' should be
> used.
> You may argue that list may contain sub-sequence of atom, but can you give
> exemples
> were this would be usefull?
> 

Further, currently all Euphoria math operations work on sequences of any shape.
sqrt(), sin(), arctan(), you name it.

As a result I strongly oppose separation between atoms and sequences in this
area.

CChris

> What i propose is this:
> 
> }}}
<eucode>
> function find_least(sequence list,integer start) 
> -- return the smallest element of list where list is sequence of atoms.
> -- list must have length(list)>=2
> -- but what should we do if length(list)<2, crash!!! ?
> atom temp
> ineger ret
> 
>    temp = s[start]
>    ret = start
>    for i = start+1 to length(list) do
>      if s[i]<temp then
>         temp = s[i] 
>         ret = i    
>      end if
>    end for
>    return ret
> end function
> </eucode>
{{{

> same thing for find_greatest()
> 
> regards,
> Jacques Deschênes
> 
> 
> Juergen Luethje wrote:
> > 
> > This is my new proposal for a "math.e" standard include file,
> > according to the recent discussion on this forum.
> > 
> > Changes compared to the previous version:
> > - All constant values are now truncated after the 17th digit
> >   (according to Matt's explanation about precision).
> > - Double-checked all constant values by using a third-party
> >   calculator (--> no changes).
> > - No user-defined type checking of the last parameter anymore in
> >   functions find_least(), find_greatest(), least(), greatest()
> >   ( with an invalid parameter, the functions will crash anyway --
> >     with or without type-checking smile ).
> >   Removed the concerning user-defined type.
> > - Simplified function log10() by using sequence operations.
> > - Changed the names deg() and rad() to radians_to_degrees() and
> >   degrees_to_radians(), respectively.
> > 
> > }}}
<eucode>
> > global constant
> >    LN2        = 0.6931471805599453,
> >    LN10       = 2.3025850929940456,
> >    E          = 2.7182818284590452,
> >    SQRT2      = 1.4142135623730950,
> >    HALF_SQRT2 = 0.7071067811865475,
> >    PI         = 3.1415926535897932,
> >    HALF_PI    = 1.5707963267948966,
> >    QUARTER_PI = 0.7853981633974483,
> >    TWO_PI     = 6.2831853071795864
> > 
> > 
> > global function log2 (object x)
> >    -- logarithm base 2
> >    -- in : (sequence of) real number(s) > 0
> >    -- out: (sequence of) real number(s)
> >    -- Note: This function returns _exact_ results for all integral
> >    --       powers of 2 in the half-closed interval ]0,#FFFFFFFF]
> > 
> >    if atom(x) then
> >       if x = #20000000 then
> >          return 29
> >       elsif x = #80000000 then
> >          return 31
> >       else 
> >          return log(x)/LN2
> >       end if
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       x[i] = log2(x[i])
> >    end for
> >    return x
> > end function
> > 
> > global function log10 (object x)
> >    -- logarithm base 10
> >    -- in : (sequence of) real number(s) > 0
> >    -- out: (sequence of) real number(s)
> > 
> >    return log(x)/LN10
> > end function
> > 
> > global function exp (object x)
> >    return power(E, x)
> > end function
> > 
> > global function sinh (object x)
> >    return (exp(x) - exp(-x)) / 2
> > end function
> > 
> > global function cosh (object x)
> >    return (exp(x) + exp(-x)) / 2
> > end function
> > 
> > global function tanh (object x)
> >    return sinh(x) / cosh(x)
> > end function
> > 
> > global function arcsinh (object x)
> >    return log(x + sqrt(x*x+1))
> > end function
> > 
> > type not_below_1 (object x)
> >    if atom(x) then
> >       return x >= 1.0
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       if not not_below_1(x[i]) then
> >          return 0
> >       end if
> >    end for
> >    return 1
> > end type
> > 
> > global function arccosh (not_below_1 x)
> >    return log(x + sqrt(x*x-1))
> > end function
> > 
> > type abs_below_1 (object x)
> >    if atom(x) then
> >       return x > -1.0 and x < 1.0
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       if not abs_below_1(x[i]) then
> >          return 0
> >       end if
> >    end for
> >    return 1
> > end type
> > 
> > global function arctanh (abs_below_1 x)
> >    return log((1+x)/(1-x)) / 2
> > end function
> > 
> > global function abs (object x)
> >    -- return the absolute value of (all elements of) x
> > 
> >    if atom(x) then
> >       if x < 0 then
> >          return -x
> >       else
> >          return x
> >       end if
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       x[i] = abs(x[i])
> >    end for
> >    return x
> > end function
> > 
> > global function sign (object x)
> >    --  x < 0  ==>  -1
> >    --  x = 0  ==>   0
> >    --  x > 0  ==>  +1
> > 
> >    if atom(x) then
> >       return compare(x, 0)
> >    end if
> > 
> >    for i = 1 to length(x) do
> >       x[i] = sign(x[i])
> >    end for
> >    return x
> > end function
> > 
> > global function ceil (object x)
> >    -- the opposite of floor()
> >    -- Examples: ? ceil(3.2)          --> 4
> >    --           ? ceil({-3.2,7,1.6}) --> {-3,7,2}
> > 
> >    return -floor(-x)
> > end function
> > 
> > global function sum (sequence list)
> >    -- Return the sum of all elements in 'list'.
> >    -- Note: This does not do a recursive sum of sub-sequences.
> >    atom ret
> > 
> >    ret = 0
> >    for i = 1 to length(list) do
> >       ret += list[i]
> >    end for
> >    return ret
> > end function
> > 
> > global function find_least (sequence list, integer start)
> >    -- Search for the lowest value in 'list', beginning at index 'start'.
> >    -- Return the index of that element.
> >    -- Notes: This does not do a recursive compare on sub-sequences.
<snip>

new topic     » goto parent     » topic index » view message » categorize

9. Re: New proposal for math.e

Fernando Bauer wrote:
>   2) Use the minimum quantity of characters that still makes sense;
> In particular, I think the functions "greatest", "greater", "lesser", etc. are
> much less international than "max", "max2", "min2" proposed initially by
> Juergen. Also, in many equipments, datasheets, specifications, even in other
> languages, use the same words: min, max, ... 
> In case of mathematical functions, I think a good source is electronic
> calculators
> and other computer languages.

I prefer min/max to least/greatest.

Regards,

Salix
(a native Hungarian speaker)
(a very lazy typer)

new topic     » goto parent     » topic index » view message » categorize

10. Re: New proposal for math.e

Fernando Bauer wrote:

> Hi All,
> 
> I would like that Euphoria could be easily used by all programmers in the
> world,
> in particular, not only for English speakers. To minimize the learning
> effort to non-English speakers, I suggest to take into consideration:
> 
>   1) Choose the most international known word that can be used to describe its
> intention;
>   2) Use the minimum quantity of characters that still makes sense;
> 
> In particular, I think the functions "greatest", "greater", "lesser", etc. are
> much less international than "max", "max2", "min2" proposed initially by
> Juergen. Also, in many equipments, datasheets, specifications, even in other
> languages, use the same words: min, max, ... 
> In case of mathematical functions, I think a good source is electronic
> calculators
> and other computer languages.
> The item 2, improves the efficiency in reading, writing and debugging the
> code,
> reducing several costs and helps the item 1 in increasing
> the probability that several languages start with (or have) the same letters
> (Ex.: maximum = maximo(Portuguese), maximum (French), ...)

I think these are good arguments, but other people don't like those names.
So I personally don't know what we should do now ... sad

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

11. Re: New proposal for math.e

Me wrote:

<snip>

> Using the code:
> }}}
<eucode>
> function log2 (atom x)
>    return log(x)/log(2)
> end function
>  
> for i = 0 to 32 do
>    printf(1, "%d: %0.16g\n", i & log2( power( 2, i ) ))
> end for
> </eucode>
{{{

> with the EXW.EXE interpreter 3.0.2, I can't manage to get imprecise results
> anymore, neither on my old system nor on my new system.  *LOL*

<snip>

I think know I've found the explanation.
Matt, when I had tested my log2() function, I probably had used a different
way than you to look for imprecise results. Please test this:
function log2 (atom x)
   return log(x)/log(2)
end function
 
for i = 0 to 32 do
   if i != log2( power( 2, i ) ) then
      printf(1, "%d: %0.16g\n", i & log2( power( 2, i ) ))
   end if
end for

On my system, this prints (using EXW.EXE 3.0.2):
29: 29
31: 31
These are the two cases that I treated specially in my proposal for
"math.e".

So it seems that for i = 29 and for i = 31, the results of log2() are
not equal according to the != operator, but they are (or only look)
equal according to printf() ...

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

12. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> Me wrote:
> 
> <snip>
> 
> > Using the code:
> > }}}
<eucode>
> > function log2 (atom x)
> >    return log(x)/log(2)
> > end function
> >  
> > for i = 0 to 32 do
> >    printf(1, "%d: %0.16g\n", i & log2( power( 2, i ) ))
> > end for
> > </eucode>
{{{

> > with the EXW.EXE interpreter 3.0.2, I can't manage to get imprecise results
> > anymore, neither on my old system nor on my new system.  *LOL*
> 
> <snip>
> 
> I think know I've found the explanation.
> Matt, when I had tested my log2() function, I probably had used a different
> way than you to look for imprecise results. Please test this:

<snip>

> These are the two cases that I treated specially in my proposal for
> "math.e".
> 
> So it seems that for i = 29 and for i = 31, the results of log2() are
> not equal according to the != operator, but they are (or only look)
> equal according to printf() ...

OK, I see the difference now.  Using the straight log/log method, there
is still a difference for 29 and 31.

OTOH, using the constant, the difference for 29 and 31 was in the next to 
least significant bit, making the differences twice as big.  And there 
were many more differences.  Definitely looks like rounding errors.

And by looking at what I got by parsing the constant, I can see that 
by letting the interpreter parse your constant, it loses accuracy.
Below, I've shown the bits of the double gotten in these different
ways:

1: log(2)
2: 0.6931471805599453
3: 0.6931471805599453e0 (using my parser)

1: 1111011110011100010111110111111101000010011101000110 01111111110 0 (-1)
2: 0111011110011100010111110111111101000010011101000110 01111111110 0 (-1)
3: 1111011110011100010111110111111101000010011101000110 01111111110 0 (-1)

This certainly calls into question the other constants, since they might
also be one bit off (probably ok for most applications, but still...)
For log(2), we could just do the calculation on assignment, but that 
doesn't help with the others.  The easiest solution is to use the
float64s, and call machine_func(46,...) on them (to avoid including
machine.e) and putting the human readable value in a comment:
LN2        = machine_func(47, {239,57,250,254,66,46,230,63}),   --
    0.6931471805599453e0
LN10       = machine_func(47, {21,85,181,187,177,107,2,64}),    --
    2.3025850929940456e0
E          = machine_func(47, {105,87,20,139,10,191,5,64}),     --
    2.7182818284590452e0
SQRT2      = machine_func(47, {204,59,127,102,158,160,246,63}), --
    1.4142135623730950e0
HALF_SQRT2 = machine_func(47, {204,59,127,102,158,160,230,63}), --
    0.7071067811865475e0
PI         = machine_func(47, {24,45,68,84,251,33,9,64}),       --
    3.1415926535897932e0
HALF_PI    = machine_func(47, {24,45,68,84,251,33,249,63}),     --
    1.5707963267948966e0
QUARTER_PI = machine_func(47, {24,45,68,84,251,33,233,63}),     --
    0.7853981633974483e0
TWO_PI     = machine_func(47, {24,45,68,84,251,33,25,64})       --
    6.2831853071795864e0


Using the constant for LN2 (as long as it's the *right* one) is probably
faster (I think that's a reasonable assumption), we should probably go
with your original function, but without the special cases.

For a new proposal, I know that we've covered the most common cases, but
how about a logn (or logx?) function for the general case:
global function logn( object x, atom base )


Matt

new topic     » goto parent     » topic index » view message » categorize

13. Re: New proposal for math.e

Matt Lewis wrote:

<snip>

> OK, I see the difference now.  Using the straight log/log method, there
> is still a difference for 29 and 31.
> 
> OTOH, using the constant, the difference for 29 and 31 was in the next to 
> least significant bit, making the differences twice as big.  And there 
> were many more differences.  Definitely looks like rounding errors.
> 
> And by looking at what I got by parsing the constant, I can see that 
> by letting the interpreter parse your constant, it loses accuracy.
> Below, I've shown the bits of the double gotten in these different
> ways:
> 
> 1: log(2)
> 2: 0.6931471805599453
> 3: 0.6931471805599453e0 (using my parser)
> 
> 1: 1111011110011100010111110111111101000010011101000110 01111111110 0 (-1)
> 2: 0111011110011100010111110111111101000010011101000110 01111111110 0 (-1)
> 3: 1111011110011100010111110111111101000010011101000110 01111111110 0 (-1)
> 
> This certainly calls into question the other constants, since they might
> also be one bit off (probably ok for most applications, but still...)
> For log(2), we could just do the calculation on assignment, but that 
> doesn't help with the others.  The easiest solution is to use the
> float64s, and call machine_func(46,...) on them (to avoid including
> machine.e) and putting the human readable value in a comment:
> 
>     LN2        = machine_func(47, {239,57,250,254,66,46,230,63}),   --
>     0.6931471805599453e0
>     LN10       = machine_func(47, {21,85,181,187,177,107,2,64}),    --
>     2.3025850929940456e0
>     E          = machine_func(47, {105,87,20,139,10,191,5,64}),     --
>     2.7182818284590452e0
>     SQRT2      = machine_func(47, {204,59,127,102,158,160,246,63}), --
>     1.4142135623730950e0
>     HALF_SQRT2 = machine_func(47, {204,59,127,102,158,160,230,63}), --
>     0.7071067811865475e0
>     PI         = machine_func(47, {24,45,68,84,251,33,9,64}),       --
>     3.1415926535897932e0
>     HALF_PI    = machine_func(47, {24,45,68,84,251,33,249,63}),     --
>     1.5707963267948966e0
>     QUARTER_PI = machine_func(47, {24,45,68,84,251,33,233,63}),     --
>     0.7853981633974483e0
>     TWO_PI     = machine_func(47, {24,45,68,84,251,33,25,64})       --
>     6.2831853071795864e0
> 
> 
> Using the constant for LN2 (as long as it's the *right* one) is probably
> faster (I think that's a reasonable assumption),

I also think so. When the log2() function uses your new LN2 constant, the
function results seem to have the same precision as if it used log(2).
Very nice!! Also other constants (such as PI), which can not be replaced
by a simple call to a built-in function, are more precise now, which is
very good.

> we should probably go
> with your original function, but without the special cases.

So just the following?
global function log2 (object x)
   return log(x)/LN2
end function

But then we know that we'll get imprecise results for x = 2^29
and x = 2^31. Why shouldn't we avoid that?

> For a new proposal, I know that we've covered the most common cases, but
> how about a logn (or logx?) function for the general case:
> 
> global function logn( object x, atom base ) 

I also have thougt of that. But why not use 'object base' in order to
allow sequence operations, e.g.
? logx({100,32}, {10,2})    -- prints {2,5}

Well, looks good to me, but will actually anyone ever use it? smile

A personal remark according the name:
You certainly know the term "Logarithmus naturalis" for logarithm base E.
Because of this name, the abbreviation for logarithm base E that is used
everywhere in Germany is ln(). So (at least for Germnas) it is already
confusing that Euphoria's built-in function is not named ln(), but log().
(At least for Germans) log() should be the name for the general function
log(x, base).
It's probably too late now to change that, but: An 'n' in a name of a
logarithm function would always make me think of "naturalis". So using
the name logn() for the genaral logarithm function would even increase
the potential for confusion IMHO.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

14. Re: New proposal for math.e

Matt Lewis wrote:
> 
> Juergen Luethje wrote:
> > 
> > Me wrote:
> > 
> > <snip>
> > 
> > > Using the code:
> > > }}}
<eucode>
> > > function log2 (atom x)
> > >    return log(x)/log(2)
> > > end function
> > >  
> > > for i = 0 to 32 do
> > >    printf(1, "%d: %0.16g\n", i & log2( power( 2, i ) ))
> > > end for
> > > </eucode>
{{{

> > > with the EXW.EXE interpreter 3.0.2, I can't manage to get imprecise
> > > results
> > > anymore, neither on my old system nor on my new system.  *LOL*
> > 
> > <snip>
> > 
> > I think know I've found the explanation.
> > Matt, when I had tested my log2() function, I probably had used a different
> > way than you to look for imprecise results. Please test this:
> 
> <snip>
> 
> > These are the two cases that I treated specially in my proposal for
> > "math.e".
> > 
> > So it seems that for i = 29 and for i = 31, the results of log2() are
> > not equal according to the != operator, but they are (or only look)
> > equal according to printf() ...
> 
> OK, I see the difference now.  Using the straight log/log method, there
> is still a difference for 29 and 31.
> 
> OTOH, using the constant, the difference for 29 and 31 was in the next to 
> least significant bit, making the differences twice as big.  And there 
> were many more differences.  Definitely looks like rounding errors.
> 
> And by looking at what I got by parsing the constant, I can see that 
> by letting the interpreter parse your constant, it loses accuracy.
> Below, I've shown the bits of the double gotten in these different
> ways:
> 
> 1: log(2)
> 2: 0.6931471805599453
> 3: 0.6931471805599453e0 (using my parser)
> 
> 1: 1111011110011100010111110111111101000010011101000110 01111111110 0 (-1)
> 2: 0111011110011100010111110111111101000010011101000110 01111111110 0 (-1)
> 3: 1111011110011100010111110111111101000010011101000110 01111111110 0 (-1)
> 
> This certainly calls into question the other constants, since they might
> also be one bit off (probably ok for most applications, but still...)
> For log(2), we could just do the calculation on assignment, but that 
> doesn't help with the others.  The easiest solution is to use the
> float64s, and call machine_func(46,...) on them (to avoid including
> machine.e) and putting the human readable value in a comment:
> }}}
<eucode>
>     LN2        = machine_func(47, {239,57,250,254,66,46,230,63}),   --
>     0.6931471805599453e0
>     LN10       = machine_func(47, {21,85,181,187,177,107,2,64}),    --
>     2.3025850929940456e0
>     E          = machine_func(47, {105,87,20,139,10,191,5,64}),     --
>     2.7182818284590452e0
>     SQRT2      = machine_func(47, {204,59,127,102,158,160,246,63}), --
>     1.4142135623730950e0
>     HALF_SQRT2 = machine_func(47, {204,59,127,102,158,160,230,63}), --
>     0.7071067811865475e0
>     PI         = machine_func(47, {24,45,68,84,251,33,9,64}),       --
>     3.1415926535897932e0
>     HALF_PI    = machine_func(47, {24,45,68,84,251,33,249,63}),     --
>     1.5707963267948966e0
>     QUARTER_PI = machine_func(47, {24,45,68,84,251,33,233,63}),     --
>     0.7853981633974483e0
>     TWO_PI     = machine_func(47, {24,45,68,84,251,33,25,64})       --
>     6.2831853071795864e0
> </eucode>
{{{

> 
> Using the constant for LN2 (as long as it's the *right* one) is probably
> faster (I think that's a reasonable assumption), we should probably go
> with your original function, but without the special cases.
> 
> For a new proposal, I know that we've covered the most common cases, but
> how about a logn (or logx?) function for the general case:
> }}}
<eucode>
> global function logn( object x, atom base ) 
> </eucode>
{{{

> 
> Matt

Your solution for the constants is certainly the most rigorous one. Let humans
read material for humans and computers read material for computers, without
interference.

As for deg_to_rad's name: too many keystrokes as usual, but I'll pretend I don't
care, since I don't think I ever had to write it before this post.

logn(x,base)=log(x)/log(base)? I have nothing against it, but the doc should
emphasize that there may be tiny discrepancies, for instance between LN2 and
logn(2,E), because of the just discussed rounding errors.

Since no one replied to my first proposal, I'll repeat it: add a gamma()
function and an erf() function, since they re very commonly used in analysis and
statistics. Note that an incomplete gamma function could be an even better idea
than erf(), as erf() is a special, very frequent occurrence of
incomplete_gamma(x,z) after a trivial transform. The general incomplete_gamma()
arises in physics rather. The value of the Euler constant (=-gamma'(1)) would be
a logical addition then too.

1/sqrt(2*PI) is a very common normalisation constant as well, both in statistics
and in Fourier series calculations, so it may not hurt to have it on board as
well.

The most difficult thing here could be to port some Fortran code to Eu to do the
above, assuming the C compiler don't have this as standard. There is ample supply
of such free code.

CChris

new topic     » goto parent     » topic index » view message » categorize

15. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> Matt Lewis wrote:
> 
> > we should probably go
> > with your original function, but without the special cases.
> 
> So just the following?
global function log2 (object x)
    return log(x)/LN2
end function

> But then we know that we'll get imprecise results for x = 2^29
> and x = 2^31. Why shouldn't we avoid that?

Yeah, you're probably right.  We *know* the right result, so we might
as well return it.  Just a bit less elegant...

> > For a new proposal, I know that we've covered the most common cases, but
> > how about a logn (or logx?) function for the general case:
> > 
> > global function logn( object x, atom base ) 
> 
> I also have thougt of that. But why not use 'object base' in order to
> allow sequence operations, e.g.
? logx({100,32}, {10,2})    -- prints {2,5}

> Well, looks good to me, but will actually anyone ever use it? smile

Who knows.  A simple use case: It could be useful to get something in base 
#100 to see how many bytes it would take to store a number.  After log10
and log2, it just seems to be missing (to me).

I think it makes more sense that the base be an atom, so that every element
gets same calculation.

> A personal remark according the name:
> You certainly know the term "Logarithmus naturalis" for logarithm base E.
> Because of this name, the abbreviation for logarithm base E that is used
> everywhere in Germany is ln(). So (at least for Germnas) it is already
> confusing that Euphoria's built-in function is not named ln(), but log().
> (At least for Germans) log() should be the name for the general function
> log(x, base).
> It's probably too late now to change that, but: An 'n' in a name of a
> logarithm function would always make me think of "naturalis". So using
> the name logn() for the genaral logarithm function would even increase
> the potential for confusion IMHO.

I fully agree that log() is confusing.  I expect to see ln().  Maybe we
could add a wrapper? :)  Actually, the reason I used logn() was because,
at least in english, we tend to say, "Log [base] 'n' of <some number>.'
And I suggested the logx exactly because logn made me think of ln.

Matt

new topic     » goto parent     » topic index » view message » categorize

16. Re: New proposal for math.e

CChris wrote:

<snip>

> Since no one replied to my first proposal, I'll repeat it: add a gamma()
> function
> and an erf() function, since they re very commonly used in analysis and
> statistics.
> Note that an incomplete gamma function could be an even better idea than
> erf(),
> as erf() is a special, very frequent occurrence of incomplete_gamma(x,z) after
> a trivial transform. The general incomplete_gamma() arises in physics rather.
> The value of the Euler constant (=-gamma'(1)) would be a logical addition then
> too.
> 
> 1/sqrt(2*PI) is a very common normalisation constant as well, both in
> statistics
> and in Fourier series calculations, so it may not hurt to have it on board as
> well.
> 
> The most difficult thing here could be to port some Fortran code to Eu to do
> the above, assuming the C compiler don't have this as standard. There is ample
> supply of such free code.

I do not even know the meaning of a gamma() and an erf() function, so I
can't provide code for them. But you probably can do so. smile

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

17. Re: New proposal for math.e

Matt Lewis wrote:

<snip>

> I think it makes more sense that the base be an atom, so that every element
> gets same calculation.

So how about something like this:
type positive_not_1 (object x)
   if atom(x) and x > 0 then
      return x != 1
   end if
   return 0
end type

global function logx (object x, positive_not_1 base)
   -- general log() function
   -- in  : x   : (sequence of) real number(s) > 0
   --       base: real number > 0 and != 1
   -- out : (sequence of) real number(s)
   -- Note: If x = 1 then the function returns 0 for any possible base.

   return log(x)/log(base)
end function

<snip>

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

18. Re: New proposal for math.e

CChris wrote:
> 
> Since no one replied to my first proposal, I'll repeat it: add a gamma()
> function
> and an erf() function, since they re very commonly used in analysis and
> statistics.
> Note that an incomplete gamma function could be an even better idea than
> erf(),
> as erf() is a special, very frequent occurrence of incomplete_gamma(x,z) after
> a trivial transform. The general incomplete_gamma() arises in physics rather.
> The value of the Euler constant (=-gamma'(1)) would be a logical addition then
> too.

Yes, I think gamma() and erf() would be good additions.

Matt

new topic     » goto parent     » topic index » view message » categorize

19. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> CChris wrote:
> 
> <snip>
> 
> > Since no one replied to my first proposal, I'll repeat it: add a gamma()
> > function
> > and an erf() function, since they re very commonly used in analysis and
> > statistics.
> > Note that an incomplete gamma function could be an even better idea than
> > erf(),
> > as erf() is a special, very frequent occurrence of incomplete_gamma(x,z)
> > after
> > a trivial transform. The general incomplete_gamma() arises in physics
> > rather.
> > The value of the Euler constant (=-gamma'(1)) would be a logical addition
> > then
> > too.
> > 
> > 1/sqrt(2*PI) is a very common normalisation constant as well, both in
> > statistics
> > and in Fourier series calculations, so it may not hurt to have it on board
> > as
> > well.
> > 
> > The most difficult thing here could be to port some Fortran code to Eu to do
> > the above, assuming the C compiler don't have this as standard. There is
> > ample
> > supply of such free code.
> 
> I do not even know the meaning of a gamma() and an erf() function, so I
> can't provide code for them. But you probably can do so. smile
> 
> Regards,
>    Juergen

gamma(x) is the integral, over [0,+oo[, of power(t,x-1)*exp(-t)dt. The immense
majority of asymptotic results in ODE, probability theory, nomber theory etc is
expressed in terms of this function.

incomplete_gamma(x,a) is the same integral over [0,a[ with a>=0. Calculations of
electromagnetic fields generated by currents in solids/plasmas routinely let
themselves expressed using this function. Additionally, it is a broad
generalisation of the below.

The erf() function is the integral, over ]-oo,x[, of exp(-t*t/2)dt, multiplied
by 1/sqrt(2*PI). This is the distribution function of the centered, reduced Gauss
normal density, to which 97% of all statistical results refer (because of the law
of large numbers). A simple variable change shows that, if x>=0,
erf(x)=1/2 + incomplete_gamma(sqrt(2*x),1/2)/sqrt(PI)
And, because of the symmetry of the normal law, we have erf(x)+erf(-x)=1.

CChris

new topic     » goto parent     » topic index » view message » categorize

20. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> CChris wrote:
> 
> <snip>
> 
> > Since no one replied to my first proposal, I'll repeat it: add a gamma()
> > function
> > and an erf() function, since they re very commonly used in analysis and
> > statistics.
> > Note that an incomplete gamma function could be an even better idea than
> > erf(),
> > as erf() is a special, very frequent occurrence of incomplete_gamma(x,z)
> > after
> > a trivial transform. The general incomplete_gamma() arises in physics
> > rather.
> > The value of the Euler constant (=-gamma'(1)) would be a logical addition
> > then
> > too.
> > 
> > 1/sqrt(2*PI) is a very common normalisation constant as well, both in
> > statistics
> > and in Fourier series calculations, so it may not hurt to have it on board
> > as
> > well.
> > 
> > The most difficult thing here could be to port some Fortran code to Eu to do
> > the above, assuming the C compiler don't have this as standard. There is
> > ample
> > supply of such free code.
> 
> I do not even know the meaning of a gamma() and an erf() function, so I
> can't provide code for them. But you probably can do so. smile
> 
> Regards,
>    Juergen

The Cephes C/C++ numericall library at www.moshier.net has more than what we
need, and doesn't seem to have any licensing issue, apart from reproducing the
copyright notice.

CChris

new topic     » goto parent     » topic index » view message » categorize

21. Re: New proposal for math.e

jacques deschênes wrote:

> Hi Juergen,
> 
> As I mentionned it in previous unoticed post, a math.e library should only
> deal
> with numbers. So why find_least() use compare() to compare elements of
> sequence?
> Those elements should be atoms and the relational operator '<' should be
> used.
> You may argue that list may contain sub-sequence of atom, but can you give
> exemples
> were this would be usefull?
> 
> What i propose is this:
> 
> 
> function find_least(sequence list,integer start) 
> -- return the smallest element of list where list is sequence of atoms.
> -- list must have length(list)>=2
> -- but what should we do if length(list)<2, crash!!! ?
> atom temp
> ineger ret
> 
>    temp = s[start]
>    ret = start
>    for i = start+1 to length(list) do
>      if s[i]<temp then
>         temp = s[i] 
>         ret = i    
>      end if
>    end for
>    return ret
> end function
> 
> same thing for find_greatest()
> 
> regards,
> Jacques Deschênes

Hi Jacques,

do be frank, I must say that I don't like the suggestion.
One of Euphoria's advantages is that it often allows to write generic
routines, that work for different kinds of data. For instance, in
other languages there may be functions such as
- sort_array_of_numbers()
- sort_array_of_strings()
- sort_array_of_structures()

In Eupharia it's just sort(). I like this very much.
If we now would implement find_least(), find_greatest() etc. only for
numbers, then sooner or later we would need to change the functions, or
to write new functions _with the same functionality_ for strings and/or
for nested sequences. Why should we now deliberately do without a
generic solution?

However, I agree with you that "math.e" is not actually a good place for
those generic functions. Poeple who want to use say find_greatest() with
strings probably would not expect it to be located in "math.e" (although
the documentation will tell them the name of the proper include file).

So maybe we should put these functions in a standard include file named
say "compare.e", which could contain several routines that have got to
do with comparisons? Just an idea. This file also could contain the
binary_search() function that recently has been suggested.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

22. Re: New proposal for math.e

CChris wrote:

> Juergen Luethje wrote:

<snip>

>> I do not even know the meaning of a gamma() and an erf() function, so I
>> can't provide code for them. But you probably can do so. smile
>> 
>> Regards,
>>    Juergen
> 
> The Cephes C/C++ numericall library at www.moshier.net has more than what we
> need, and doesn't seem to have any licensing issue, apart from reproducing the
> copyright notice.
> 
> CChris

That's probably a good source for people who understand C. Another good
source might be "Numerical Recipes in C", see
<http://www.nrbook.com/a/bookcpdf.php>, and I'm sure there is more free
stuff on the internet, especially in C (or C++).
There are also big math textbooks, so literally dozens of formulas are
waiting to be implemented in Euphoria.

But we should soon come to an end (for now!). It is not necessary to
include all formulas that we consider more or less important in the
_first_ edition of "math.e".  We should be somewhat modest regarding
our first "community product". Nobody expects that the first product
of a craftsman is already his masterpiece.

I think for now we should not add more than say two or three additional
functions. Then we should try to get agreement about as much points as
possible, and decide what to do with the points that we couldn't agree
upon. Then the documentation must be written. This also will be a
considerable amount of work. Maybe there also will be some discussion
about the documentation.

All this should not take too long, otherwise too many people will lose
interest. But I think it's important to actually release a
"math.e created by the OpenEuphoria community". This will be give a good
feeling of success, so we should concentrate on this goal. Later, we can
anyway add more functions to the library like we want.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

23. Re: New proposal for math.e

Wouldn't be more accurate to write misc.e using Euphoria and 

the Euphoria assembler calls to use the PC's built-in 

floating point processor.


Bernie

My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

new topic     » goto parent     » topic index » view message » categorize

24. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> This is my new proposal for a "math.e" standard include file,
> according to the recent discussion on this forum.
> 
...
> global function radians_to_degrees (object x)
>    -- in : (sequence of) angle(s) in radians
>    -- out: (sequence of) angle(s) in degrees
> 
>    return x/PI * 180.0
> end function
> 
> global function degrees_to_radians (object x)
>    -- in : (sequence of) angle(s) in degrees
>    -- out: (sequence of) angle(s) in radians
> 
>    return x/180.0 * PI
> end function
> 
...
> Regards,
>    Juergen

Very nice.  First I would suggest adding a constant RADIANS =
57.29577951308232158
and modifying radians_to_degrees() and degrees_to_radians() as follows:

global function radians_to_degrees (object x)
   return x * RADIANS
end function

global function degrees_to_radians (object x)
   return x / RADIANS
end function


This will save a multiplication in each function.  I would also like to add a
couple of functions:

global function polar_to_rect(sequence xy)
-- convert a rectangular coordinates to polar coordinates
    atom angle, distance, x, y
    x = xy[1]
    y = xy[2]
    distance = sqrt(power(x, 2)+power(y, 2))
    if x > 0 then
    	angle = arctan(y/x)
    elsif x < 0 then
    	if y < 0 then
    	    angle = arctan(y/x)-PI
    	else
    	    angle = arctan(y/x)+PI
    	end if
    else
    	if y < 0 then
    	    angle = -HALF_PI
    	else
    	    angle = HALF_PI
    	end if
    end if
    return {distance, angle}
end function

global function rect_to_polar(sequence pol)
-- convert a polar coordinates to rectangular coordinates
    atom distance, angle, x, y
    distance = pol[1]
    angle = pol[2]
    x = distance*cos(angle)
    y = distance*sin(angle)
    return {x, y}
end function

 
       
In the above functions, angle is expressed in radians, increasing in a clockwise
direction from east.

Regards,  Colin   (now returning to deep lurk mode)

new topic     » goto parent     » topic index » view message » categorize

25. Re: New proposal for math.e

Bernie Ryan wrote:
> 
> 
> Wouldn't be more accurate to write misc.e using Euphoria and 
> the Euphoria assembler calls to use the PC's built-in 
> floating point processor.
 
I don't understand why this would be more accurate, unless you're assuming
that the backend isn't using these same features for us as part of the
compiler's/platform's C runtime library.

Matt

new topic     » goto parent     » topic index » view message » categorize

26. Re: New proposal for math.e

Colin Taylor wrote:
> 
...
> 
> global function polar_to_rect(sequence xy)
> -- convert a rectangular coordinates to polar coordinates
>     atom angle, distance, x, y
... 
> 
> global function rect_to_polar(sequence pol)
> -- convert a polar coordinates to rectangular coordinates
>     atom distance, angle, x, y
...
> Regards,  Colin   (now returning to deep lurk mode)

Oops!  Obviously got the names of these two funcions reversed. (somehow...)

Regards,  Colin

new topic     » goto parent     » topic index » view message » categorize

27. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> CChris wrote:
> 
> > Juergen Luethje wrote:
> 
> <snip>
> 
> >> I do not even know the meaning of a gamma() and an erf() function, so I
> >> can't provide code for them. But you probably can do so. smile
> >> 
> >> Regards,
> >>    Juergen
> > 
> > The Cephes C/C++ numericall library at www.moshier.net has more than what we
> > need, and doesn't seem to have any licensing issue, apart from reproducing
> > the
> > copyright notice.
> > 
> > CChris
> 
> That's probably a good source for people who understand C. Another good
> source might be "Numerical Recipes in C", see
> <<a
> href="http://www.nrbook.com/a/bookcpdf.php">http://www.nrbook.com/a/bookcpdf.php</a>>,
> and I'm sure there is more free
> stuff on the internet, especially in C (or C++).
> There are also big math textbooks, so literally dozens of formulas are
> waiting to be implemented in Euphoria.
> 
> But we should soon come to an end (for now!). It is not necessary to
> include all formulas that we consider more or less important in the
> _first_ edition of "math.e".  We should be somewhat modest regarding
> our first "community product". Nobody expects that the first product
> of a craftsman is already his masterpiece.
> 

I'd be a little more prudent here.
It is true that we don't need more than two, three, four functions, because
hardly anyone in the vocal community - I'll say more on this later - is
interested in maths beyond a very elementary level. However, the small steps
approach often results in stunted growth, because said growth will impose changes
later, while changes are widely rejected bu the vocal community. Euphoria has
suffered a lot from that already, so don't be too cautious or shy - the cost
later is high.

> I think for now we should not add more than say two or three additional
> functions. Then we should try to get agreement about as much points as
> possible, and decide what to do with the points that we couldn't agree
> upon. Then the documentation must be written. This also will be a
> considerable amount of work. Maybe there also will be some discussion
> about the documentation.
> 

The documentation for the very simple stuff being addded will really require
little work. However, I expect an immense amount of discussion around it.

> All this should not take too long, otherwise too many people will lose
> interest.

It is not possible to access posts 5 day old from the web interface at the
current rate, which may not collapse sharply anytime soon. The "not too long"
really needs to be very short, otherwise nothing consistent will be ever built,
even before people lose interest, as posts won't be available. All right, they
will through the search facility, but it is less convenient, not everyone will
use it, and the reference # of the post aren't even apparent on the search result
pages.

> But I think it's important to actually release a
> "math.e created by the OpenEuphoria community". This will be give a good
> feeling of success, so we should concentrate on this goal. Later, we can
> anyway add more functions to the library like we want.
> 

Now we may have a problem. The number of posters on this list is (hopefully!)
largely less than the number of Euphoria users worldwide. I have no idea about
whether the opinions being voiced here, as well as their relative frequency, are
representative of the user base at large. Perhaps Rob can tell us something about
it - he is probably the only one to receive news from users who are not amongst
the group of 15 persons at best trading code, opinions and preferences at any
given time on this list, which I  called the "vocal community" earlier.

CChris

> Regards,
>    Juergen

new topic     » goto parent     » topic index » view message » categorize

28. Re: New proposal for math.e

Colin Taylor wrote:
> Very nice.  First I would suggest adding a constant RADIANS =
> 57.29577951308232158
> and modifying radians_to_degrees() and degrees_to_radians() as follows:
> 
> }}}
<eucode>
> 
> global function radians_to_degrees (object x)
>    return x * RADIANS
> end function
> 
> global function degrees_to_radians (object x)
>    return x / RADIANS
> end function
> 
> </eucode>
{{{


Good suggestion. And even better would be to avoid the division as well.


constant RADIANS_DEGREES = 57.29577951308232158
constant DEGREES_RADIANS = 0.017453292519943296
global function radians_to_degrees (object r)
   return r * RADIANS_DEGREES
end function

global function degrees_to_radians (object d)
   return d * DEGREES_RADIANS
end function



-- 
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell

new topic     » goto parent     » topic index » view message » categorize

29. Re: New proposal for math.e

Derek Parnell wrote:
> 
> Colin Taylor wrote:
> > Very nice.  First I would suggest adding a constant RADIANS =
> > 57.29577951308232158
> > and modifying radians_to_degrees() and degrees_to_radians() as follows:
> > 
> > }}}
<eucode>
> > 
> > global function radians_to_degrees (object x)
> >    return x * RADIANS
> > end function
> > 
> > global function degrees_to_radians (object x)
> >    return x / RADIANS
> > end function
> > 
> > </eucode>
{{{

> 
> Good suggestion. And even better would be to avoid the division as well.
> 
> 
> }}}
<eucode>
> constant RADIANS_DEGREES = 57.29577951308232158
> constant DEGREES_RADIANS = 0.017453292519943296
> global function radians_to_degrees (object r)
>    return r * RADIANS_DEGREES
> end function
> 
> global function degrees_to_radians (object d)
>    return d * DEGREES_RADIANS
> end function
> </eucode>
{{{

> 
> 
> -- 
> Derek Parnell
> Melbourne, Australia
> Skype name: derek.j.parnell

Hmm. On modern hardware does it really matter? Especially in the context of an
interpreted language?

Not trying to nitpick, I'm just curious. I think the most obvious solution is
the best, and both of these qualify.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

new topic     » goto parent     » topic index » view message » categorize

30. Re: New proposal for math.e

Colin Taylor wrote:

> Juergen Luethje wrote:
> 
> > This is my new proposal for a "math.e" standard include file,
> > according to the recent discussion on this forum.
> > 
> ...
> > global function radians_to_degrees (object x)
> >    -- in : (sequence of) angle(s) in radians
> >    -- out: (sequence of) angle(s) in degrees
> > 
> >    return x/PI * 180.0
> > end function
> > 
> > global function degrees_to_radians (object x)
> >    -- in : (sequence of) angle(s) in degrees
> >    -- out: (sequence of) angle(s) in radians
> > 
> >    return x/180.0 * PI
> > end function
> > 
> ...
> > Regards,
> >    Juergen
> 
> Very nice.  First I would suggest adding a constant RADIANS =
> 57.29577951308232158
> and modifying radians_to_degrees() and degrees_to_radians() as follows:
> 
> 
> global function radians_to_degrees (object x)
>    return x * RADIANS
> end function
> 
> global function degrees_to_radians (object x)
>    return x / RADIANS
> end function
> 
> 
> This will save a multiplication in each function.

I think that's a good idea. And Derek recently wrote that
multiplication is faster than division. So maybe we should have
two constants here, and do a multiplication in both functions.

>  I would also like to add a couple of functions:

Very nice!
How about adding a user-defined type here, that your functions use for
parameter checking?
(Below I also swapped the function names, according to your other post.)

type point (object x)
   if sequence(x) and (length(x) = 2) then
      return atom(x[1]) and atom(x[2])
   end if
   return 0
end type

> global function polar_to_rect(sequence xy)

global function rect_to_polar(point xy)
                              ^^^^^

> -- convert a rectangular coordinates to polar coordinates
>     atom angle, distance, x, y
>     x = xy[1]
>     y = xy[2]
>     distance = sqrt(power(x, 2)+power(y, 2))

I'm pretty sure the following will be faster:
      distance = sqrt(x*x + y*y)

>     if x > 0 then
>           angle = arctan(y/x)
>     elsif x < 0 then
>           if y < 0 then
>               angle = arctan(y/x)-PI
>           else
>               angle = arctan(y/x)+PI
>           end if

Are you sure?
According to one of my math textbooks, it should simply be:
     elsif x < 0 then
           angle = arctan(y/x)+PI


>     else
>           if y < 0 then
>               angle = -HALF_PI
>           else
>               angle = HALF_PI
>           end if
>     end if

According to the same math textbook, it should be:
     else                        -- x = 0 here
           if y < 0 then
               angle = -HALF_PI
           elsif y > 0 then
               angle = HALF_PI
           else
               angle = UNDEFINRD
           end if
     end if

>     return {distance, angle}
> end function
> 
> global function rect_to_polar(sequence pol)

global function polar_to_rect(point pol)
                              ^^^^^

> -- convert a polar coordinates to rectangular coordinates
>     atom distance, angle, x, y
>     distance = pol[1]
>     angle = pol[2]
>     x = distance*cos(angle)
>     y = distance*sin(angle)
>     return {x, y}
> end function
> 
>  
> In the above functions, angle is expressed in radians, increasing in a
> clockwise
> direction from east.
> 
> Regards,  Colin   (now returning to deep lurk mode)

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

31. Re: New proposal for math.e

Matt Lewis wrote:
> 
> Bernie Ryan wrote:
> > 
> > 
> > Wouldn't be more accurate to write misc.e using Euphoria and 
> > the Euphoria assembler calls to use the PC's built-in 
> > floating point processor.
>  
> I don't understand why this would be more accurate, unless you're assuming
> that the backend isn't using these same features for us as part of the
> compiler's/platform's C runtime library.
> 

Matt:

The document talks about using hardware .


 Performance Note:
 -----------------
        Calculations using variables declared as integer will usually be
        somewhat faster than calculations involving variables declared as atom.
        If your machine has floating-point hardware, Euphoria will use it to
        manipulate atoms that aren't representable as integers. If your machine
        doesn't have floating-point hardware, Euphoria will call software
        floating-point arithmetic routines contained in ex.exe (or in Windows).
        You can force ex.exe to bypass any floating-point hardware, by setting
        an environment variable:

            SET NO87=1

        The slower software routines will be used, but this could be of some
        advantage if you are worried about the floating-point bug in some early
        Pentium chips.

But I dont see any where in the source checks for it or indicates

that fp hardware is being used by default.


Bernie

My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

new topic     » goto parent     » topic index » view message » categorize

32. Re: New proposal for math.e

Bernie Ryan wrote:
> Matt:
> 
> The document talks about using hardware .
> 
> 
>  Performance Note:
>  -----------------
>         Calculations using variables declared as integer will usually be
>         somewhat faster than calculations involving variables declared as
>         atom.
>         If your machine has floating-point hardware, Euphoria will use it to
>         manipulate atoms that aren't representable as integers. If your
>         machine
>         doesn't have floating-point hardware, Euphoria will call software
>         floating-point arithmetic routines contained in ex.exe (or in
>         Windows).
>         You can force ex.exe to bypass any floating-point hardware, by setting
>         an environment variable:
> 
>             SET NO87=1
> 
>         The slower software routines will be used, but this could be of some
>         advantage if you are worried about the floating-point bug in some
>         early
>         Pentium chips.
> 
> But I dont see any where in the source checks for it or indicates
> 
> that fp hardware is being used by default.
> 
> 
> Bernie
> 
> My files in archive:
> WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 
> 
> Can be downloaded here:
> <a
> href="http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan">http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan</a>

I think that it's in the makefile. Let me check...

Hmm. in the file makefile.wat, /fp5 /fpi87 are added to the compiler flags.
These specify to use processor floating point instructions inline in the object
code and optimizes for Pentium and above.

I'm not sure if recently built versions even use software FP emulation anymore
--

Oh, I found it, in the translator docs:
http://www.rapideuphoria.com/e2c.htm
"To make a DOS program, compiled by WATCOM, that uses fast hardware
floating-point instructions, add -fastfp to the command line. e.g.

      ec -wat -fastfp crunch.ex
 

By default, Euphoria for DOS calls routines to test if hardware floating-point
instructions are available. If they are not, then slower software emulation code
is used. When -fastfp is specified, the compiled code will assume the existence
of hardware floating-point. This can cause floating-point intensive programs to
run about twice as fast, but they will fail to run at all on old 486's and 386's
that are lacking hardware floating-point support. With -fastfp, emake.bat chooses
faster WATCOM C compiler options, and emake.bat must also link in ecfastfp.lib
instead of ec.lib.

On all other platforms, Euphoria uses fast hardware floating-point instructions,
and the operating system handles the case where hardware f.p. is missing."

Hope that helps.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

new topic     » goto parent     » topic index » view message » categorize

33. Re: New proposal for math.e

Oh, and BTW, I almost never use ex for dos -- I almost exclusively use
exw/exwc/exu. I haven't seen a machine without floating point hardware for over
ten years.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

new topic     » goto parent     » topic index » view message » categorize

34. Re: New proposal for math.e

Derek Parnell wrote:
> Colin Taylor wrote:
> Good suggestion. And even better would be to avoid the division as well.
> 
[snip] 
> }}}
<eucode>
> constant RADIANS_DEGREES = 57.29577951308232158
> constant DEGREES_RADIANS = 0.017453292519943296
> </eucode>
{{{

> 
[snip]
It seems to me too many 'S' sometimes,
I'd like:
constant RADIAN_DEGREES = 57.29577951308232158
constant DEGREE_RADIANS = 0.017453292519943296

Regards,
Igor Kachan
kinz at peterlink.ru

new topic     » goto parent     » topic index » view message » categorize

35. Re: New proposal for math.e

Derek Parnell wrote:
> 
> }}}
<eucode>
> constant RADIANS_DEGREES = 57.29577951308232158
> constant DEGREES_RADIANS = 0.017453292519943296
> </eucode>
{{{


I think:
constant RADIANS_TO_DEGREES = 180/PI
constant DEGREES_TO_RADIANS = PI/180

is more in keeping with the Eu philosophy.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

36. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> Fernando Bauer wrote:
> 
> > Hi All,
> > 
> > I would like that Euphoria could be easily used by all programmers in the
> > world,
> > in particular, not only for English speakers. To minimize the learning
> > effort to non-English speakers, I suggest to take into consideration:
> > 
> >   1) Choose the most international known word that can be used to describe
> >   its
> > intention;
> >   2) Use the minimum quantity of characters that still makes sense;
> > 
> > In particular, I think the functions "greatest", "greater", "lesser", etc.
> > are
> > much less international than "max", "max2", "min2" proposed initially by
> > Juergen. Also, in many equipments, datasheets, specifications, even in other
> > languages, use the same words: min, max, ... 
> > In case of mathematical functions, I think a good source is electronic
> > calculators
> > and other computer languages.
> > The item 2, improves the efficiency in reading, writing and debugging the
> > code,
> > reducing several costs and helps the item 1 in increasing
> > the probability that several languages start with (or have) the same letters
> > (Ex.: maximum = maximo(Portuguese), maximum (French), ...)
> 
> I think these are good arguments, but other people don't like those names.
> So I personally don't know what we should do now ... sad
 
Why not to use the synonyms?

Just some set of the identical routines under different names?
For example, in bilingual Euphoria, every standard routine is
defined twice, with English name and with Russian name.

I know, the synonyms are not very good for the technical,
scientific and programming tasks and texts, we must avoid them,
but there are some exceptions from the common rules.

Maybe it is a case for such an exception?
At least it is a simple way to be good for every personal taste.

Regards,
Igor Kachan
kinz at peterlink.ru

new topic     » goto parent     » topic index » view message » categorize

37. Re: New proposal for math.e

Pete Lomax wrote:

> Derek Parnell wrote:
> 
> > constant RADIANS_DEGREES = 57.29577951308232158
> > constant DEGREES_RADIANS = 0.017453292519943296
> 
> I think:
> 
> constant RADIANS_TO_DEGREES = 180/PI
> constant DEGREES_TO_RADIANS = PI/180
> 
> is more in keeping with the Eu philosophy.

And the list of global constants then would look like this:
global constant
   LN2        = log(2),
   LN10       = log(10),
E          = machine_func(47, {105,87,20,139,10,191,5,64}),    --
   2.7182818284590452e0
   SQRT2      = sqrt(2),
   HALF_SQRT2 = SQRT2/2
PI         = machine_func(47, {24,45,68,84,251,33,9,64}),      --
   3.1415926535897932e0
   HALF_PI    = PI/2
   QUARTER_PI = PI/4
   TWO_PI     = PI*2

I like it. The calculation of the constant values is only done once at
initialization of the program, so the time for it is negligible, no?

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

38. Re: New proposal for math.e

Igor Kachan wrote:

> Juergen Luethje wrote:
> > 
> > Fernando Bauer wrote:
> > 
> > > Hi All,
> > > 
> > > I would like that Euphoria could be easily used by all programmers in the
> > > world,
> > > in particular, not only for English speakers. To minimize the learning
> > > effort to non-English speakers, I suggest to take into consideration:
> > > 
> > >   1) Choose the most international known word that can be used to describe
> > >   its
> > > intention;
> > >   2) Use the minimum quantity of characters that still makes sense;
> > > 
> > > In particular, I think the functions "greatest", "greater", "lesser", etc.
> > > are
> > > much less international than "max", "max2", "min2" proposed initially by
> > > Juergen. Also, in many equipments, datasheets, specifications, even in
> > > other
> > > languages, use the same words: min, max, ... 
> > > In case of mathematical functions, I think a good source is electronic
> > > calculators
> > > and other computer languages.
> > > The item 2, improves the efficiency in reading, writing and debugging the
> > > code,
> > > reducing several costs and helps the item 1 in increasing
> > > the probability that several languages start with (or have) the same
> > > letters
> > > (Ex.: maximum = maximo(Portuguese), maximum (French), ...)
> > 
> > I think these are good arguments, but other people don't like those names.
> > So I personally don't know what we should do now ... sad
>  
> Why not to use the synonyms?
> 
> Just some set of the identical routines under different names?
> For example, in bilingual Euphoria, every standard routine is
> defined twice, with English name and with Russian name.
> 
> I know, the synonyms are not very good for the technical,
> scientific and programming tasks and texts, we must avoid them,
> but there are some exceptions from the common rules.
> 
> Maybe it is a case for such an exception?
> At least it is a simple way to be good for every personal taste.

For every personal taste, I think it is best for everyone to define
synonyms her/himself for private usage, in case it is wanted.
But I don't think that should be supported officially.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

39. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> Pete Lomax wrote:
> 
> > Derek Parnell wrote:
> > 
> > > constant RADIANS_DEGREES = 57.29577951308232158
> > > constant DEGREES_RADIANS = 0.017453292519943296
> > 
> > I think:
> > 
> > constant RADIANS_TO_DEGREES = 180/PI
> > constant DEGREES_TO_RADIANS = PI/180
> > 
> > is more in keeping with the Eu philosophy.
> 
> And the list of global constants then would look like this:
> }}}
<eucode>
> global constant
>    LN2        = log(2),
>    LN10       = log(10),
>    E          = machine_func(47, {105,87,20,139,10,191,5,64}),    --
>    2.7182818284590452e0
>    SQRT2      = sqrt(2),
>    HALF_SQRT2 = SQRT2/2
>    PI         = machine_func(47, {24,45,68,84,251,33,9,64}),      --
>    3.1415926535897932e0
>    HALF_PI    = PI/2
>    QUARTER_PI = PI/4
>    TWO_PI     = PI*2
> </eucode>
{{{

> I like it. The calculation of the constant values is only done once at
> initialization of the program, so the time for it is negligible, no?
> 
> Regards,
>    Juergen

Doesn't this negate the very purpose of the precision analysis Matt just
performed a couple days ago? The divisions induce rounding errors sometimes, and
that's precisely why he coded all constants using machine_func(47,...).

At least, I'd replace 2 by 2.0 etc, since doubles don't have a native divide by
2 operation, contrary to integers.

By the way, let me add:
EULER_GAMMA = machine_func(47,{25,182,111,252,140,120,226,63})
-- the Euler-Mascheroni-Soldner gamma constant: 0.57721566490153286606065121 
EULER_NORMAL = machine_func(47,{81,54,212,51,69,136,217,63})
-- 1/sqrt(2*PI) = 0.3989422804014326779399461


CChris

new topic     » goto parent     » topic index » view message » categorize

40. Re: New proposal for math.e

Colin Taylor wrote:

<snip>

> I would also like to add a couple of functions:
> 
> }}}
<eucode>
> 
> global function polar_to_rect(sequence xy)
> -- convert a rectangular coordinates to polar coordinates
>     atom angle, distance, x, y
>     x = xy[1]
>     y = xy[2]
>     distance = sqrt(power(x, 2)+power(y, 2))
>     if x > 0 then
>     	angle = arctan(y/x)
>     elsif x < 0 then
>     	if y < 0 then
>     	    angle = arctan(y/x)-PI
>     	else
>     	    angle = arctan(y/x)+PI
>     	end if
>     else
>     	if y < 0 then
>     	    angle = -HALF_PI
>     	else
>     	    angle = HALF_PI
>     	end if
>     end if
>     return {distance, angle}
> end function
> 
> global function rect_to_polar(sequence pol)
> -- convert a polar coordinates to rectangular coordinates
>     atom distance, angle, x, y
>     distance = pol[1]
>     angle = pol[2]
>     x = distance*cos(angle)
>     y = distance*sin(angle)
>     return {x, y}
> end function
> 
> </eucode>
{{{
 
>        
> In the above functions, angle is expressed in radians, increasing in a
> clockwise
> direction from east.
> 
> Regards,  Colin   (now returning to deep lurk mode)

I don't know what you mean by "east" in this context. However, the
normal math convention is: Increasing positive values of an angle
correspond to _counter_ clockwise rotation.

But I've seen now that different textbooks use different conventions
about the range of values that is used for the angle in Polar
Coordinates. Some books use -PI < a <= PI, while others use
0 <= a < 2*PI. Our implementation of the functions will depend on the
range that we'll allow for the angle.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

41. Re: New proposal for math.e

CChris wrote:

> Juergen Luethje wrote:
> > 
> > Pete Lomax wrote:
> > 
> > > Derek Parnell wrote:
> > > 
> > > > constant RADIANS_DEGREES = 57.29577951308232158
> > > > constant DEGREES_RADIANS = 0.017453292519943296
> > > 
> > > I think:
> > > 
> > > constant RADIANS_TO_DEGREES = 180/PI
> > > constant DEGREES_TO_RADIANS = PI/180
> > > 
> > > is more in keeping with the Eu philosophy.
> > 
> > And the list of global constants then would look like this:
> > }}}
<eucode>
> > global constant
> >    LN2        = log(2),
> >    LN10       = log(10),
> >    E          = machine_func(47, {105,87,20,139,10,191,5,64}),    --
> >    2.7182818284590452e0
> >    SQRT2      = sqrt(2),
> >    HALF_SQRT2 = SQRT2/2
> >    PI         = machine_func(47, {24,45,68,84,251,33,9,64}),      --
> >    3.1415926535897932e0
> >    HALF_PI    = PI/2
> >    QUARTER_PI = PI/4
> >    TWO_PI     = PI*2
> > </eucode>
{{{

> > I like it. The calculation of the constant values is only done once at
> > initialization of the program, so the time for it is negligible, no?
> > 
> > Regards,
> >    Juergen
> 
> Doesn't this negate the very purpose of the precision analysis Matt just
> performed
> a couple days ago?

I don't know, but you might be absolutely right. I didn't think of this. sad
So probably the safest thing will be to provide the values in that special
format which Matt had suggested.

> The divisions induce rounding errors sometimes, and that's
> precisely why he coded all constants using machine_func(47,...).
> 
> At least, I'd replace 2 by 2.0 etc, since doubles don't have a native divide
> by 2 operation, contrary to integers.
> 
> By the way, let me add:
> }}}
<eucode>
> EULER_GAMMA = machine_func(47,{25,182,111,252,140,120,226,63})
> -- the Euler-Mascheroni-Soldner gamma constant: 0.57721566490153286606065121 
> EULER_NORMAL = machine_func(47,{81,54,212,51,69,136,217,63})
> -- 1/sqrt(2*PI) = 0.3989422804014326779399461
> </eucode>
{{{


Cool.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

42. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> > >    E          = machine_func(47, {105,87,20,139,10,191,5,64}),    --
> > >    2.7182818284590452e0
> > >    PI         = machine_func(47, {24,45,68,84,251,33,9,64}),      --
> > >    3.1415926535897932e0
Oh, I wasn't paying attention. There is an old thread which maybe should be
revisited:
http://www.openeuphoria.org/cgi-bin/esearch.exu?thread=1&fromMonth=4&fromYear=B&toMonth=6&toYear=B&keywords=%22Number+Stability+With+Decimals%22

In summary, a tweak to the way value(), and eu.ex, load numbers might mean that
this is not necessary.

FWIW, if this "trick" is needed, I'd prefer to see:
constant
E  = float64_to_atom({#69,#57,#14,#8B,#0A,#BF,#05,#40}), --(ie 2.7182...)
PI = float64_to_atom({#18,#2D,#44,#54,#FB,#21,#09,#40}), --(ie 3.1415...)

(I am a bit allergic to machine_func(47 etc, but it is not life-threatening)

If after that, PI/2 is not as accurate as it sh/could be, then something is
seriously wrong.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

43. Re: New proposal for math.e

Pete Lomax wrote:

> Juergen Luethje wrote:
> > 
> > > >    E          = machine_func(47, {105,87,20,139,10,191,5,64}),    --
> > > >    2.7182818284590452e0
> > > >    PI         = machine_func(47, {24,45,68,84,251,33,9,64}),      --
> > > >    3.1415926535897932e0
> Oh, I wasn't paying attention. There is an old thread which maybe should be
> revisited:
> <a
> href="http://www.openeuphoria.org/cgi-bin/esearch.exu?thread=1&fromMonth=4&fromYear=B&toMonth=6&toYear=B&keywords=%22Number+Stability+With+Decimals%22">http://www.openeuphoria.org/cgi-bin/esearch.exu?thread=1&fromMonth=4&fromYear=B&toMonth=6&toYear=B&keywords=%22Number+Stability+With+Decimals%22</a>
> 
> In summary, a tweak to the way value(), and eu.ex, load numbers might mean
> that
> this is not necessary.

I would appreciate it, if no such special tricks were necessary in order to
enter floating point constants in the source code with a precision as high
as possible.

> FWIW, if this "trick" is needed,

Currently it seems to be needed for maximum prcision, isn't it?

> I'd prefer to see:
> }}}
<eucode>
> constant 
> E  = float64_to_atom({#69,#57,#14,#8B,#0A,#BF,#05,#40}), --(ie 2.7182...)
> PI = float64_to_atom({#18,#2D,#44,#54,#FB,#21,#09,#40}), --(ie 3.1415...)
> </eucode>
{{{

> (I am a bit allergic to machine_func(47 etc, but it is not life-threatening)

I also think it's better readable. float64_to_atom() would require
   include machine.e
I think that was the reason for not using it. But that include statement
should not cause any problem, should it?

> If after that, PI/2 is not as accurate as it sh/could be, then something is
> seriously wrong.

I created a short test, and division doesn't seem to cause any problem
(here). The two differences that occur are between assigning a hard-coded
value vs. assingnimg the corresponding function result. I don't know what
that means.
global constant
E          = machine_func(47, {105,87,20,139,10,191,5,64}),     --
   2.7182818284590452e0
PI         = machine_func(47, {24,45,68,84,251,33,9,64}),       --
   3.1415926535897932e0

LN2        = machine_func(47, {239,57,250,254,66,46,230,63}),   --
   0.6931471805599453e0
LN10       = machine_func(47, {21,85,181,187,177,107,2,64}),    --
   2.3025850929940456e0
SQRT2      = machine_func(47, {204,59,127,102,158,160,246,63}), --
   1.4142135623730950e0
HALF_SQRT2 = machine_func(47, {204,59,127,102,158,160,230,63}), --
   0.7071067811865475e0
HALF_PI    = machine_func(47, {24,45,68,84,251,33,249,63}),     --
   1.5707963267948966e0
QUARTER_PI = machine_func(47, {24,45,68,84,251,33,233,63}),     --
   0.7853981633974483e0
TWO_PI     = machine_func(47, {24,45,68,84,251,33,25,64}),      --
   6.2831853071795864e0

   LN2_test        = log(2),
   LN10_test       = log(10),
   SQRT2_test      = sqrt(2),
   HALF_SQRT2_test = SQRT2/2,
   HALF_PI_test    = PI/2, 
   QUARTER_PI_test = PI/4, 
   TWO_PI_test     = PI*2 


? compare( LN2       , LN2_test )
? compare( LN10      , LN10_test )          -- LN10_test  is bigger!
? compare( SQRT2     , SQRT2_test )         -- SQRT2_test is bigger!
? compare( HALF_SQRT2, HALF_SQRT2_test )
? compare( HALF_PI   , HALF_PI_test ) 
? compare( QUARTER_PI, QUARTER_PI_test ) 
? compare( TWO_PI    , TWO_PI_test ) 

Tested with EXW.EXE 3.0.2.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

44. Re: New proposal for math.e

Pete Lomax wrote:
> 
> CChris wrote:
> > I'm contemplating a brute force attack against the backend code smile
> 
> Hurrah! Go, tiger, go!
> 
> This is excellent news. Instead of wasting time trying to improve Eu, we can
> all spend the next five years trying to fix it. I can't wait.
> 
> Pete
Heh. Nice.


Juergen Luethje wrote:
> 
> Pete Lomax wrote:
> 
> > Juergen Luethje wrote:
> > (I am a bit allergic to machine_func(47 etc, but it is not life-threatening)
> 
> I also think it's better readable. float64_to_atom() would require
>    include machine.e
> I think that was the reason for not using it. But that include statement
> should not cause any problem, should it?

I think it's just for namespace reasons, or if you want to use safe.e instead of
machine.e. It shouldn't really be problem though.


> > If after that, PI/2 is not as accurate as it sh/could be, then something is
> > seriously wrong.
> 
> I created a short test, and division doesn't seem to cause any problem
> (here). The two differences that occur are between assigning a hard-coded
> value vs. assingnimg the corresponding function result. I don't know what
> that means.
> }}}
<eucode>
> global constant
>    E          = machine_func(47, {105,87,20,139,10,191,5,64}),     --
>    2.7182818284590452e0
>    PI         = machine_func(47, {24,45,68,84,251,33,9,64}),       --
>    3.1415926535897932e0
> 
>    LN2        = machine_func(47, {239,57,250,254,66,46,230,63}),   --
>    0.6931471805599453e0
>    LN10       = machine_func(47, {21,85,181,187,177,107,2,64}),    --
>    2.3025850929940456e0
>    SQRT2      = machine_func(47, {204,59,127,102,158,160,246,63}), --
>    1.4142135623730950e0
>    HALF_SQRT2 = machine_func(47, {204,59,127,102,158,160,230,63}), --
>    0.7071067811865475e0
>    HALF_PI    = machine_func(47, {24,45,68,84,251,33,249,63}),     --
>    1.5707963267948966e0
>    QUARTER_PI = machine_func(47, {24,45,68,84,251,33,233,63}),     --
>    0.7853981633974483e0
>    TWO_PI     = machine_func(47, {24,45,68,84,251,33,25,64}),      --
>    6.2831853071795864e0
> 
>    LN2_test        = log(2),
>    LN10_test       = log(10),
>    SQRT2_test      = sqrt(2),
>    HALF_SQRT2_test = SQRT2/2,
>    HALF_PI_test    = PI/2, 
>    QUARTER_PI_test = PI/4, 
>    TWO_PI_test     = PI*2 
> 
> 
> ? compare( LN2       , LN2_test )
> ? compare( LN10      , LN10_test )          -- LN10_test  is bigger!
> ? compare( SQRT2     , SQRT2_test )         -- SQRT2_test is bigger!
> ? compare( HALF_SQRT2, HALF_SQRT2_test )
> ? compare( HALF_PI   , HALF_PI_test ) 
> ? compare( QUARTER_PI, QUARTER_PI_test ) 
> ? compare( TWO_PI    , TWO_PI_test ) 
> </eucode>
{{{

> Tested with EXW.EXE 3.0.2.
> 
> Regards,
>    Juergen
Some precision will be lost after more than a few operations anyway. Just like
almost any other calculation.

Hmm. Should check it with C sometime soon.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

new topic     » goto parent     » topic index » view message » categorize

45. Re: New proposal for math.e

Juergen Luethje wrote:
> I would appreciate it, if no such special tricks were necessary in order
> to enter floating point constants in the source code with a precision as 
> high as possible.
Ditto.

> }}}
<eucode>
>    LN10       = machine_func(47, {21,85,181,187,177,107,2,64}),    --
>    2.3025850929940456e0
>    SQRT2      = machine_func(47, {204,59,127,102,158,160,246,63}), --
>    1.4142135623730950e0
>    LN10_test       = log(10),
>    SQRT2_test      = sqrt(2),
> 
> ? compare( LN10      , LN10_test )          -- LN10_test  is bigger!
?{power(E,LN10)-10,power(E,LN10_test)-10}
The error with LN10_test is about half that of LN10.
> ? compare( SQRT2     , SQRT2_test )         -- SQRT2_test is bigger!
?{SQRT2*SQRT2-2,SQRT2_test*SQRT2_test-2}
Same error, different signs, so neither is particularly better?
> </eucode>
{{{

A re-read of Matt's post offered me no further clues, so without anything more
to go by I think log(10) is better and sqrt(2) is "just as good".

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

46. Re: New proposal for math.e

Me wrote:

> Pete Lomax wrote:
> 
> > Juergen Luethje wrote:
> > > 
> > > > >    E          = machine_func(47, {105,87,20,139,10,191,5,64}),    --
> 2.7182818284590452e0</font></i>
> > > > >    PI         = machine_func(47, {24,45,68,84,251,33,9,64}),      --
> 3.1415926535897932e0</font></i>
> > Oh, I wasn't paying attention. There is an old thread which maybe should be
> > revisited:
> > <a
> > href="http://www.openeuphoria.org/cgi-bin/esearch.exu?thread=1&fromMonth=4&fromYear=B&toMonth=6&toYear=B&keywords=%22Number+Stability+With+Decimals%22">http://www.openeuphoria.org/cgi-bin/esearch.exu?thread=1&fromMonth=4&fromYear=B&toMonth=6&toYear=B&keywords=%22Number+Stability+With+Decimals%22</a>
> > 
> > In summary, a tweak to the way value(), and eu.ex, load numbers might mean
> > that
> > this is not necessary.
> 
> I would appreciate it, if no such special tricks were necessary in order to
> enter floating point constants in the source code with a precision as high
> as possible.
> 
> > FWIW, if this "trick" is needed,
> 
> Currently it seems to be needed for maximum prcision, isn't it?
> 
> > I'd prefer to see:
> > }}}
<eucode>
> > constant 
> > E  = float64_to_atom({#69,#57,#14,#8B,#0A,#BF,#05,#40}), --(ie 2.7182...)
> > PI = float64_to_atom({#18,#2D,#44,#54,#FB,#21,#09,#40}), --(ie 3.1415...)
> > </eucode>
{{{

> > (I am a bit allergic to machine_func(47 etc, but it is not life-threatening)
> 
> I also think it's better readable. float64_to_atom() would require
>    include machine.e
> I think that was the reason for not using it. But that include statement
> should not cause any problem, should it?
> 
> > If after that, PI/2 is not as accurate as it sh/could be, then something is
> > seriously wrong.
> 
> I created a short test, and division doesn't seem to cause any problem
> (here). The two differences that occur are between assigning a hard-coded
> value vs. assingnimg the corresponding function result. I don't know what
> that means.
> }}}
<eucode>
> global constant
>    E          = machine_func(47, {105,87,20,139,10,191,5,64}),     --
>    2.7182818284590452e0
>    PI         = machine_func(47, {24,45,68,84,251,33,9,64}),       --
>    3.1415926535897932e0
> 
>    LN2        = machine_func(47, {239,57,250,254,66,46,230,63}),   --
>    0.6931471805599453e0
>    LN10       = machine_func(47, {21,85,181,187,177,107,2,64}),    --
>    2.3025850929940456e0
>    SQRT2      = machine_func(47, {204,59,127,102,158,160,246,63}), --
>    1.4142135623730950e0
>    HALF_SQRT2 = machine_func(47, {204,59,127,102,158,160,230,63}), --
>    0.7071067811865475e0
>    HALF_PI    = machine_func(47, {24,45,68,84,251,33,249,63}),     --
>    1.5707963267948966e0
>    QUARTER_PI = machine_func(47, {24,45,68,84,251,33,233,63}),     --
>    0.7853981633974483e0
>    TWO_PI     = machine_func(47, {24,45,68,84,251,33,25,64}),      --
>    6.2831853071795864e0
> 
>    LN2_test        = log(2),
>    LN10_test       = log(10),
>    SQRT2_test      = sqrt(2),
>    HALF_SQRT2_test = SQRT2/2,
>    HALF_PI_test    = PI/2, 
>    QUARTER_PI_test = PI/4, 
>    TWO_PI_test     = PI*2 
> 
> 
> ? compare( LN2       , LN2_test )
> ? compare( LN10      , LN10_test )          -- LN10_test  is bigger!
> ? compare( SQRT2     , SQRT2_test )         -- SQRT2_test is bigger!
> ? compare( HALF_SQRT2, HALF_SQRT2_test )
> ? compare( HALF_PI   , HALF_PI_test ) 
> ? compare( QUARTER_PI, QUARTER_PI_test ) 
> ? compare( TWO_PI    , TWO_PI_test ) 
> </eucode>
{{{

> Tested with EXW.EXE 3.0.2.

I changed the first byte of both constants, and now the values
are equal.
global constant
-- LN10       = machine_func(47, {21,85,181,187,177,107,2,64}),    -- old
LN10       = machine_func(47, {22,85,181,187,177,107,2,64}),    --
   2.3025850929940456e0
-- SQRT2      = machine_func(47, {204,59,127,102,158,160,246,63}), -- old
SQRT2      = machine_func(47, {205,59,127,102,158,160,246,63}), --
   1.4142135623730950e0

   LN10_test  = log(10),
   SQRT2_test = sqrt(2)


? compare( LN10 , LN10_test )
? compare( SQRT2, SQRT2_test )

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

47. Re: New proposal for math.e

Jason Gade wrote:

<snip>

> Juergen Luethje wrote:
> > 
> > Pete Lomax wrote:
> > 
> > > Juergen Luethje wrote:
> > > (I am a bit allergic to machine_func(47 etc, but it is not
> > > life-threatening)
> > 
> > I also think it's better readable. float64_to_atom() would require
> >    include machine.e
> > I think that was the reason for not using it. But that include statement
> > should not cause any problem, should it?
> 
> I think it's just for namespace reasons, or if you want to use safe.e instead
> of machine.e. It shouldn't really be problem though.

<snip>

Maybe the following would be a good compromise:
constant FLOAT64_TO_ATOM = 47

global constant
LN10 = machine_func(FLOAT64_TO_ATOM, {22,85,181,187,177,107,2,64}),    --
   2.3025850929940456e0
   ...

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

48. Re: New proposal for math.e

No differenced anymore!  *LOL*
constant FLOAT64_TO_ATOM = 47

global constant
   E          = 2.7182818284590452,
   PI         = 3.1415926535897932,
   LN2        = log(2),
   LN10       = log(10),
   SQRT2      = sqrt(2),
   HALF_SQRT2 = sqrt(2)/2,
   HALF_PI    = PI/2, 
   QUARTER_PI = PI/4, 
   TWO_PI     = PI*2, 

   E_f          = machine_func(FLOAT64_TO_ATOM, {105,87,20,139,10,191,5,64}),
   PI_f         = machine_func(FLOAT64_TO_ATOM, {24,45,68,84,251,33,9,64}),
   LN2_f        = machine_func(FLOAT64_TO_ATOM, {239,57,250,254,66,46,230,63}),
   LN10_f       = machine_func(FLOAT64_TO_ATOM, {22,85,181,187,177,107,2,64}),
SQRT2_f      = machine_func(FLOAT64_TO_ATOM,
   {205,59,127,102,158,160,246,63}),
HALF_SQRT2_f = machine_func(FLOAT64_TO_ATOM,
   {205,59,127,102,158,160,230,63}),
   HALF_PI_f    = machine_func(FLOAT64_TO_ATOM, {24,45,68,84,251,33,249,63}),
   QUARTER_PI_f = machine_func(FLOAT64_TO_ATOM, {24,45,68,84,251,33,233,63}),
   TWO_PI_f     = machine_func(FLOAT64_TO_ATOM, {24,45,68,84,251,33,25,64})

? compare( E         , E_f )
? compare( PI        , PI_f )
? compare( LN2       , LN2_f )
? compare( LN10      , LN10_f )
? compare( SQRT2     , SQRT2_f )
? compare( HALF_SQRT2, HALF_SQRT2_f )
? compare( HALF_PI   , HALF_PI_f ) 
? compare( QUARTER_PI, QUARTER_PI_f ) 
? compare( TWO_PI    , TWO_PI_f ) 

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

49. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> Jason Gade wrote:
> 
> <snip>
> 
> > Juergen Luethje wrote:
> > > 
> > > Pete Lomax wrote:
> > > 
> > > > Juergen Luethje wrote:
> > > > (I am a bit allergic to machine_func(47 etc, but it is not
> > > > life-threatening)
> > > 
> > > I also think it's better readable. float64_to_atom() would require
> > >    include machine.e
> > > I think that was the reason for not using it. But that include statement
> > > should not cause any problem, should it?
> > 
> > I think it's just for namespace reasons, or if you want to use safe.e
> > instead
> > of machine.e. It shouldn't really be problem though.
> 
> <snip>
> 
> Maybe the following would be a good compromise:
> }}}
<eucode>
> constant FLOAT64_TO_ATOM = 47
> 
> global constant
>    LN10 = machine_func(FLOAT64_TO_ATOM, {22,85,181,187,177,107,2,64}),    --
>    2.3025850929940456e0
>    ...
> </eucode>
{{{

> Regards,
>    Juergen

Or M_FLOAT64_TO_ATOM, since that's how it's named elsewhere. But this solution
is probably the best.

CChris

new topic     » goto parent     » topic index » view message » categorize

50. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> Colin Taylor wrote:
> 
> <snip>
> >        
> > In the above functions, angle is expressed in radians, increasing in a
> > clockwise
> > direction from east.
> > 
> > Regards,  Colin   (now returning to deep lurk mode)
> 
> I don't know what you mean by "east" in this context. However, the
> normal math convention is: Increasing positive values of an angle
> correspond to _counter_ clockwise rotation.
> 
> But I've seen now that different textbooks use different conventions
> about the range of values that is used for the angle in Polar
> Coordinates. Some books use -PI < a <= PI, while others use
> 0 <= a < 2*PI. Our implementation of the functions will depend on the
> range that we'll allow for the angle.
> 
> Regards,
>    Juergen

When I wrote these functions some years ago I wanted them to be perfectly 
reversable so that data could be transformed in both directions without 
any corruption.  I think I also wanted to adopt the same angle notation 
which was used by another application (don't remember which - possibly 
AutoCAD) so that I could easily import and export data.

I leave it to Juergen or someone else to recommend an angle notation which 
works best with Euphoria, and (if necessary) modify the functions to suit.

Regards,  Colin

new topic     » goto parent     » topic index » view message » categorize

51. Re: New proposal for math.e

Colin Taylor wrote:

> Juergen Luethje wrote:
> > 
> > Colin Taylor wrote:
> > 
> > <snip>
> > >        
> > > In the above functions, angle is expressed in radians, increasing in a
> > > clockwise
> > > direction from east.
> > > 
> > > Regards,  Colin   (now returning to deep lurk mode)
> > 
> > I don't know what you mean by "east" in this context. However, the
> > normal math convention is: Increasing positive values of an angle
> > correspond to _counter_ clockwise rotation.
> > 
> > But I've seen now that different textbooks use different conventions
> > about the range of values that is used for the angle in Polar
> > Coordinates. Some books use -PI < a <= PI, while others use
> > 0 <= a < 2*PI. Our implementation of the functions will depend on the
> > range that we'll allow for the angle.
> > 
> > Regards,
> >    Juergen
> 
> When I wrote these functions some years ago I wanted them to be perfectly 
> reversable so that data could be transformed in both directions without 
> any corruption.  I think I also wanted to adopt the same angle notation 
> which was used by another application (don't remember which - possibly 
> AutoCAD) so that I could easily import and export data.
> 
> I leave it to Juergen or someone else to recommend an angle notation which 
> works best with Euphoria, and (if necessary) modify the functions to suit.
> 
> Regards,  Colin

Helo Colin,

in the meantime, I've looked closer to this stuff, and I think
when rect_to_polar() returns an angle between -PI and +PI, like
yours code does, this is probably the most straightforward way.
I'd like to read an opinion of a mathematician, though.

What I'd actually like to change in rect_to_polar() is the return
value for the angle, when both x and y are 0. In this case the angle
is undefined. This would be again a good case for having 'nil' or
'nan' available in Euphoria. We don't have it, but I think at least
it's better to assign 0 to the angle in this case, rather than HALF_PI.
And the docs should contain something like this:
| Note: A calling program should firstly check the
|       'distance' value of the result. If it is 0, then the
|       'angle' value of the result is actually undefined.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

52. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> Colin Taylor wrote:
> 
> > Juergen Luethje wrote:
> > > 
> > > Colin Taylor wrote:
> > > 
> > > <snip>
> > > >        
> > > > In the above functions, angle is expressed in radians, increasing in a
> > > > clockwise
> > > > direction from east.
> > > > 
> > > > Regards,  Colin   (now returning to deep lurk mode)
> > > 
> > > I don't know what you mean by "east" in this context. However, the
> > > normal math convention is: Increasing positive values of an angle
> > > correspond to _counter_ clockwise rotation.
> > > 
> > > But I've seen now that different textbooks use different conventions
> > > about the range of values that is used for the angle in Polar
> > > Coordinates. Some books use -PI < a <= PI, while others use
> > > 0 <= a < 2*PI. Our implementation of the functions will depend on the
> > > range that we'll allow for the angle.
> > > 
> > > Regards,
> > >    Juergen
> > 
> > When I wrote these functions some years ago I wanted them to be perfectly 
> > reversable so that data could be transformed in both directions without 
> > any corruption.  I think I also wanted to adopt the same angle notation 
> > which was used by another application (don't remember which - possibly 
> > AutoCAD) so that I could easily import and export data.
> > 
> > I leave it to Juergen or someone else to recommend an angle notation which 
> > works best with Euphoria, and (if necessary) modify the functions to suit.
> > 
> > Regards,  Colin
> 
> Helo Colin,
> 
> in the meantime, I've looked closer to this stuff, and I think
> when rect_to_polar() returns an angle between -PI and +PI, like
> yours code does, this is probably the most straightforward way.
> I'd like to read an opinion of a mathematician, though.
> 
> What I'd actually like to change in rect_to_polar() is the return
> value for the angle, when both x and y are 0. In this case the angle
> is undefined. This would be again a good case for having 'nil' or
> 'nan' available in Euphoria. We don't have it, but I think at least
> it's better to assign 0 to the angle in this case, rather than HALF_PI.
> And the docs should contain something like this:
> | Note: A calling program should firstly check the
> |       'distance' value of the result. If it is 0, then the
> |       'angle' value of the result is actually undefined.
> 
> Regards,
>    Juergen

You may take a look at the corresponding routines I wrote in complex.e - you can
find it at oedoc.free.fr/Fichiers/ESL/complex.zip . Obviously, it would need some
rewriting if you wanted to use it, because it takes its argument from the
sequence representing a complex number.

As far as I know:
* When counting in radians, angles go from -PI excluded to +PI included,
counterclockwise. The point at rectangular coordinates (1,0) defines the 0 angle.
* When counting in degrees, the usage is to count from 0 to 360° rather, with
the point at (0,1) defining the 0 (North) angle, counting clockwise.
* Some schoolbooks use a mixed thing where angles start from (1,0) and go from 0
to 360° counterclockwise, probably to ease transition from degrees to radians. I
hope they have stopped this confusing course; they were doing that some 30-40
years ago. At the very least, it's a high school only thing.

So perhaps you'll wish to include a parameter in the rect_to_polar() and
polar_to_rect() which says which of the two angle representations is being used,
either as input or output. Or use two separate sets of functions, but this looks
clumsier to me. Yet it's an option, and would be faster (one test less, and one
passed parameter less).

In the framework of the ESL, errors were reported by the library to stderr and
caused an abort(); that's what you'll find in the code. Here, we may return an
invalid value for the angle, namely {}. It's the sort of non portable NIL we have
been using from day one, and we won't have it before long, if it ever happens -
which isn't guaranteed in any way.

CChris

new topic     » goto parent     » topic index » view message » categorize

53. Re: New proposal for math.e

CChris wrote:

<snip>

> You may take a look at the corresponding routines I wrote in complex.e - you
> can find it at oedoc.free.fr/Fichiers/ESL/complex.zip . Obviously, it would
> need some rewriting if you wanted to use it, because it takes its argument
> from
> the sequence representing a complex number.

In "complex.zip" I couldn't see what range is used for the angles.

> As far as I know:
> * When counting in radians, angles go from -PI excluded to +PI included,
> counterclockwise.

This is the same as what is used in the Russian textbook by
Bronstein, Semendjajew, Musiol, Mühlig. And the same as Colin
proposed.

> The point at rectangular coordinates (1,0) defines the 0 angle.
> * When counting in degrees, the usage is to count from 0 to 360° rather, with
> the point at (0,1) defining the 0 (North) angle, counting clockwise.
> * Some schoolbooks use a mixed thing where angles start from (1,0) and go from
> 0 to 360° counterclockwise, probably to ease transition from degrees to
> radians.
> I hope they have stopped this confusing course; they were doing that some
> 30-40
> years ago. At the very least, it's a high school only thing.
> 
> So perhaps you'll wish to include a parameter in the rect_to_polar() and
> polar_to_rect()
> which says which of the two angle representations is being used, either as
> input
> or output. Or use two separate sets of functions, but this looks clumsier to
> me. Yet it's an option, and would be faster (one test less, and one passed
> parameter
> less).

I think rect_to_polar() and polar_to_rect() just should use radians.
For conversion we already have radians_to_degrees() and degrees_to_radians().
So it's not necessary to build a conversion option into every routine that
deals with angels, or to write two versions of those routines.

> In the framework of the ESL, errors were reported by the library to stderr and
> caused an abort(); that's what you'll find in the code. Here, we may return
> an invalid value for the angle, namely {}.

I also thought of that. It is rather strict, but probably the
clearest way to express "Here is not a (valid) number."

> It's the sort of non portable NIL
> we have been using from day one, and we won't have it before long, if it ever
> happens - which isn't guaranteed in any way.
> 
> CChris

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

54. Re: New proposal for math.e

Juergen Luethje wrote:
> 
> Helo Colin,
> 
> in the meantime, I've looked closer to this stuff, and I think
> when rect_to_polar() returns an angle between -PI and +PI, like
> yours code does, this is probably the most straightforward way.
> I'd like to read an opinion of a mathematician, though.
> 
> What I'd actually like to change in rect_to_polar() is the return
> value for the angle, when both x and y are 0. In this case the angle
> is undefined. This would be again a good case for having 'nil' or
> 'nan' available in Euphoria. We don't have it, but I think at least
> it's better to assign 0 to the angle in this case, rather than HALF_PI.
> And the docs should contain something like this:
> | Note: A calling program should firstly check the
> |       'distance' value of the result. If it is 0, then the
> |       'angle' value of the result is actually undefined.
> 
> Regards,
>    Juergen

Sure, when x anf y are 0 the angle is undefined, but does it really matter?  
It isn't an error.  If you set the angle to any legal value (such as 0), it
will translate in both directions.  I don't see how this would ever be a 
problem.

Regards,  Colin

new topic     » goto parent     » topic index » view message » categorize

55. Re: New proposal for math.e

Colin Taylor wrote:

> Juergen Luethje wrote:
> > 
> > Helo Colin,
> > 
> > in the meantime, I've looked closer to this stuff, and I think
> > when rect_to_polar() returns an angle between -PI and +PI, like
> > yours code does, this is probably the most straightforward way.
> > I'd like to read an opinion of a mathematician, though.
> > 
> > What I'd actually like to change in rect_to_polar() is the return
> > value for the angle, when both x and y are 0. In this case the angle
> > is undefined. This would be again a good case for having 'nil' or
> > 'nan' available in Euphoria. We don't have it, but I think at least
> > it's better to assign 0 to the angle in this case, rather than HALF_PI.
> > And the docs should contain something like this:
> > | Note: A calling program should firstly check the
> > |       'distance' value of the result. If it is 0, then the
> > |       'angle' value of the result is actually undefined.
> > 
> > Regards,
> >    Juergen
> 
> Sure, when x anf y are 0 the angle is undefined, but does it really matter?
>  
> It isn't an error.  If you set the angle to any legal value (such as 0), it
> will translate in both directions.  I don't see how this would ever be a 
> problem.

Yes it will translate in both directions, but a program might use the
result of rect_to_polar() not only as input for polar_to_rect() but also
for other purposes. So the result should be mathematically correct.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu