function Matrix(_size = 1) constructor { size = [ 1, 1 ]; isize = 1; raw = []; static setSize = function(_s) { if(!is_array(_s)) _s = [ _s, _s ]; size = _s; isize = _s[0] * _s[1]; array_resize(raw, isize); return self; } static setArray = function(_arr) { var _l = min(array_length(_arr), isize); for( var i = 0; i < _l; i++ ) raw[i] = _arr[i]; return self; } static setMatrix = function(_mat) { setSize(_mat.size); setArray(_mat.raw); return self; } setSize(_size); static lerpTo = function(_mat, _t) { if(!is(_mat, Matrix)) return self; if(_mat.size[0] != size[0] || _mat.size[1] != size[1]) return self; var _m = new Matrix(); _m.size = [ size[0], size[1] ]; _m.isize = isize; _m.raw = array_create(isize); for( var i = 0; i < isize; i++ ) _m.raw[i] = lerp(raw[i], _mat.raw[i], _t); return _m; } static serialize = function() { return { size, isize, raw }; } static deserialize = function(dat) { if(is_array(dat)) { var _len = array_length(dat); var _siz = floor(sqrt(_len)); size = [ _siz, _siz ]; isize = _siz * _siz; raw = dat; return self; } size = dat[$ "size"] ?? size; isize = dat[$ "isize"] ?? isize; raw = dat[$ "raw"] ?? raw; return self; } static clone = function() { var _m = new Matrix(size); _m.setArray(raw); return _m; } static to_string = function() { return $"{raw}"; } static to_real = function() { return raw; } ////- Unary static isSquare = function() { return size[0] == size[1]; } static det = function() { if(!isSquare()) return -1; return __matrix_determinant(raw, size[0]); } static invert = function() { if(!isSquare()) return self; var _inv = __matrix_inverse(raw, size[0]); var _mat = new Matrix(size).setArray(_inv); return _mat; } static transpose = function() { var _trn = __matrix_transpose(raw, size); var _mat = new Matrix([size[1], size[0]]).setArray(_trn); return _mat; } ////- Operations static add = function(_mat2) { var _mat = clone(); for( var i = 0; i < isize; i++ ) _mat.raw[i] += array_safe_get(_mat2.raw, i, 0); return _mat; } static subtract = function(_mat2) { var _mat = clone(); for( var i = 0; i < isize; i++ ) _mat.raw[i] -= array_safe_get(_mat2.raw, i, 0); return _mat; } static multiplyScalar = function(_sca) { var _mat = clone(); for( var i = 0; i < isize; i++ ) _mat.raw[i] *= _sca; return _mat; } static divideScalar = function(_sca) { var _mat = clone(); for( var i = 0; i < isize; i++ ) _mat.raw[i] /= _sca; return _mat; } static multiplyVector = function(_vec) { var result = []; var cols = size[0]; var rows = size[1]; for (var i = 0; i < rows; i++) { var sum = 0; for (var j = 0; j < cols; j++) sum += raw[i * cols + j] * array_safe_get(_vec, j, 1); result[i] = sum; } return result; } static multiplyMatrix = function(_mat2) { var result = []; var rowsA = size[0]; var colsA = size[1]; var rowsB = _mat2.size[0]; var colsB = _mat2.size[1]; if (colsA != rowsB) return self; // Incompatible matrices for (var i = 0; i < rowsA; i++) { for (var j = 0; j < colsB; j++) { var sum = 0; for (var k = 0; k < colsA; k++) { sum += raw[i * colsA + k] * _mat2.raw[k * colsB + j]; } result[i * colsB + j] = sum; } } var _mat = new Matrix([rowsA, colsB]).setArray(result); return _mat; } }