static int luaC_lunum_slice(lua_State *L) { // The first part of this function extracts a slice of the array 'A' according // to the convention start:stop:skip. The result is a contiguous array 'B' // having the same number of dimensions as 'A'. // --------------------------------------------------------------------------- size_t Nd0_t, Nd1_t, Nd2_t, Nd3_t; const Array *A = lunum_checkarray1(L, 1); // the array to resize size_t *start = (size_t*) lunum_checkarray2(L, 2, ARRAY_TYPE_SIZE_T, &Nd0_t); size_t *stop = (size_t*) lunum_checkarray2(L, 3, ARRAY_TYPE_SIZE_T, &Nd1_t); size_t *skip = (size_t*) lunum_checkarray2(L, 4, ARRAY_TYPE_SIZE_T, &Nd2_t); size_t *squeeze = (size_t*) lunum_checkarray2(L, 5, ARRAY_TYPE_SIZE_T, &Nd3_t); int Nd0 = (int)Nd0_t, Nd1 = (int)Nd1_t, Nd2 = (int)Nd2_t, Nd3 = (int)Nd3_t; if (Nd0 != A->ndims || Nd1 != A->ndims || Nd2 != A->ndims || Nd3 != A->ndims) { return luaL_error(L, "slice has wrong number of dimensions for array"); } for (int d=0; d<A->ndims; ++d) { if (start[d] < 0 || stop[d] > A->shape[d]) { return luaL_error(L, "slice not within array extent"); } } Array B = array_new_from_slice(A, start, stop, skip, Nd0); // The rest of this function deals with squeezing out the size-1 dimensions of // 'B' which are marked by the 'squeeze' array. // --------------------------------------------------------------------------- size_t Nd_new = 0; for (int d=0; d<Nd0; ++d) Nd_new += !squeeze[d]; // In case we're left with a 0-dimensional (scalar) slice if (Nd_new == 0) { _push_value(L, B.dtype, B.data); return 1; } // In case there are any dims to squeeze out else if (Nd_new != Nd0) { size_t *shape_new = (size_t*) malloc(Nd_new * sizeof(size_t)); for (int d=0,e=0; d<Nd0; ++d) { if (B.shape[d] > 1 || !squeeze[d]) { shape_new[e] = B.shape[d]; ++e; } } array_resize_t(&B, shape_new, Nd_new); free(shape_new); } lunum_pusharray1(L, &B); return 1; }
static int luaC_lunum_zeros(lua_State *L) { if (lua_isnumber(L, 1)) { const lua_Integer N = luaL_checkinteger(L, 1); if (N <= 0) { return luaL_error(L, "Invalid size %d", N); } const ArrayType T = (ArrayType) luaL_optinteger(L, 2, ARRAY_TYPE_DOUBLE); Array A = array_new_zeros(N, T); lunum_pusharray1(L, &A); return 1; } else if (lua_istable(L, 1) || lunum_hasmetatable(L, 1, "array")) { size_t Nd_t; size_t *N = (size_t*) lunum_checkarray2(L, 1, ARRAY_TYPE_SIZE_T, &Nd_t); int Nd = (int)Nd_t; const ArrayType T = (ArrayType) luaL_optinteger(L, 2, ARRAY_TYPE_DOUBLE); size_t ntot = 1; for (int d=0; d<Nd; ++d) ntot *= N[d]; Array A = array_new_zeros(ntot, T); array_resize_t(&A, N, Nd); lunum_pusharray1(L, &A); return 1; } else { return luaL_error(L, "argument must be either number, table, or array"); } }
int luaC_lunum_zeros(lua_State *L) { if (lua_isnumber(L, 1)) { const int N = luaL_checkinteger(L, 1); const enum ArrayType T = (enum ArrayType) luaL_optinteger(L, 2, ARRAY_TYPE_DOUBLE); struct Array A = array_new_zeros(N, T); lunum_pusharray1(L, &A); return 1; } else if (lua_istable(L, 1) || lunum_hasmetatable(L, 1, "array")) { int Nd; int *N = (int*) lunum_checkarray2(L, 1, ARRAY_TYPE_INT, &Nd); const enum ArrayType T = (enum ArrayType) luaL_optinteger(L, 2, ARRAY_TYPE_DOUBLE); int ntot = 1; for (int d=0; d<Nd; ++d) ntot *= N[d]; struct Array A = array_new_zeros(ntot, T); array_resize(&A, N, Nd); lunum_pusharray1(L, &A); return 1; } else { luaL_error(L, "argument must be either number, table, or array"); return 0; } }
int test_checkarray(lua_State *L) { int narg = lua_gettop(L); for (int i=1; i<=narg; ++i) { size_t N; lunum_checkarray2(L, i, ARRAY_TYPE_DOUBLE, &N); printf("argument %d had length %lu\n", i, N); } return 0; }
static int luaC_lunum_resize(lua_State *L) { size_t Nd_t; Array *A = lunum_checkarray1(L, 1); // the array to resize size_t *N = (size_t*) lunum_checkarray2(L, 2, ARRAY_TYPE_SIZE_T, &Nd_t); int Nd = (int)Nd_t; size_t ntot = 1; for (int d=0; d<Nd; ++d) ntot *= N[d]; if (A->size != ntot) { return luaL_error(L, "new and old total sizes do not agree"); } array_resize_t(A, N, Nd); return 0; }
int luaC_lunum_resize(lua_State *L) { int Nd; struct Array *A = lunum_checkarray1(L, 1); // the array to resize int *N = (int*) lunum_checkarray2(L, 2, ARRAY_TYPE_INT, &Nd); int ntot = 1; for (int d=0; d<Nd; ++d) ntot *= N[d]; if (A->size != ntot) { luaL_error(L, "new and old total sizes do not agree"); return 0; } array_resize(A, N, Nd); return 0; }