Skip to content

Commit

Permalink
math: Implementation of the math module using more modern syntax
Browse files Browse the repository at this point in the history
The math module is one of the easiest modules to convert to the "new" syntax for
module specifications.

Functions there are lifted from `<math.h>` on Linux. Presumably, the functions
are generally available on all platforms. In the long run, it would be
interesting to write all of them in XL, but for now it's mostly a waste of time.

Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
  • Loading branch information
c3d committed Jul 1, 2021
1 parent 1e2a64d commit 8a4e81e
Show file tree
Hide file tree
Showing 9 changed files with 423 additions and 150 deletions.
109 changes: 82 additions & 27 deletions native/lib/xl.math.xl
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,89 @@
// If not, see <https://www.gnu.org/licenses/>.
// *****************************************************************************

MATH is
// ----------------------------------------------------------------------------
// Implementation of the math module
// ----------------------------------------------------------------------------
with
X:real
Y:real
Z:real
N:natural
I:integer
Base:real

// Basic math functions
abs X:integer as integer is builtin IAbs
abs X:real as real is builtin FAbs
sqrt X:real as real is C sqrt
// Generic implementation of abs and sign
generic_abs T is (if T < 0 then -T else T)
generic_sign T is (if T < 0 then -1 else if T > 0 then 1 else 0)

sin X:real as real is C sin
cos X:real as real is C cos
tan X:real as real is C tan
asin X:real as real is C asin
acos X:real as real is C acos
atan X:real as real is C atan
atan Y:real, X:real as real is C atan2
abs I as integer is generic_abs I
sign I as integer is generic_sign I
abs X as real is generic_abs X
sign X as real is generic_sign X

sinh X:real as real is C sinh
cosh X:real as real is C cosh
tanh X:real as real is C tanh
asinh X:real as real is C asinh
acosh X:real as real is C acosh
atanh X:real as real is C atanh
// Nearest integer
ceil X as real is C "ceil"
floor X as real is C "floor"

exp X:real as real is C exp
expm1 X:real as real is C expm1
log X:real as real is C log
log10 X:real as real is C log10
log2 X:real as real is C log2
log1p X:real as real is C log1p
// C interface for base functions
sqrt X as real is C "sqrt"
exp X as real is C "exp"
exp2 X as real is C "exp2"
log X as real is C "log"
ln X as real is log X
log10 X as real is C "log10"
log2 X as real is C "log2"
logb X as integer is C "logb"
log(Base,X) as real is (log X / log Base)
hypot(X,Y) as real is C "hypot"
cbrt X as real is C "cbrt"
erf X as real is C "erf"
lgamma X as real is C "lgamma"
fma X,Y,Z as real is C "fma"

// Circular trigonometry
sin X as real is C "sin"
cos X as real is C "cos"
tan X as real is C "tan"
asin X as real is C "asin"
acos X as real is C "acos"
atan X as real is C "atan"
atan Y/X as real is C "atan2"

// Hyperbolic trigonometry
sinh X as real is C "sinh"
cosh X as real is C "cosh"
tanh X as real is C "tanh"
asinh X as real is C "asinh"
acosh X as real is C "acosh"
atanh X as real is C "atanh"

// Bessel functions
j0 X as real is C "j0"
j1 X as real is C "j1"
jn I, X as real is C "jn"
y0 X as real is C "y0"
y1 X as real is C "y1"
yn I, X as real is C "yn"

// Optimized forms
(exp X)-1.0 as real is C "expm1"
log (1.0+X) as real is C "log1p"
log (X+1.0) as real is C "log1p"
2.0^X as real is C "exp2"

// Constants
pi is 3.1415926535897932384626433
e is 2.7182818284590452353602875

// Optimized expressions
// constant (log2 [[e]]) is 1.442695040888963407359924681001892137

This comment has been minimized.

Copy link
@dumblob

dumblob Jul 2, 2021

Why is actually constant needed here? Shouldn't pattern matching itself be enough to "change" log2 [[e]] to 1.442695040888963...? Or is it because of ambiguity through precision?

This comment has been minimized.

Copy link
@c3d

c3d Jul 2, 2021

Author Owner

