mat.c
#include <math.h> #include "mat.h" void lil_mat_init(lua_State* L, lil_Mat* mat){ if(mat->w == 0 || mat->h == 0) luaL_error(L, "Invalid matrix"); mat->d = calloc(sizeof(*mat->d), mat->w * mat->h); if(!mat->d) luaL_error(L, "OOM"); } void lil_mat_free(lil_Mat* mat){ free(mat->d); } lil_Mat lil_mat_get(lua_State* L, int i){ luaL_argcheck(L, lua_type(L, i) == LUA_TTABLE, 2, "Invalid matrix"); lua_rawgeti(L, i, 1); lil_Mat mat = { lua_objlen(L, -1), lua_objlen(L, i) }; lua_pop(L, 1); lil_mat_init(L, &mat); for(int y = 0; y < mat.h; y++){ lua_rawgeti(L, i, y+1); if(lua_type(L, -1) != LUA_TTABLE){ lil_mat_free(&mat); luaL_argerror(L, i, "Invalid matrix"); } for(int x = 0; x < mat.w; x++){ lua_rawgeti(L, -1, x+1); if(lua_type(L, -1) != LUA_TNUMBER){ lil_mat_free(&mat); luaL_argerror(L, i, "Non-number in matrix"); } mat.d[XY(&mat, x, y)] = lua_tonumber(L, -1); lua_pop(L, 1); } lua_pop(L, 1); } return mat; } int lil_mat_resize(lil_Mat* mat, int w, int h){ assert(w >= 1 && h >= 1); mat->w = w; mat->h = h; lil_Number* d = realloc(mat->d, sizeof(*d) * w * h); if(!d) return -1; mat->d = d; return 0; } void lil_mat_dot(const lil_Mat* restrict ma1, const lil_Mat* restrict ma2, lil_Mat* restrict res){ assert(ma1->w == ma2->h); assert(res->h == ma1->w); assert(res->w == ma2->h); for(int y = 0; y < ma1->h; y++){ for(int x = 0; x < ma2->w; x++){ lil_Number sum = 0; for(int i = 0; i < ma1->w; i++) sum += ma1->d[XY(ma1, i, y)] * ma2->d[XY(ma2, x, i)]; res->d[XY(res, x, y)] = sum; } } }