From 11399a570e89a97ba8878b02c9f9ba8c7064e54c Mon Sep 17 00:00:00 2001 From: David Schneller Date: Fri, 6 Sep 2024 18:22:14 +0200 Subject: [PATCH] Add Lua math functions --- CMakeLists.txt | 4 +- external/CMakeLists.txt | 29 +++ external/lua51/lmathx.c | 270 ++++++++++++++++++++++++ external/lua52/lmathx.c | 271 ++++++++++++++++++++++++ external/lua53/lmathx.c | 438 +++++++++++++++++++++++++++++++++++++++ src/component/LuaMap.cpp | 48 ++++- 6 files changed, 1056 insertions(+), 4 deletions(-) create mode 100644 external/CMakeLists.txt create mode 100644 external/lua51/lmathx.c create mode 100644 external/lua52/lmathx.c create mode 100644 external/lua53/lmathx.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b371c04..dc45f4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,6 +178,8 @@ if (LUA) target_compile_definitions(easi PRIVATE EASI_USE_LUA) endif() +add_subdirectory(external) + target_include_directories(easi PUBLIC $ @@ -279,7 +281,7 @@ if (TESTING) easi_add_test(3_layered_linear) easi_add_test(33_layered_constant) - if(IMPALA) + if(IMPALAJIT OR LUA) easi_add_test(2_prem) easi_add_test(5_function) easi_add_test(26_function) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt new file mode 100644 index 0000000..c6b5f74 --- /dev/null +++ b/external/CMakeLists.txt @@ -0,0 +1,29 @@ + +if (LUA) + +option(LUA_LMATHX "Compiles in Lua lmathx for more consistent math function support" ON) + +if (LUA_LMATHX) + +enable_language(C) + +message("Enabled Lua lmathx support.") + +if (LUA_VERSION_STRING VERSION_GREATER_EQUAL "5.5") +message(WARNING "You Lua version ${LUA_VERSION_STRING} is newer than the maximum lmathx package version supported (5.4.x). We'll try with the version compatible to 5.4/5.3, but no guarantee on success for that.") +target_sources(easi PRIVATE lua53/lmathx.c) +elseif (LUA_VERSION_STRING VERSION_GREATER_EQUAL "5.3") +target_sources(easi PRIVATE lua53/lmathx.c) +elseif (LUA_VERSION_STRING VERSION_GREATER_EQUAL "5.2") +target_sources(easi PRIVATE lua52/lmathx.c) +elseif (LUA_VERSION_STRING VERSION_GREATER_EQUAL "5.1") +target_sources(easi PRIVATE lua51/lmathx.c) +else() +message(FATAL_ERROR "You Lua version ${LUA_VERSION_STRING} is older than the minimum lmathx package version supported (5.1).") +endif() + +target_compile_definitions(easi PRIVATE EASI_LUA_LMATHX) + +endif() + +endif() diff --git a/external/lua51/lmathx.c b/external/lua51/lmathx.c new file mode 100644 index 0000000..cd61819 --- /dev/null +++ b/external/lua51/lmathx.c @@ -0,0 +1,270 @@ +/* +* lmathx.c +* C99 math functions for Lua +* Luiz Henrique de Figueiredo +* 04 Apr 2010 22:53:32 +* This code is hereby placed in the public domain. +*/ + +#define _GNU_SOURCE 1 +#include +#include + +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" + +#define A(i) luaL_checknumber(L,i) + +static int Lacosh(lua_State *L) +{ + lua_pushnumber(L,acosh(A(1))); + return 1; +} + +static int Lasinh(lua_State *L) +{ + lua_pushnumber(L,asinh(A(1))); + return 1; +} + +static int Latanh(lua_State *L) +{ + lua_pushnumber(L,atanh(A(1))); + return 1; +} + +static int Lcbrt(lua_State *L) +{ + lua_pushnumber(L,cbrt(A(1))); + return 1; +} + +static int Lcopysign(lua_State *L) +{ + lua_pushnumber(L,copysign(A(1),A(2))); + return 1; +} + +static int Lerf(lua_State *L) +{ + lua_pushnumber(L,erf(A(1))); + return 1; +} + +static int Lerfc(lua_State *L) +{ + lua_pushnumber(L,erfc(A(1))); + return 1; +} + +static int Lexp2(lua_State *L) +{ + lua_pushnumber(L,exp2(A(1))); + return 1; +} + +static int Lexpm1(lua_State *L) +{ + lua_pushnumber(L,expm1(A(1))); + return 1; +} + +static int Lfdim(lua_State *L) +{ + lua_pushnumber(L,fdim(A(1),A(2))); + return 1; +} + +static int Lfma(lua_State *L) +{ + lua_pushnumber(L,fma(A(1),A(2),A(3))); + return 1; +} + +static int Lfmax(lua_State *L) +{ + int i,n=lua_gettop(L); + lua_Number m=A(1); + for (i=2; i<=n; i++) m=fmax(m,A(i)); + lua_pushnumber(L,m); + return 1; +} + +static int Lfmin(lua_State *L) +{ + int i,n=lua_gettop(L); + lua_Number m=A(1); + for (i=2; i<=n; i++) m=fmin(m,A(i)); + lua_pushnumber(L,m); + return 1; +} + +static int Lfpclassify(lua_State *L) +{ + switch (fpclassify(A(1))) + { + case FP_INFINITE: lua_pushliteral(L,"inf"); break; + case FP_NAN: lua_pushliteral(L,"nan"); break; + case FP_NORMAL: lua_pushliteral(L,"normal"); break; + case FP_SUBNORMAL: lua_pushliteral(L,"subnormal"); break; + case FP_ZERO: lua_pushliteral(L,"zero"); break; + } + return 1; +} + +static int Lhypot(lua_State *L) +{ + lua_pushnumber(L,hypot(A(1),A(2))); + return 1; +} + +static int Lisfinite(lua_State *L) +{ + lua_pushboolean(L,isfinite(A(1))); + return 1; +} + +static int Lisinf(lua_State *L) +{ + lua_pushboolean(L,isinf(A(1))); + return 1; +} + +static int Lisnan(lua_State *L) +{ + lua_pushboolean(L,isnan(A(1))); + return 1; +} + +static int Lisnormal(lua_State *L) +{ + lua_pushboolean(L,isnormal(A(1))); + return 1; +} + +static int Llgamma(lua_State *L) +{ + lua_pushnumber(L,lgamma(A(1))); + return 1; +} + +static int Llog1p(lua_State *L) +{ + lua_pushnumber(L,log1p(A(1))); + return 1; +} + +static int Llog2(lua_State *L) +{ + lua_pushnumber(L,log2(A(1))); + return 1; +} + +static int Llogb(lua_State *L) +{ + lua_pushnumber(L,logb(A(1))); + return 1; +} + +static int Lnearbyint(lua_State *L) +{ + lua_pushnumber(L,nearbyint(A(1))); + return 1; +} + +static int Lnextafter(lua_State *L) +{ + lua_pushnumber(L,nextafter(A(1),A(2))); + return 1; +} + +static int Lremainder(lua_State *L) +{ + lua_pushnumber(L,remainder(A(1),A(2))); + return 1; +} + +static int Lrint(lua_State *L) +{ + lua_pushnumber(L,rint(A(1))); + return 1; +} + +static int Lround(lua_State *L) +{ + lua_pushnumber(L,round(A(1))); + return 1; +} + +static int Lscalbn(lua_State *L) +{ + lua_pushnumber(L,scalbn(A(1),(int)A(2))); + return 1; +} + +static int Lsignbit(lua_State *L) +{ + lua_pushboolean(L,signbit(A(1))); + return 1; +} + +static int Ltgamma(lua_State *L) +{ + lua_pushnumber(L,tgamma(A(1))); + return 1; +} + +static int Ltrunc(lua_State *L) +{ + lua_pushnumber(L,trunc(A(1))); + return 1; +} + +static const luaL_Reg R[] = +{ + { "acosh", Lacosh }, + { "asinh", Lasinh }, + { "atanh", Latanh }, + { "cbrt", Lcbrt }, + { "copysign", Lcopysign }, + { "erfc", Lerfc }, + { "erf", Lerf }, + { "exp2", Lexp2 }, + { "expm1", Lexpm1 }, + { "fdim", Lfdim }, + { "fma", Lfma }, + { "fmax", Lfmax }, + { "fmin", Lfmin }, + { "fpclassify", Lfpclassify }, + { "gamma", Ltgamma }, + { "hypot", Lhypot }, + { "isfinite", Lisfinite }, + { "isinf", Lisinf }, + { "isnan", Lisnan }, + { "isnormal", Lisnormal }, + { "lgamma", Llgamma }, + { "log1p", Llog1p }, + { "log2", Llog2 }, + { "logb", Llogb }, + { "nearbyint", Lnearbyint }, + { "nextafter", Lnextafter }, + { "remainder", Lremainder }, + { "rint", Lrint }, + { "round", Lround }, + { "scalbn", Lscalbn }, + { "signbit", Lsignbit }, + { "trunc", Ltrunc }, + { NULL, NULL } +}; + + +LUALIB_API int luaopen_mathx(lua_State *L) +{ + luaL_register(L,LUA_MATHLIBNAME,R); + lua_pushnumber(L,INFINITY); + lua_setfield(L,-2,"infinity"); + lua_pushnumber(L,NAN); + lua_setfield(L,-2,"nan"); + return 1; +} diff --git a/external/lua52/lmathx.c b/external/lua52/lmathx.c new file mode 100644 index 0000000..932b4b2 --- /dev/null +++ b/external/lua52/lmathx.c @@ -0,0 +1,271 @@ +/* +* lmathx.c +* C99 math functions for Lua +* Luiz Henrique de Figueiredo +* 19 Apr 2012 19:29:09 +* This code is hereby placed in the public domain. +*/ + +#define _GNU_SOURCE 1 +#include +#include + +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" + +#define A(i) luaL_checknumber(L,i) + +static int Lacosh(lua_State *L) +{ + lua_pushnumber(L,acosh(A(1))); + return 1; +} + +static int Lasinh(lua_State *L) +{ + lua_pushnumber(L,asinh(A(1))); + return 1; +} + +static int Latanh(lua_State *L) +{ + lua_pushnumber(L,atanh(A(1))); + return 1; +} + +static int Lcbrt(lua_State *L) +{ + lua_pushnumber(L,cbrt(A(1))); + return 1; +} + +static int Lcopysign(lua_State *L) +{ + lua_pushnumber(L,copysign(A(1),A(2))); + return 1; +} + +static int Lerf(lua_State *L) +{ + lua_pushnumber(L,erf(A(1))); + return 1; +} + +static int Lerfc(lua_State *L) +{ + lua_pushnumber(L,erfc(A(1))); + return 1; +} + +static int Lexp2(lua_State *L) +{ + lua_pushnumber(L,exp2(A(1))); + return 1; +} + +static int Lexpm1(lua_State *L) +{ + lua_pushnumber(L,expm1(A(1))); + return 1; +} + +static int Lfdim(lua_State *L) +{ + lua_pushnumber(L,fdim(A(1),A(2))); + return 1; +} + +static int Lfma(lua_State *L) +{ + lua_pushnumber(L,fma(A(1),A(2),A(3))); + return 1; +} + +static int Lfmax(lua_State *L) +{ + int i,n=lua_gettop(L); + lua_Number m=A(1); + for (i=2; i<=n; i++) m=fmax(m,A(i)); + lua_pushnumber(L,m); + return 1; +} + +static int Lfmin(lua_State *L) +{ + int i,n=lua_gettop(L); + lua_Number m=A(1); + for (i=2; i<=n; i++) m=fmin(m,A(i)); + lua_pushnumber(L,m); + return 1; +} + +static int Lfpclassify(lua_State *L) +{ + switch (fpclassify(A(1))) + { + case FP_INFINITE: lua_pushliteral(L,"inf"); break; + case FP_NAN: lua_pushliteral(L,"nan"); break; + case FP_NORMAL: lua_pushliteral(L,"normal"); break; + case FP_SUBNORMAL: lua_pushliteral(L,"subnormal"); break; + case FP_ZERO: lua_pushliteral(L,"zero"); break; + } + return 1; +} + +static int Lhypot(lua_State *L) +{ + lua_pushnumber(L,hypot(A(1),A(2))); + return 1; +} + +static int Lisfinite(lua_State *L) +{ + lua_pushboolean(L,isfinite(A(1))); + return 1; +} + +static int Lisinf(lua_State *L) +{ + lua_pushboolean(L,isinf(A(1))); + return 1; +} + +static int Lisnan(lua_State *L) +{ + lua_pushboolean(L,isnan(A(1))); + return 1; +} + +static int Lisnormal(lua_State *L) +{ + lua_pushboolean(L,isnormal(A(1))); + return 1; +} + +static int Llgamma(lua_State *L) +{ + lua_pushnumber(L,lgamma(A(1))); + return 1; +} + +static int Llog1p(lua_State *L) +{ + lua_pushnumber(L,log1p(A(1))); + return 1; +} + +static int Llog2(lua_State *L) +{ + lua_pushnumber(L,log2(A(1))); + return 1; +} + +static int Llogb(lua_State *L) +{ + lua_pushnumber(L,logb(A(1))); + return 1; +} + +static int Lnearbyint(lua_State *L) +{ + lua_pushnumber(L,nearbyint(A(1))); + return 1; +} + +static int Lnextafter(lua_State *L) +{ + lua_pushnumber(L,nextafter(A(1),A(2))); + return 1; +} + +static int Lremainder(lua_State *L) +{ + lua_pushnumber(L,remainder(A(1),A(2))); + return 1; +} + +static int Lrint(lua_State *L) +{ + lua_pushnumber(L,rint(A(1))); + return 1; +} + +static int Lround(lua_State *L) +{ + lua_pushnumber(L,round(A(1))); + return 1; +} + +static int Lscalbn(lua_State *L) +{ + lua_pushnumber(L,scalbn(A(1),(int)A(2))); + return 1; +} + +static int Lsignbit(lua_State *L) +{ + lua_pushboolean(L,signbit(A(1))); + return 1; +} + +static int Ltgamma(lua_State *L) +{ + lua_pushnumber(L,tgamma(A(1))); + return 1; +} + +static int Ltrunc(lua_State *L) +{ + lua_pushnumber(L,trunc(A(1))); + return 1; +} + +static const luaL_Reg R[] = +{ + { "acosh", Lacosh }, + { "asinh", Lasinh }, + { "atanh", Latanh }, + { "cbrt", Lcbrt }, + { "copysign", Lcopysign }, + { "erfc", Lerfc }, + { "erf", Lerf }, + { "exp2", Lexp2 }, + { "expm1", Lexpm1 }, + { "fdim", Lfdim }, + { "fma", Lfma }, + { "fmax", Lfmax }, + { "fmin", Lfmin }, + { "fpclassify", Lfpclassify }, + { "gamma", Ltgamma }, + { "hypot", Lhypot }, + { "isfinite", Lisfinite }, + { "isinf", Lisinf }, + { "isnan", Lisnan }, + { "isnormal", Lisnormal }, + { "lgamma", Llgamma }, + { "log1p", Llog1p }, + { "log2", Llog2 }, + { "logb", Llogb }, + { "nearbyint", Lnearbyint }, + { "nextafter", Lnextafter }, + { "remainder", Lremainder }, + { "rint", Lrint }, + { "round", Lround }, + { "scalbn", Lscalbn }, + { "signbit", Lsignbit }, + { "trunc", Ltrunc }, + { NULL, NULL } +}; + + +LUALIB_API int luaopen_mathx(lua_State *L) +{ + lua_getglobal(L,LUA_MATHLIBNAME); + luaL_setfuncs(L,R,0); + lua_pushnumber(L,INFINITY); + lua_setfield(L,-2,"infinity"); + lua_pushnumber(L,NAN); + lua_setfield(L,-2,"nan"); + return 1; +} diff --git a/external/lua53/lmathx.c b/external/lua53/lmathx.c new file mode 100644 index 0000000..a727eb6 --- /dev/null +++ b/external/lua53/lmathx.c @@ -0,0 +1,438 @@ +/* +* lmathx.c +* C99 math functions for Lua 5.3 +* Luiz Henrique de Figueiredo +* 24 Jun 2015 09:51:50 +* This code is hereby placed in the public domain. +*/ + +#include + +#include "lua.h" +#include "lauxlib.h" + +#define MYNAME "mathx" +#define MYVERSION MYNAME " library for " LUA_VERSION " / Jun 2015" + +#define A(i) luaL_checknumber(L,i) +#define I(i) ((int)luaL_checkinteger(L,i)) + +#undef PI +#define PI (l_mathop(3.141592653589793238462643383279502884)) +#define rad(x) ((x)*(PI/l_mathop(180.0))) +#define deg(x) ((x)*(l_mathop(180.0)/PI)) + +static int Lfmax(lua_State *L) /** fmax */ +{ + int i,n=lua_gettop(L); + lua_Number m=A(1); + for (i=2; i<=n; i++) m=l_mathop(fmax)(m,A(i)); + lua_pushnumber(L,m); + return 1; +} + +static int Lfmin(lua_State *L) /** fmin */ +{ + int i,n=lua_gettop(L); + lua_Number m=A(1); + for (i=2; i<=n; i++) m=l_mathop(fmin)(m,A(i)); + lua_pushnumber(L,m); + return 1; +} + +static int Lfrexp(lua_State *L) /** frexp */ +{ + int e; + lua_pushnumber(L,l_mathop(frexp)(A(1),&e)); + lua_pushinteger(L,e); + return 2; +} + +static int Lldexp(lua_State *L) /** ldexp */ +{ + lua_pushnumber(L,l_mathop(ldexp)(A(1),I(2))); + return 1; +} + +static int Lmodf(lua_State *L) /** modf */ +{ + lua_Number ip; + lua_Number fp=l_mathop(modf)(A(1),&ip); + lua_pushnumber(L,ip); + lua_pushnumber(L,fp); + return 2; +} + +static int Lfabs(lua_State *L) /** fabs */ +{ + lua_pushnumber(L,l_mathop(fabs)(A(1))); + return 1; +} + +static int Lacos(lua_State *L) /** acos */ +{ + lua_pushnumber(L,l_mathop(acos)(A(1))); + return 1; +} + +static int Lacosh(lua_State *L) /** acosh */ +{ + lua_pushnumber(L,l_mathop(acosh)(A(1))); + return 1; +} + +static int Lasin(lua_State *L) /** asin */ +{ + lua_pushnumber(L,l_mathop(asin)(A(1))); + return 1; +} + +static int Lasinh(lua_State *L) /** asinh */ +{ + lua_pushnumber(L,l_mathop(asinh)(A(1))); + return 1; +} + +static int Latan(lua_State *L) /** atan */ +{ + int n=lua_gettop(L); + if (n==1) + lua_pushnumber(L,l_mathop(atan)(A(1))); + else + lua_pushnumber(L,l_mathop(atan2)(A(1),A(2))); + return 1; +} + +static int Latan2(lua_State *L) /** atan2 */ +{ + lua_pushnumber(L,l_mathop(atan2)(A(1),A(2))); + return 1; +} + +static int Latanh(lua_State *L) /** atanh */ +{ + lua_pushnumber(L,l_mathop(atanh)(A(1))); + return 1; +} + +static int Lcbrt(lua_State *L) /** cbrt */ +{ + lua_pushnumber(L,l_mathop(cbrt)(A(1))); + return 1; +} + +static int Lceil(lua_State *L) /** ceil */ +{ + lua_pushnumber(L,l_mathop(ceil)(A(1))); + return 1; +} + +static int Lcopysign(lua_State *L) /** copysign */ +{ + lua_pushnumber(L,l_mathop(copysign)(A(1),A(2))); + return 1; +} + +static int Lcos(lua_State *L) /** cos */ +{ + lua_pushnumber(L,l_mathop(cos)(A(1))); + return 1; +} + +static int Lcosh(lua_State *L) /** cosh */ +{ + lua_pushnumber(L,l_mathop(cosh)(A(1))); + return 1; +} + +static int Ldeg(lua_State *L) /** deg */ +{ + lua_pushnumber(L,deg(A(1))); + return 1; +} + +static int Lerf(lua_State *L) /** erf */ +{ + lua_pushnumber(L,l_mathop(erf)(A(1))); + return 1; +} + +static int Lerfc(lua_State *L) /** erfc */ +{ + lua_pushnumber(L,l_mathop(erfc)(A(1))); + return 1; +} + +static int Lexp(lua_State *L) /** exp */ +{ + lua_pushnumber(L,l_mathop(exp)(A(1))); + return 1; +} + +static int Lexp2(lua_State *L) /** exp2 */ +{ + lua_pushnumber(L,l_mathop(exp2)(A(1))); + return 1; +} + +static int Lexpm1(lua_State *L) /** expm1 */ +{ + lua_pushnumber(L,l_mathop(expm1)(A(1))); + return 1; +} + +static int Lfdim(lua_State *L) /** fdim */ +{ + lua_pushnumber(L,l_mathop(fdim)(A(1),A(2))); + return 1; +} + +static int Lfloor(lua_State *L) /** floor */ +{ + lua_pushnumber(L,l_mathop(floor)(A(1))); + return 1; +} + +static int Lfma(lua_State *L) /** fma */ +{ + lua_pushnumber(L,l_mathop(fma)(A(1),A(2),A(3))); + return 1; +} + +static int Lfmod(lua_State *L) /** fmod */ +{ + lua_pushnumber(L,l_mathop(fmod)(A(1),A(2))); + return 1; +} + +static int Lgamma(lua_State *L) /** gamma */ +{ + lua_pushnumber(L,l_mathop(tgamma)(A(1))); + return 1; +} + +static int Lhypot(lua_State *L) /** hypot */ +{ + lua_pushnumber(L,l_mathop(hypot)(A(1),A(2))); + return 1; +} + +static int Lisfinite(lua_State *L) /** isfinite */ +{ + lua_pushboolean(L,isfinite(A(1))); + return 1; +} + +static int Lisinf(lua_State *L) /** isinf */ +{ + lua_pushboolean(L,isinf(A(1))); + return 1; +} + +static int Lisnan(lua_State *L) /** isnan */ +{ + lua_pushboolean(L,isnan(A(1))); + return 1; +} + +static int Lisnormal(lua_State *L) /** isnormal */ +{ + lua_pushboolean(L,isnormal(A(1))); + return 1; +} + +static int Llgamma(lua_State *L) /** lgamma */ +{ + lua_pushnumber(L,l_mathop(lgamma)(A(1))); + return 1; +} + +static int Llog(lua_State *L) /** log */ +{ + int n=lua_gettop(L); + if (n==1) + lua_pushnumber(L,l_mathop(log)(A(1))); + else + { + lua_Number b=A(2); + if (b==10.0) + lua_pushnumber(L,l_mathop(log10)(A(1))); + else if (b==2.0) + lua_pushnumber(L,l_mathop(log2)(A(1))); + else + lua_pushnumber(L,l_mathop(log)(A(1))/l_mathop(log)(b)); + } + return 1; +} + +static int Llog10(lua_State *L) /** log10 */ +{ + lua_pushnumber(L,l_mathop(log10)(A(1))); + return 1; +} + +static int Llog1p(lua_State *L) /** log1p */ +{ + lua_pushnumber(L,l_mathop(log1p)(A(1))); + return 1; +} + +static int Llog2(lua_State *L) /** log2 */ +{ + lua_pushnumber(L,l_mathop(log2)(A(1))); + return 1; +} + +static int Llogb(lua_State *L) /** logb */ +{ + lua_pushnumber(L,l_mathop(logb)(A(1))); + return 1; +} + +static int Lnearbyint(lua_State *L) /** nearbyint */ +{ + lua_pushnumber(L,l_mathop(nearbyint)(A(1))); + return 1; +} + +static int Lnextafter(lua_State *L) /** nextafter */ +{ + lua_pushnumber(L,l_mathop(nextafter)(A(1),A(2))); + return 1; +} + +static int Lpow(lua_State *L) /** pow */ +{ + lua_pushnumber(L,l_mathop(pow)(A(1),A(2))); + return 1; +} + +static int Lrad(lua_State *L) /** rad */ +{ + lua_pushnumber(L,rad(A(1))); + return 1; +} + +static int Lremainder(lua_State *L) /** remainder */ +{ + lua_pushnumber(L,l_mathop(remainder)(A(1),A(2))); + return 1; +} + +static int Lround(lua_State *L) /** round */ +{ + lua_pushnumber(L,l_mathop(round)(A(1))); + return 1; +} + +static int Lscalbn(lua_State *L) /** scalbn */ +{ + lua_pushnumber(L,l_mathop(scalbn)(A(1),A(2))); + return 1; +} + +static int Lsin(lua_State *L) /** sin */ +{ + lua_pushnumber(L,l_mathop(sin)(A(1))); + return 1; +} + +static int Lsinh(lua_State *L) /** sinh */ +{ + lua_pushnumber(L,l_mathop(sinh)(A(1))); + return 1; +} + +static int Lsqrt(lua_State *L) /** sqrt */ +{ + lua_pushnumber(L,l_mathop(sqrt)(A(1))); + return 1; +} + +static int Ltan(lua_State *L) /** tan */ +{ + lua_pushnumber(L,l_mathop(tan)(A(1))); + return 1; +} + +static int Ltanh(lua_State *L) /** tanh */ +{ + lua_pushnumber(L,l_mathop(tanh)(A(1))); + return 1; +} + +static int Ltrunc(lua_State *L) /** trunc */ +{ + lua_pushnumber(L,l_mathop(trunc)(A(1))); + return 1; +} + +static const luaL_Reg R[] = +{ + { "fabs", Lfabs }, + { "acos", Lacos }, + { "acosh", Lacosh }, + { "asin", Lasin }, + { "asinh", Lasinh }, + { "atan", Latan }, + { "atan2", Latan2 }, + { "atanh", Latanh }, + { "cbrt", Lcbrt }, + { "ceil", Lceil }, + { "copysign", Lcopysign }, + { "cos", Lcos }, + { "cosh", Lcosh }, + { "deg", Ldeg }, + { "erf", Lerf }, + { "erfc", Lerfc }, + { "exp", Lexp }, + { "exp2", Lexp2 }, + { "expm1", Lexpm1 }, + { "fdim", Lfdim }, + { "floor", Lfloor }, + { "fma", Lfma }, + { "fmax", Lfmax }, + { "fmin", Lfmin }, + { "fmod", Lfmod }, + { "frexp", Lfrexp }, + { "gamma", Lgamma }, + { "hypot", Lhypot }, + { "isfinite", Lisfinite }, + { "isinf", Lisinf }, + { "isnan", Lisnan }, + { "isnormal", Lisnormal }, + { "ldexp", Lldexp }, + { "lgamma", Llgamma }, + { "log", Llog }, + { "log10", Llog10 }, + { "log1p", Llog1p }, + { "log2", Llog2 }, + { "logb", Llogb }, + { "modf", Lmodf }, + { "nearbyint", Lnearbyint }, + { "nextafter", Lnextafter }, + { "pow", Lpow }, + { "rad", Lrad }, + { "remainder", Lremainder }, + { "round", Lround }, + { "scalbn", Lscalbn }, + { "sin", Lsin }, + { "sinh", Lsinh }, + { "sqrt", Lsqrt }, + { "tan", Ltan }, + { "tanh", Ltanh }, + { "trunc", Ltrunc }, + { NULL, NULL } +}; + +LUALIB_API int luaopen_mathx(lua_State *L) +{ + luaL_newlib(L,R); + lua_pushliteral(L,"version"); /** version */ + lua_pushliteral(L,MYVERSION); + lua_settable(L,-3); + lua_pushnumber(L,INFINITY); lua_setfield(L,-2,"inf"); + lua_pushnumber(L,NAN); lua_setfield(L,-2,"nan"); + lua_pushnumber(L,PI); lua_setfield(L,-2,"pi"); + return 1; +} diff --git a/src/component/LuaMap.cpp b/src/component/LuaMap.cpp index b7cfb91..1278af5 100644 --- a/src/component/LuaMap.cpp +++ b/src/component/LuaMap.cpp @@ -1,4 +1,5 @@ #include "easi/component/LuaMap.h" +#include #ifdef EASI_USE_LUA extern "C" { @@ -11,6 +12,46 @@ extern "C" { #include #include +#ifdef EASI_LUA_LMATHX +extern "C" int luaopen_mathx(lua_State* L); + +// Lua changes a lot between the different versions, hence we need quite some ifdefs here +namespace { + +static void loadLmathx(lua_State* L) { +#if LUA_VERSION_NUM < 502 + lua_pushcfunction(L, luaopen_mathx); + lua_pushliteral(L, "mathx"); + lua_call(L, 1, 0); +#else + luaL_requiref(L, "mathx", luaopen_mathx, 1); + lua_pop(L, 1); +#endif +} + +static std::string loadCodeLmathX() { + // cf. example code for mathx: for Lua 5.3 and upwards, we need to supplement the math table. + // (for 5.2 and lower, that's done automatically) +#if LUA_VERSION_NUM < 503 + return ""; +#else + return "for fname,fval in pairs(mathx) do math[fname] = fval end;\n"; +#endif + return ""; +} + +} +#else +namespace { +static void loadLmathx(lua_State* L) { +} + +static std::string loadCodeLmathX() { + return ""; +} +} +#endif + namespace easi { double getField(lua_State* L, const std::string& key) { @@ -34,8 +75,8 @@ void LuaMap::executeLuaFunction(const Matrix& x, if (!luaState) { luaState = luaL_newstate(); luaL_openlibs(luaState); - - // luaJIT_setmode(luaState, -1, LUAJIT_MODE_ALLFUNC|LUAJIT_MODE_ON); + + loadLmathx(luaState); const auto status = luaL_dostring(luaState, function.data()); if (status) { @@ -72,6 +113,7 @@ void LuaMap::executeLuaFunction(const Matrix& x, std::cerr << "Error running function f " << lua_tostring(luaState, -1) + << " :::: f given by: " << function << std::endl; std::abort(); } @@ -100,7 +142,7 @@ void LuaMap::setMap(const std::set& in, const std::string& newFunction) { setIn(in); setOut(out); - function = newFunction; + function = loadCodeLmathX() + newFunction; for (const auto& i: in) { idxToInputName.push_back(i); }