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;
		}
	}
}
generated by LDoc 1.4.6 Last updated 2023-04-13 13:58:34