This is not really needed. It’s an implementation hint, suggesting to use a constant rather than, say, a function. See https://xlr.sourceforge.io/#implementations-hints

// constant (log10 [[e]]) is 0.434294481903251827651128918916605082
// constant (log 2.0) is 0.693147180559945309417232121458176568
// constant (pi/2.0) is 1.570796326794896619231321691639751442
// constant (pi/4.0) is 0.785398163397448309615660845819875721
// constant (pi*0.5) is constant(pi/2.0)
// constant (pi*0.25) is constant(pi/4.0)
// constant (1.0/[[pi]]) is 0.318309886183790671537767526745028724
// constant (2.0/[[pi]]) is 0.636619772367581343075535053490057448
// constant (2.0/sqrt [[pi]]) is 1.128379167095512573896158903121545172
// constant (sqrt 2.0) is 1.414213562373095048801688724209698079
// constant (1.0/sqrt 2.0) is 0.707106781186547524400844362104849039
// constant (sqrt 2.0/2.0) is 0.707106781186547524400844362104849039
141 changes: 88 additions & 53 deletions native/lib/xl.math.xs
Original file line number Diff line number Diff line change
Expand Up @@ -34,64 +34,99 @@
// If not, see <https://www.gnu.org/licenses/>.
// *****************************************************************************

module ARBITRARY_PRECISION
with
X:real
Y:real
Z:real
N:natural
I:integer
Base:real

module COMPLEX
module QUATERNION
module VECTOR
module MATRIX
module STATISTICS
// Functions on integer values
abs I as integer
sign I as integer

// Functions on real values
abs X as real
sign X as real
ceil X as real
floor X as real
sqrt X as real
exp X as real
exp2 X as real
log X as real
ln X as real
log10 X as real
log2 X as real
logb X as integer
log(Base,X) as real
hypot(X,Y) as real
hypothenuse(X,Y)as real is hypot(X,Y)
cbrt X as real
CubeRoot X as real is cbrt X
erf X as real
ErrorFunction X as real is erf X
lgamma X as real
LogGamma X as real is lgamma X
fma X,Y,Z as real
X*Y+Z as real is fma X,Y,Z
Z+X*Y as real is fma X,Y,Z

// Using the `MATH` module by default uses `real` functions and constants
use REAL
use MATH[real].FUNCTIONS
use MATH[real].CONSTANTS
// Circular trigonometry
sin X as real
cos X as real
tan X as real
asin X as real
acos X as real
atan X as real
atan Y/X as real

// Hyperbolic trigonometry
sinh X as real
cosh X as real
tanh X as real
asinh X as real
acosh X as real
atanh X as real

module MATH[type number] with
// ----------------------------------------------------------------------------
// Interface of the math module for a given number type
// ----------------------------------------------------------------------------
// Bessel functions
j0 X as real
j1 X as real
jn I, X as real
J 0, X as real is j0 X
J 1, X as real is j1 X
J I, X as real is jn I,X
y0 X as real
y1 X as real
yn I, X as real
Y 0, X as real is y0 X
Y 1, X as real is y1 X
Y I, X as real is yn I, X

module FUNCTIONS with
// ------------------------------------------------------------------------
// Interface for basic math functions
// ------------------------------------------------------------------------
// Optimized forms
(exp X) - 1.0 as real
log (1.0+X) as real
log (X+1.0) as real
2.0^X as real

Abs X:number as number
Sign X:number as integer
Sqrt X:number as number
// Constants
pi
e

Sin X:number as number
Cos X:number as number
Tan X:number as number
ArcSin X:number as number
ArcCos X:number as number
ArcTan X:number as number
ArcTan Y:number, X:number as number

SinH X:number as number
CosH X:number as number
TanH X:number as number
ArcSinH X:number as number
ArcCosH X:number as number
ArcTanH X:number as number

Exp X:number as number
Exp X:number - 1 as number
Log X:number as number
Log10 X:number as number
Log2 X:number as number
Log2i X:number as integer
Log (1 + X:number) as number


