Proposal for 'math.e' (2007-08-23)
This is my current (2007-08-23) proposal for a "math.e" standard
include file, according to the discussion here on EUforum.
Changes compared to the previous version:
- Changed function sum(), so that it can't only add numbers,
but also sequences.
- Fixed a glitch in function rect_to_polar().
global constant
E = 2.7182818284590452,
PI = 3.1415926535897932,
EULER_GAMMA = 0.57721566490153286, -- Euler-Mascheroni constant
LN2 = log(2),
LN10 = log(10),
SQRT2 = sqrt(2),
HALF_SQRT2 = SQRT2/2.0,
HALF_PI = PI/2.0,
QUARTER_PI = PI/4.0,
TWO_PI = PI*2.0,
EULER_NORMAL = 1/sqrt(TWO_PI)
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 -- log(x)/LN2 is imprecise in this case
elsif x = #80000000 then
return 31 -- log(x)/LN2 is imprecise in this case
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
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 logarithm function
-- in : x : (sequence of) atom(s) > 0
-- base: atom > 0 and != 1
-- out : (sequence of) atom(s)
-- Note: If x = 1 then the function returns 0 for any possible base.
return log(x)/log(base)
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
type sequence_of_a_xor_s (object x)
-- A sequence whose top-level elements are either only atoms or only
-- sequences (or which is empty).
integer object_type
if atom(x) then
return 0
end if
if length(x) = 0 then
return 1
end if
object_type = atom(x[1])
for i = 2 to length(x) do
if object_type != atom(x[i]) then
return 0
end if
end for
return 1
end type
global function sum (sequence_of_a_xor_s list)
-- Return the sum of all elements in 'list'.
-- Note: This does not do a recursive sum of sub-sequences.
object ret
if length(list) = 0 then
return 0
end if
ret = list[1]
for i = 2 to length(list) do
ret += list[i]
end for
return ret
end function
constant RADIANS_TO_DEGREES = 180.0/PI
global function radians_to_degrees (object x)
-- in : (sequence of) angle(s) in radians
-- out: (sequence of) angle(s) in degrees
return x * RADIANS_TO_DEGREES
end function
constant DEGREES_TO_RADIANS = PI/180.0
global function degrees_to_radians (object x)
-- in : (sequence of) angle(s) in degrees
-- out: (sequence of) angle(s) in radians
return x * DEGREES_TO_RADIANS
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
type point_pol (object x)
if sequence(x) and (length(x) = 2)
and atom(x[1]) and (x[1] >= 0)
and atom(x[2]) then
return 1
end if
return 0
end type
global function polar_to_rect (point_pol p)
-- convert polar coordinates to rectangular coordinates
-- in : sequence of two atoms: {distance, angle};
-- 'distance' must be >= 0, 'angle' is in radians
-- out: sequence of two atoms: {x, y}
atom distance, angle, x, y
distance = p[1]
angle = p[2]
x = distance*cos(angle)
y = distance*sin(angle)
return {x, y}
end function
type point_xy (object x)
if sequence(x) and (length(x) = 2)
and atom(x[1])
and atom(x[2]) then
return 1
end if
return 0
end type
global function rect_to_polar (point_xy p)
-- convert rectangular coordinates to polar coordinates
-- in : sequence of two atoms: {x, y}
-- out: sequence of two atoms: {distance, angle}
-- - 'distance' is always >= 0
-- - 'angle' is an atom that expresses radians,
-- and is in the half-closed interval ]-PI,+PI].
-- If 'distance' equals 0, then 'angle' is undefined.
object angle
atom distance, x, y
x = p[1]
y = p[2]
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
else
if y < 0 then
angle = -HALF_PI
elsif y > 0 then
angle = HALF_PI
else
angle = 0 -- The angle is undefined in this case.
end if
end if
return {distance, angle}
end function
global function find_min (sequence list, integer start)
-- Search for the minimum 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_max (sequence list, integer start)
-- Search for the maximum 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 min (sequence list, integer start)
-- Search for the minimum 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 max (sequence list, integer start)
-- Search for the maximum 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
Regards,
Juergen
|
Not Categorized, Please Help
|
|