mirror of https://github.com/exaloop/codon.git
520 lines
11 KiB
Python
520 lines
11 KiB
Python
e = 2.718281828459045
|
|
pi = 3.141592653589793
|
|
tau = 6.283185307179586
|
|
|
|
inf = 1.0 / 0.0
|
|
nan = 0.0 / 0.0
|
|
|
|
def factorial(x: int) -> int:
|
|
_F = (1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000)
|
|
if not (0 <= x <= 20):
|
|
raise ValueError("factorial is only supported for 0 <= x <= 20")
|
|
return _F[x]
|
|
|
|
def isnan(x: float) -> bool:
|
|
"""
|
|
isnan(float) -> bool
|
|
|
|
Return True if float arg is a NaN, else False.
|
|
"""
|
|
test = x == x
|
|
# if it is true then it is a number
|
|
if test:
|
|
return False
|
|
return True
|
|
|
|
def isinf(x: float) -> bool:
|
|
"""
|
|
isinf(float) -> bool:
|
|
|
|
Return True if float arg is an INF, else False.
|
|
"""
|
|
return x == inf or x == -inf
|
|
|
|
def isfinite(x: float) -> bool:
|
|
"""
|
|
isfinite(float) -> bool
|
|
|
|
Return True if x is neither an infinity nor a NaN,
|
|
and False otherwise.
|
|
"""
|
|
if isnan(x) or isinf(x):
|
|
return False
|
|
return True
|
|
|
|
def ceil(x: float) -> float:
|
|
"""
|
|
ceil(float) -> float
|
|
|
|
Return the ceiling of x as an Integral.
|
|
This is the smallest integer >= x.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.ceil.f64(double)
|
|
%y = call double @llvm.ceil.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def floor(x: float) -> float:
|
|
"""
|
|
floor(float) -> float
|
|
|
|
Return the floor of x as an Integral.
|
|
This is the largest integer <= x.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.floor.f64(double)
|
|
%y = call double @llvm.floor.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def fabs(x: float) -> float:
|
|
"""
|
|
fabs(float) -> float
|
|
|
|
Returns the absolute value of a floating point number.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.fabs.f64(double)
|
|
%y = call double @llvm.fabs.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def fmod(x: float, y: float) -> float:
|
|
"""
|
|
fmod(float, float) -> float
|
|
|
|
Returns the remainder of x divided by y.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float, y: float) -> float:
|
|
%z = frem double %x, %y
|
|
ret double %z
|
|
|
|
return f(x, y)
|
|
|
|
def exp(x: float) -> float:
|
|
"""
|
|
exp(float) -> float
|
|
|
|
Returns the value of e raised to the xth power.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.exp.f64(double)
|
|
%y = call double @llvm.exp.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def expm1(x: float) -> float:
|
|
"""
|
|
expm1(float) -> float
|
|
|
|
Return e raised to the power x, minus 1. expm1 provides
|
|
a way to compute this quantity to full precision.
|
|
"""
|
|
return _C.expm1(x)
|
|
|
|
def ldexp(x: float, i: int) -> float:
|
|
"""
|
|
ldexp(float, int) -> float
|
|
|
|
Returns x multiplied by 2 raised to the power of exponent.
|
|
"""
|
|
return _C.ldexp(x, i)
|
|
|
|
def log(x: float, base: float = e) -> float:
|
|
"""
|
|
log(float) -> float
|
|
|
|
Returns the natural logarithm (base-e logarithm) of x.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.log.f64(double)
|
|
%y = call double @llvm.log.f64(double %x)
|
|
ret double %y
|
|
|
|
if base == e:
|
|
return f(x)
|
|
else:
|
|
return f(x)/f(base)
|
|
|
|
def log2(x: float) -> float:
|
|
"""
|
|
log2(float) -> float
|
|
|
|
Return the base-2 logarithm of x.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.log2.f64(double)
|
|
%y = call double @llvm.log2.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def log10(x: float) -> float:
|
|
"""
|
|
log10(float) -> float
|
|
|
|
Returns the common logarithm (base-10 logarithm) of x.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.log10.f64(double)
|
|
%y = call double @llvm.log10.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def degrees(x: float) -> float:
|
|
"""
|
|
degrees(float) -> float
|
|
|
|
Convert angle x from radians to degrees.
|
|
"""
|
|
radToDeg = 180.0/pi
|
|
return x * radToDeg
|
|
|
|
def radians(x: float) -> float:
|
|
"""
|
|
radians(float) -> float
|
|
|
|
Convert angle x from degrees to radians.
|
|
"""
|
|
degToRad = pi/180.0
|
|
return x * degToRad
|
|
|
|
def sqrt(x: float) -> float:
|
|
"""
|
|
sqrt(float) -> float
|
|
|
|
Returns the square root of x.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.sqrt.f64(double)
|
|
%y = call double @llvm.sqrt.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def pow(x: float, y: float) -> float:
|
|
"""
|
|
pow(float, float) -> float
|
|
|
|
Returns x raised to the power of y.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float, y: float) -> float:
|
|
declare double @llvm.pow.f64(double, double)
|
|
%z = call double @llvm.pow.f64(double %x, double %y)
|
|
ret double %z
|
|
|
|
return f(x, y)
|
|
|
|
def acos(x: float) -> float:
|
|
"""
|
|
acos(float) -> float
|
|
|
|
Returns the arc cosine of x in radians.
|
|
"""
|
|
return _C.acos(x)
|
|
|
|
def asin(x: float) -> float:
|
|
"""
|
|
asin(float) -> float
|
|
|
|
Returns the arc sine of x in radians.
|
|
"""
|
|
return _C.asin(x)
|
|
|
|
def atan(x: float) -> float:
|
|
"""
|
|
atan(float) -> float
|
|
|
|
Returns the arc tangent of x in radians.
|
|
"""
|
|
return _C.atan(x)
|
|
|
|
def atan2(y: float, x: float) -> float:
|
|
"""
|
|
atan2(float, float) -> float
|
|
|
|
Returns the arc tangent in radians of y/x based
|
|
on the signs of both values to determine the
|
|
correct quadrant.
|
|
"""
|
|
return _C.atan2(y, x)
|
|
|
|
def cos(x: float) -> float:
|
|
"""
|
|
cos(float) -> float
|
|
|
|
Returns the cosine of a radian angle x.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.cos.f64(double)
|
|
%y = call double @llvm.cos.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def sin(x: float) -> float:
|
|
"""
|
|
sin(float) -> float
|
|
|
|
Returns the sine of a radian angle x.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.sin.f64(double)
|
|
%y = call double @llvm.sin.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def hypot(x: float, y: float) -> float:
|
|
"""
|
|
hypot(float, float) -> float
|
|
|
|
Return the Euclidean norm.
|
|
This is the length of the vector from the
|
|
origin to point (x, y).
|
|
"""
|
|
return _C.hypot(x, y)
|
|
|
|
def tan(x: float) -> float:
|
|
"""
|
|
tan(float) -> float
|
|
|
|
Return the tangent of a radian angle x.
|
|
"""
|
|
return _C.tan(x)
|
|
|
|
def cosh(x: float) -> float:
|
|
"""
|
|
cosh(float) -> float
|
|
|
|
Returns the hyperbolic cosine of x.
|
|
"""
|
|
return _C.cosh(x)
|
|
|
|
def sinh(x: float) -> float:
|
|
"""
|
|
sinh(float) -> float
|
|
|
|
Returns the hyperbolic sine of x.
|
|
"""
|
|
return _C.sinh(x)
|
|
|
|
def tanh(x: float) -> float:
|
|
"""
|
|
tanh(float) -> float
|
|
|
|
Returns the hyperbolic tangent of x.
|
|
"""
|
|
return _C.tanh(x)
|
|
|
|
def acosh(x: float) -> float:
|
|
"""
|
|
acosh(float) -> float
|
|
|
|
Return the inverse hyperbolic cosine of x.
|
|
"""
|
|
return _C.acosh(x)
|
|
|
|
def asinh(x: float) -> float:
|
|
"""
|
|
asinh(float) -> float
|
|
|
|
Return the inverse hyperbolic sine of x.
|
|
"""
|
|
return _C.asinh(x)
|
|
|
|
def atanh(x: float) -> float:
|
|
"""
|
|
atanh(float) -> float
|
|
|
|
Return the inverse hyperbolic tangent of x.
|
|
"""
|
|
return _C.atanh(x)
|
|
|
|
def copysign(x: float, y: float) -> float:
|
|
"""
|
|
copysign(float, float) -> float
|
|
|
|
Return a float with the magnitude (absolute value) of
|
|
x but the sign of y.
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float, y: float) -> float:
|
|
declare double @llvm.copysign.f64(double, double)
|
|
%z = call double @llvm.copysign.f64(double %x, double %y)
|
|
ret double %z
|
|
|
|
return f(x, y)
|
|
|
|
def log1p(x: float) -> float:
|
|
"""
|
|
log1p(float) -> float
|
|
|
|
Return the natural logarithm of 1+x (base e).
|
|
"""
|
|
return _C.log1p(x)
|
|
|
|
def trunc(x: float) -> float:
|
|
"""
|
|
trunc(float) -> float
|
|
|
|
Return the Real value x truncated to an Integral
|
|
(usually an integer).
|
|
"""
|
|
@pure
|
|
@llvm
|
|
def f(x: float) -> float:
|
|
declare double @llvm.trunc.f64(double)
|
|
%y = call double @llvm.trunc.f64(double %x)
|
|
ret double %y
|
|
|
|
return f(x)
|
|
|
|
def erf(x: float) -> float:
|
|
"""
|
|
erf(float) -> float
|
|
|
|
Return the error function at x.
|
|
"""
|
|
return _C.erf(x)
|
|
|
|
def erfc(x: float) -> float:
|
|
"""
|
|
erfc(float) -> float
|
|
|
|
Return the complementary error function at x.
|
|
"""
|
|
return _C.erfc(x)
|
|
|
|
def gamma(x: float) -> float:
|
|
"""
|
|
gamma(float) -> float
|
|
|
|
Return the Gamma function at x.
|
|
"""
|
|
return _C.tgamma(x)
|
|
|
|
def lgamma(x: float) -> float:
|
|
"""
|
|
lgamma(float) -> float
|
|
|
|
Return the natural logarithm of
|
|
the absolute value of the Gamma function at x.
|
|
"""
|
|
return _C.lgamma(x)
|
|
|
|
def remainder(x: float, y: float) -> float:
|
|
"""
|
|
remainder(float, float) -> float
|
|
|
|
Return the IEEE 754-style remainder of x with respect to y.
|
|
For finite x and finite nonzero y, this is the difference
|
|
x - n*y, where n is the closest integer to the exact value
|
|
of the quotient x / y. If x / y is exactly halfway between
|
|
two consecutive integers, the nearest even integer is used
|
|
for n.
|
|
"""
|
|
return _C.remainder(x, y)
|
|
|
|
def gcd(a: float, b: float) -> float:
|
|
"""
|
|
gcd(float, float) -> float
|
|
|
|
returns greatest common divisor of x and y.
|
|
"""
|
|
a = abs(a)
|
|
b = abs(b)
|
|
while a:
|
|
a, b = b%a, a
|
|
return b
|
|
|
|
@pure
|
|
def frexp(x: float) -> Tuple[float, int]:
|
|
"""
|
|
frexp(float) -> Tuple[float, int]
|
|
|
|
The returned value is the mantissa and the integer pointed
|
|
to by exponent is the exponent. The resultant value is
|
|
x = mantissa * 2 ^ exponent.
|
|
"""
|
|
tmp = i32(0)
|
|
res = _C.frexp(float(x), __ptr__(tmp))
|
|
return (res, int(tmp))
|
|
|
|
@pure
|
|
def modf(x: float) -> Tuple[float, float]:
|
|
"""
|
|
modf(float) -> Tuple[float, float]
|
|
|
|
The returned value is the fraction component (part after
|
|
the decimal), and sets integer to the integer component.
|
|
"""
|
|
tmp = 0.0
|
|
res = _C.modf(float(x), __ptr__(tmp))
|
|
return (res, tmp)
|
|
|
|
def isclose(a: float, b: float, rel_tol: float = 1e-09, abs_tol: float = 0.0) -> bool:
|
|
"""
|
|
isclose(float, float) -> bool
|
|
|
|
Return True if a is close in value to b, and False otherwise.
|
|
For the values to be considered close, the difference between them
|
|
must be smaller than at least one of the tolerances.
|
|
"""
|
|
|
|
# short circuit exact equality -- needed to catch two
|
|
# infinities of the same sign. And perhaps speeds things
|
|
# up a bit sometimes.
|
|
if a == b:
|
|
return True
|
|
|
|
# This catches the case of two infinities of opposite sign, or
|
|
# one infinity and one finite number. Two infinities of opposite
|
|
# sign would otherwise have an infinite relative tolerance.
|
|
# Two infinities of the same sign are caught by the equality check
|
|
# above.
|
|
if a == inf or b == inf:
|
|
return False
|
|
|
|
# NAN is not close to anything, not even itself
|
|
if a == nan or b == nan:
|
|
return False
|
|
|
|
# regular computation
|
|
diff = fabs(b - a)
|
|
|
|
return (((diff <= fabs(rel_tol * b)) or
|
|
(diff <= fabs(rel_tol * a))) or
|
|
(diff <= abs_tol))
|