/* This file is part of lfann. lfann is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. lfann is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with lfann. If not, see . Copyright (C) 2009 - 2013 Lucas Hermann Negri */ static void priv_push_net(lua_State* L, struct fann* ptr) { if(ptr) { Object* obj = lua_newuserdata(L, sizeof(Object)); obj->pointer = ptr; luaL_getmetatable(L, "lfannNeT"); lua_setmetatable(L, -2); fann_set_error_log((struct fann_error *) ptr, NULL); } else lua_pushnil(L); } static int FANN_API priv_callback_handle(struct fann* ann, struct fann_train_data* train, unsigned int max_epochs, unsigned int epochs_between_reports, float desired_error, unsigned int epochs) { CallbackInfo* ptr = fann_get_user_data(ann); int ret = 0; if(ptr) { lua_State* L = ptr->L; int top = lua_gettop(L); lua_rawgeti(L, LUA_REGISTRYINDEX, ptr->function_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, ptr->ud_ref); lua_pushinteger(L, max_epochs); lua_pushinteger(L, epochs_between_reports); lua_pushnumber(L, desired_error); lua_pushinteger(L, epochs); lua_call(L, 5, 1); ret = lua_tointeger(L, -1); lua_settop(L, top); } return ret; } /* Shared code between network constructors. If anything wrong occours, it * thows an error. * The returned array is always valid, and need to be released by the caller. */ static void priv_create_array(lua_State* L, int tbl_index, unsigned int* ret_n_layers, unsigned int** ret_arr) { size_t n_layers; unsigned int* arr; size_t i; #ifdef IDEBUG fprintf(stderr, "Creating a new Neural Network\n"); #endif luaL_checktype(L, tbl_index, LUA_TTABLE); n_layers = lua_objlen(L, tbl_index); if(n_layers <= 1) luaL_error(L, "Can't create a Neural Network with less than two layers"); /* Allocated the temp array and get the neurons of each layer */ arr = malloc(sizeof(unsigned int) * n_layers); if(!arr) luaL_error(L, "Couldn't allocate the array"); for(i = 1; i <= n_layers; ++i) { lua_pushinteger(L, i); lua_rawget(L, tbl_index); if(lua_type(L, -1) == LUA_TNUMBER) { arr[i - 1] = lua_tonumber(L, -1); lua_pop(L, 1); } else { free(arr); luaL_error(L, "The number of neurons must be a number"); } } /* Return */ *ret_n_layers = n_layers; *ret_arr = arr; } static int lfann_net_create_standard(lua_State* L) { struct fann* ptr; unsigned int n_layers, *arr; priv_create_array(L, 1, &n_layers, &arr); ptr = fann_create_standard_array(n_layers, arr); free(arr); priv_push_net(L, ptr); return 1; } static int lfann_net_create_sparse(lua_State* L) { struct fann* ptr; unsigned int n_layers, *arr; priv_create_array(L, 2, &n_layers, &arr); ptr = fann_create_sparse_array(lua_tonumber(L, 1), n_layers, arr); free(arr); priv_push_net(L, ptr); return 1; } static int lfann_net_create_shortcut(lua_State* L) { unsigned int n_layers, *arr; struct fann* ptr; priv_create_array(L, 1, &n_layers, &arr); ptr = fann_create_shortcut_array(n_layers, arr); free(arr); priv_push_net(L, ptr); return 1; } static int lfann_net_copy(lua_State* L) { struct fann* ptr; Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); ptr = fann_copy(obj->pointer); fann_set_user_data(ptr, NULL); priv_push_net(L, ptr); return 1; } static int lfann_net_create_from_file(lua_State* L) { struct fann* ptr; luaL_checktype(L, 1, LUA_TSTRING); ptr = fann_create_from_file(lua_tostring(L, 1)); priv_push_net(L, ptr); return 1; } static int lfann_net_tostring(lua_State* L) { Object* obj = lua_touserdata(L, 1); char name[41]; #ifndef _MSC_VER snprintf(name, 40, "Neural Network: %p", obj->pointer); #else _snprintf(name, 40, "Neural Network: %p", obj->pointer); #endif lua_pushstring(L, name); return 1; } static void priv_free_callback(lua_State* L, Object* obj) { CallbackInfo* info; info = fann_get_user_data(obj->pointer); if(!info) return; luaL_unref(L, LUA_REGISTRYINDEX, info->function_ref); luaL_unref(L, LUA_REGISTRYINDEX, info->ud_ref); free(info); fann_set_user_data(obj->pointer, NULL); } static int lfann_net_gc(lua_State* L) { #ifdef IDEBUG fprintf(stderr, "Garbage collecting a Neural Network\n"); #endif Object* obj = lua_touserdata(L, 1); /* Release the callback if present */ priv_free_callback(L, obj); /* Destroy the network */ fann_destroy(obj->pointer); return 1; } static int lfann_net_print_connections(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); fann_print_connections(obj->pointer); return 0; } static int lfann_net_train_on_file(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TSTRING); luaL_checktype(L, 3, LUA_TNUMBER); luaL_checktype(L, 4, LUA_TNUMBER); luaL_checktype(L, 5, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_train_on_file(obj->pointer, lua_tostring(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tonumber(L, 5)); return 0; } static int lfann_net_train_on_data(lua_State* L) { Object* obj1; Object* obj2; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TUSERDATA); luaL_checktype(L, 3, LUA_TNUMBER); luaL_checktype(L, 4, LUA_TNUMBER); luaL_checktype(L, 5, LUA_TNUMBER); obj1 = lua_touserdata(L, 1); obj2 = lua_touserdata(L, 2); fann_train_on_data(obj1->pointer, obj2->pointer, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tonumber(L, 5)); return 0; } static int lfann_net_train_epoch(lua_State* L) { Object* obj1; Object* obj2; float res; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TUSERDATA); obj1 = lua_touserdata(L, 1); obj2 = lua_touserdata(L, 2); res = fann_train_epoch(obj1->pointer, obj2->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_save(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TSTRING); obj = lua_touserdata(L, 1); res = fann_save(obj->pointer, lua_tostring(L, 2)); lua_pushinteger(L, res); return 1; } static int lfann_net_save_to_fixed(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TSTRING); obj = lua_touserdata(L, 1); res = fann_save_to_fixed(obj->pointer, lua_tostring(L, 2)); lua_pushinteger(L, res); return 1; } static int lfann_net_run(lua_State* L) { Object* obj; int n_in; int n_out; int i; fann_type* input; fann_type* output; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TTABLE); obj = lua_touserdata(L, 1); n_in = fann_get_num_input(obj->pointer); n_out = fann_get_num_output(obj->pointer); /* Get the input array */ input = malloc(sizeof(fann_type) * n_in); if(!input) luaL_error(L, "Couldn't allocate the structure"); for(i = 1; i <= n_in; ++i) { lua_pushinteger(L, i); lua_gettable(L, 2); if(lua_type(L, -1) == LUA_TNUMBER) { input[i - 1] = lua_tonumber(L, -1); lua_pop(L, 1); } else { free(input); luaL_error(L, "The input must be a number"); } } /* Run and release the input array */ output = fann_run(obj->pointer, input); free(input); /* Push the result into a table */ lua_newtable(L); for(i = 1; i <= n_out; ++i) { lua_pushinteger(L, i); lua_pushnumber(L, output[i - 1]); lua_rawset(L, -3); } return 1; } static int lfann_net_init_weights(lua_State* L) { Object* obj1; Object* obj2; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TUSERDATA); obj1 = lua_touserdata(L, 1); obj2 = lua_touserdata(L, 2); fann_init_weights(obj1->pointer, obj2->pointer); return 0; } static int lfann_net_randomize_weights(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); luaL_checktype(L, 3, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_randomize_weights(obj->pointer, lua_tonumber(L, 2), lua_tonumber(L, 3)); return 0; } static int lfann_net_set_weight(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); luaL_checktype(L, 3, LUA_TNUMBER); luaL_checktype(L, 4, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_weight(obj->pointer, lua_tointeger(L, 2) - 1, lua_tointeger(L, 3) - 1, lua_tonumber(L, 4)); return 0; } static int lfann_net_get_MSE(lua_State* L) { Object* obj; float mse; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); mse = fann_get_MSE(obj->pointer); lua_pushnumber(L, mse); return 1; } static int lfann_net_get_bit_fail(lua_State* L) { Object* obj; unsigned int bit; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); bit = fann_get_bit_fail(obj->pointer); lua_pushinteger(L, bit); return 1; } static int lfann_net_reset_MSE(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); fann_reset_MSE(obj->pointer); return 0; } static int lfann_net_set_callback(lua_State* L) { Object* obj; CallbackInfo* info; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); priv_free_callback(L, obj); if(lua_type(L, 2) == LUA_TFUNCTION) { /* User passed the function to call */ luaL_checktype(L, 2, LUA_TFUNCTION); info = malloc(sizeof(CallbackInfo)); if(!info) luaL_error(L, "Couldn't allocate the structure"); info->L = L; /* Reference the function */ lua_pushvalue(L, 2); info->function_ref = luaL_ref(L, LUA_REGISTRYINDEX); /* Reference the userdata */ lua_pushvalue(L, 3); info->ud_ref = luaL_ref(L, LUA_REGISTRYINDEX); fann_set_user_data(obj->pointer, info); } fann_set_callback(obj->pointer, priv_callback_handle); return 0; } static int lfann_net_test_data(lua_State* L) { Object* obj1; Object* obj2; float mse; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TUSERDATA); obj1 = lua_touserdata(L, 1); obj2 = lua_touserdata(L, 2); mse = fann_test_data(obj1->pointer, obj2->pointer); lua_pushnumber(L, mse); return 1; } static int lfann_net_get_layer_array(lua_State* L) { Object* obj; unsigned int n_layers; unsigned int* layers; unsigned int i; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); n_layers = fann_get_num_layers(obj->pointer); layers = malloc(sizeof(unsigned int) * n_layers); if(!layers) luaL_error(L, "Couldn't allocate the structure"); fann_get_layer_array(obj->pointer, layers); lua_newtable(L); for(i = 1; i <= n_layers; ++i) { lua_pushinteger(L, layers[i - 1]); lua_rawseti(L, -2, i); } free(layers); return 1; } static int lfann_net_get_bias_array(lua_State* L) { Object* obj; unsigned int n_layers; unsigned int* layers; unsigned int i; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); n_layers = fann_get_num_layers(obj->pointer); layers = malloc(sizeof(unsigned int) * n_layers); if(!layers) luaL_error(L, "Couldn't allocate the structure"); fann_get_bias_array(obj->pointer, layers); lua_newtable(L); for(i = 1; i <= n_layers; ++i) { lua_pushinteger(L, layers[i - 1]); lua_rawseti(L, -2, i); } free(layers); return 1; } static int lfann_net_get_connection_array(lua_State* L) { Object* obj; unsigned int n_conn; struct fann_connection* conn; fann_type min_w = 32000, max_w = -32000; unsigned int i; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); n_conn = fann_get_total_connections(obj->pointer); conn = malloc(sizeof(struct fann_connection) * n_conn); if(!conn) luaL_error(L, "Couldn't allocate the structure"); fann_get_connection_array(obj->pointer, conn); /* get the min and max weights too. evil */ /* build a graph in the form graph[from][to] = [weight] */ lua_newtable(L); for(i = 0; i < n_conn; ++i) { lua_pushinteger(L, conn[i].from_neuron + 1); lua_rawget(L, -2); if(lua_isnil(L, -1)) { /* First connection of the neuron */ lua_pop(L, 1); /* pop the nil */ lua_newtable(L); /* Set in the main table */ lua_pushinteger(L, conn[i].from_neuron + 1); lua_pushvalue(L, -2); lua_rawset(L, -4); } lua_pushinteger(L, conn[i].to_neuron + 1); lua_pushnumber(L, conn[i].weight); lua_rawset(L, -3); lua_pop(L, 1); /* Pop the neuron table */ if(conn[i].weight < min_w ) min_w = conn[i].weight; if(conn[i].weight > max_w) max_w = conn[i].weight; } free(conn); lua_pushnumber(L, min_w); lua_pushnumber(L, max_w); return 3; } /* parameters */ static int lfann_net_set_training_algorithm(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_training_algorithm(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_training_algorithm(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); lua_pushinteger(L, fann_get_training_algorithm(obj->pointer)); return 1; } static int lfann_net_set_learning_rate(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_learning_rate(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_learning_rate(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_learning_rate(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_learning_momentum(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_learning_momentum(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_learning_momentum(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_learning_momentum(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_activation_function(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); luaL_checktype(L, 3, LUA_TNUMBER); luaL_checktype(L, 4, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_activation_function(obj->pointer, lua_tointeger(L, 2), lua_tointeger(L, 3) - 1, lua_tointeger(L, 4) - 1); return 0; } static int lfann_net_get_activation_function(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); luaL_checktype(L, 3, LUA_TNUMBER); obj = lua_touserdata(L, 1); res = fann_get_activation_function(obj->pointer, lua_tointeger(L, 2) - 1, lua_tointeger(L, 3) - 1); lua_pushinteger(L, res); return 1; } static int lfann_net_set_activation_function_layer(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); luaL_checktype(L, 3, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_activation_function_layer(obj->pointer, lua_tointeger(L, 2), lua_tointeger(L, 3) - 1); return 0; } static int lfann_net_set_activation_function_hidden(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_activation_function_hidden(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_set_activation_function_output(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_activation_function_output(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_set_activation_steepness(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); luaL_checktype(L, 3, LUA_TNUMBER); luaL_checktype(L, 4, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_activation_steepness(obj->pointer, lua_tonumber(L, 2), lua_tointeger(L, 3) - 1, lua_tointeger(L, 4) - 1); return 0; } static int lfann_net_get_activation_steepness(lua_State* L) { Object* obj; fann_type res; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); luaL_checktype(L, 3, LUA_TNUMBER); obj = lua_touserdata(L, 1); res = fann_get_activation_steepness(obj->pointer, lua_tointeger(L, 2) - 1, lua_tointeger(L, 3) - 1); lua_pushnumber(L, res); return 1; } static int lfann_net_set_activation_steepness_layer(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); luaL_checktype(L, 3, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_activation_steepness_layer(obj->pointer, lua_tonumber(L, 2), lua_tointeger(L, 3) - 1); return 0; } static int lfann_net_set_activation_steepness_hidden(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_activation_steepness_hidden(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_set_activation_steepness_output(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_activation_steepness_output(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_set_train_error_function(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_train_error_function(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_train_error_function(lua_State* L) { Object* obj; int func; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); func = fann_get_train_error_function(obj->pointer); lua_pushinteger(L, func); return 1; } static int lfann_net_set_train_stop_function(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_train_stop_function(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_train_stop_function(lua_State* L) { Object* obj; int func; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); func = fann_get_train_stop_function(obj->pointer); lua_pushinteger(L, func); return 1; } static int lfann_net_get_bit_fail_limit(lua_State* L) { Object* obj; fann_type bit; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); bit = fann_get_bit_fail_limit(obj->pointer); lua_pushnumber(L, bit); return 1; } static int lfann_net_set_bit_fail_limit(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_bit_fail_limit(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_quickprop_decay(lua_State* L) { Object* obj; float bit; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); bit = fann_get_quickprop_decay(obj->pointer); lua_pushnumber(L, bit); return 1; } static int lfann_net_set_quickprop_decay(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_quickprop_decay(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_quickprop_mu(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_quickprop_mu(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_quickprop_mu(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_quickprop_mu(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_rprop_increase_factor(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_rprop_increase_factor(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_rprop_increase_factor(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_rprop_increase_factor(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_rprop_decrease_factor(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_rprop_decrease_factor(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_rprop_decrease_factor(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_rprop_decrease_factor(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_rprop_delta_min(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_rprop_delta_min(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_rprop_delta_min(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_rprop_delta_min(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_rprop_delta_max(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_rprop_delta_max(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_rprop_delta_max(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_rprop_delta_max(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_rprop_delta_zero(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_rprop_delta_zero(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_rprop_delta_zero(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_rprop_delta_zero(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_print_parameters(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); fann_print_parameters(obj->pointer); return 0; } static int lfann_net_get_num_input(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_num_input(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_get_num_output(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_num_output(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_get_total_neurons(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_total_neurons(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_get_total_connections(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_total_connections(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_get_network_type(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_network_type(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_get_connection_rate(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_connection_rate(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_get_num_layers(lua_State* L) { Object* obj; int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_num_layers(obj->pointer); lua_pushinteger(L, res); return 1; } /* cascade */ static int lfann_net_cascade_train_on_data(lua_State* L) { Object* obj1; Object* obj2; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TUSERDATA); luaL_checktype(L, 3, LUA_TNUMBER); luaL_checktype(L, 4, LUA_TNUMBER); luaL_checktype(L, 5, LUA_TNUMBER); obj1 = lua_touserdata(L, 1); obj2 = lua_touserdata(L, 2); fann_cascadetrain_on_data(obj1->pointer, obj2->pointer, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tonumber(L, 5)); return 0; } static int lfann_net_cascade_train_on_file(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TSTRING); luaL_checktype(L, 3, LUA_TNUMBER); luaL_checktype(L, 4, LUA_TNUMBER); luaL_checktype(L, 5, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_cascadetrain_on_file(obj->pointer, lua_tostring(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tonumber(L, 5)); return 0; } static int lfann_net_get_cascade_output_change_fraction(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_output_change_fraction(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_cascade_output_change_fraction(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_output_change_fraction(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_cascade_output_stagnation_epochs(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_output_stagnation_epochs(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_set_cascade_output_stagnation_epochs(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_output_stagnation_epochs(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_cascade_candidate_stagnation_epochs(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_candidate_stagnation_epochs(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_set_cascade_candidate_stagnation_epochs(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_candidate_stagnation_epochs(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_cascade_candidate_change_fraction(lua_State* L) { Object* obj; float res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_candidate_change_fraction(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_cascade_candidate_change_fraction(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_candidate_change_fraction(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_cascade_weight_multiplier(lua_State* L) { Object* obj; fann_type res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_weight_multiplier(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_cascade_weight_multiplier(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_weight_multiplier(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_cascade_candidate_limit(lua_State* L) { Object* obj; fann_type res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_candidate_limit(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_cascade_candidate_limit(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_candidate_limit(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_cascade_max_out_epochs(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_max_out_epochs(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_set_cascade_max_out_epochs(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_max_out_epochs(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_cascade_max_cand_epochs(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_max_cand_epochs(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_set_cascade_max_cand_epochs(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_max_cand_epochs(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_cascade_num_candidates(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_num_candidates(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_get_cascade_activation_functions_count(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_activation_functions_count(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_get_cascade_activation_functions(lua_State* L) { Object* obj; int num; int* res; int i; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); num = fann_get_cascade_activation_functions_count(obj->pointer); res = (int*)fann_get_cascade_activation_functions(obj->pointer); lua_newtable(L); for(i = 0; i < num; ++i) { lua_pushinteger(L, i + 1); lua_pushinteger(L, res[i]); lua_rawset(L, -3); } return 1; } static int lfann_net_set_cascade_activation_functions(lua_State* L) { Object* obj; int count, i; int* funcs; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TTABLE); obj = lua_touserdata(L, 1); count = lua_objlen(L, 2); funcs = malloc(sizeof(int) * count); if(!funcs) luaL_error(L, "Couldn't allocate the structure"); for(i = 1; i <= count; ++i) { lua_pushinteger(L, i); lua_rawget(L, 2); if(lua_type(L, -1) == LUA_TNUMBER) { funcs[i - 1] = lua_tointeger(L, -1); lua_pop(L, 1); } else { free(funcs); luaL_error(L, "The table values must be numbers"); } } fann_set_cascade_activation_functions(obj->pointer, (void*)funcs, count); free(funcs); return 0; } static int lfann_net_get_cascade_num_candidate_groups(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_num_candidate_groups(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_set_cascade_num_candidate_groups(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_num_candidate_groups(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_cascade_activation_steepnesses(lua_State* L) { Object* obj; int num; fann_type* res; int i; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); num = fann_get_cascade_activation_steepnesses_count(obj->pointer); res = fann_get_cascade_activation_steepnesses(obj->pointer); lua_newtable(L); for(i = 0; i < num; ++i) { lua_pushinteger(L, i + 1); lua_pushnumber(L, res[i]); lua_rawset(L, -3); } return 1; } static int lfann_net_set_cascade_activation_steepnesses(lua_State* L) { Object* obj; int count, i; fann_type* res; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TTABLE); obj = lua_touserdata(L, 1); count = lua_objlen(L, 2), i; res = malloc(sizeof(fann_type) * count); if(!res) luaL_error(L, "Couldn't allocate the structure"); for(i = 1; i <= count; ++i) { lua_pushinteger(L, i); lua_rawget(L, 2); if(lua_type(L, -1) == LUA_TNUMBER) { res[i - 1] = lua_tonumber(L, -1); lua_pop(L, 1); } else { free(res); luaL_error(L, "The table values must be numbers"); } } fann_set_cascade_activation_steepnesses(obj->pointer, res, count); free(res); return 0; } static int lfann_net_get_cascade_activation_steepnesses_count(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_activation_steepnesses_count(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_get_cascade_min_out_epochs(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_min_out_epochs(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_set_cascade_min_out_epochs(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_min_out_epochs(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_cascade_min_cand_epochs(lua_State* L) { Object* obj; unsigned int res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_cascade_min_cand_epochs(obj->pointer); lua_pushinteger(L, res); return 1; } static int lfann_net_set_cascade_min_cand_epochs(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_cascade_min_cand_epochs(obj->pointer, lua_tointeger(L, 2)); return 0; } static int lfann_net_get_sarprop_weight_decay_shift(lua_State* L) { Object* obj; double res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_sarprop_weight_decay_shift(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_sarprop_weight_decay_shift(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_sarprop_weight_decay_shift(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_sarprop_step_error_threshold_factor(lua_State* L) { Object* obj; double res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_sarprop_step_error_threshold_factor(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_sarprop_step_error_threshold_factor(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_sarprop_step_error_threshold_factor(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_sarprop_step_error_shift(lua_State* L) { Object* obj; double res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_sarprop_step_error_shift(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_sarprop_step_error_shift(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_sarprop_step_error_shift(obj->pointer, lua_tonumber(L, 2)); return 0; } static int lfann_net_get_sarprop_temperature(lua_State* L) { Object* obj; double res; luaL_checktype(L, 1, LUA_TUSERDATA); obj = lua_touserdata(L, 1); res = fann_get_sarprop_temperature(obj->pointer); lua_pushnumber(L, res); return 1; } static int lfann_net_set_sarprop_temperature(lua_State* L) { Object* obj; luaL_checktype(L, 1, LUA_TUSERDATA); luaL_checktype(L, 2, LUA_TNUMBER); obj = lua_touserdata(L, 1); fann_set_sarprop_temperature(obj->pointer, lua_tonumber(L, 2)); return 0; }