module CONSTANTS is
// ------------------------------------------------------------------------
// Interface for math constants
// ------------------------------------------------------------------------
ZERO is number 0
ONE is number 1
TWO is number 2
PI is number 3.1415926535897932384626433
// Optimized expressions
// constant (log2 [[e]])
// constant (log10 [[e]])
// constant (log 2.0)
// constant (pi/2.0)
// constant (pi/4.0)
// constant (pi*0.5)
// constant (pi*0.25)
// constant (1.0/[[pi]])
// constant (2.0/[[pi]])
// constant (2.0/sqrt [[pi]])
// constant (1.0/[[pi]])
// constant (2.0/[[pi]])
// constant (2.0/sqrt [[pi]])
// constant (sqrt 2.0)
// constant (1.0/sqrt 2.0)
// constant (sqrt 2.0/2.0)
19 changes: 2 additions & 17 deletions src/builtins.xl
Original file line number Diff line number Diff line change
Expand Up @@ -150,23 +150,8 @@ Source:text from First:natural as text is text_range(Source, First, not 0)
parse Source:text is C "xl_parse_text"

// Basic math functions
abs X is if X < 0 then -X else X
pi is 3.1415926535897932384626433
sin X:real as real is C "sin"
cos X:real as real is C "cos"
tan X:real as real is C "tan"
asin X:real as real is C "asin"
acos X:real as real is C "acos"
atan X:real as real is C "atan"
exp X:real as real is C "exp"
exp2 X:real as real is C "exp2"
expm1 X:real as real is C "expm1"
log X:real as real is C "log"
log2 X:real as real is C "log2"
log10 X:real as real is C "log10"
log1p X:real as real is C "log1p"
sqrt X:real as real is C "sqrt"
atan Y:real / X:real as real is C "atan2"
abs X is if X < 0 then -X else X
sign X is if X < 0 then -1 else if X > 0 then 1 else 0

// If-then-else statement
if [[true]] then True else False is True
Expand Down
59 changes: 50 additions & 9 deletions src/posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,62 @@ double fn(double x, double y) \
NATIVE(fn); \
}

MATH(sin);
MATH(cos);
MATH(tan);
MATH(asin);
MATH(acos);
MATH(atan);
#define MATH2I(fn) \
namespace \
{ \
double fn(int x, double y) \
{ \
return ::fn(x, y); \
} \
NATIVE(fn); \
}

#define MATH3(fn) \
namespace \
{ \
double fn(double x, double y, double z) \
{ \
return ::fn(x, y, z); \
} \
NATIVE(fn); \
}

MATH(ceil);
MATH(floor);
MATH(sqrt);
MATH(exp);
MATH(expm1);
MATH(exp2);
MATH(expm1);
MATH(log);
MATH(log2);
MATH(log10);
MATH(log1p);
MATH(sqrt);
MATH2(atan2);
MATH(logb);
MATH2(hypot);
MATH(cbrt);
MATH(erf);
MATH(lgamma);
MATH3(fma);
MATH2(pow);

MATH(sin);
MATH(cos);
MATH(tan);
MATH(asin);
MATH(acos);
MATH(atan);
MATH2(atan2);
MATH(sinh);
MATH(cosh);
MATH(tanh);
MATH(asinh);
MATH(acosh);
MATH(atanh);
MATH(j0);
MATH(j1);
MATH2I(jn);
MATH(y0);
MATH(y1);
MATH2I(yn);

XL_END
2 changes: 2 additions & 0 deletions tests/01.Evaluation/04-write-types.xl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
// along with XL, in a file named COPYING.
// If not, see <https://www.gnu.org/licenses/>.
// *****************************************************************************
import XL.MATH

print "Hello"
print 'C'
print 12
Expand Down
2 changes: 1 addition & 1 deletion tests/01.Evaluation/bug3327.ref
Original file line number Diff line number Diff line change
@@ -1 +1 @@
23.1407
8.53973
4 changes: 3 additions & 1 deletion tests/01.Evaluation/bug3327.xl
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@
// along with XL, in a file named COPYING.
// If not, see <https://www.gnu.org/licenses/>.
// *****************************************************************************
exp(1) * pi
import XL.MATH

pi * exp(1)
Loading

0 comments on commit 8a4e81e

Please sign in to comment.