/* * file: layer.c * * [DEFINE DESCRIPTION = Layer class] * * Name Date Description * -------------- -------- ------------------------------------- * Andrew H. Fagg 09/05/93 Original * * * * * * */ #include "nsl_include.h" #include "layer.h" #include "alib.h" #include "gen.h" /* #define DEBUG2 */ /*#define DEBUG */ /* * layer_class::layer_class(char* local_name, int size, * * Create the layer by creating a set of columns. * */ layer_class::layer_class(char* local_name, int size, short sensor_weight_flags, column_parms_class* cparms, int n_gates, short gate_weight_flags, gate_parms_class* gparms) { int i; char nm[10]; /* Create name. */ name = new name_class(local_name, NULL); #ifdef DEBUG cout << "*** layer_class::layer_class() " << name << " ***" nl; #endif /* Create columns. */ num_columns = size; columns = new column_class*[size]; used_columns = 0; for(i = 0; i < size; ++i) { sprintf(nm, "%03d", i); /* Local name for column. */ /* Create column. */ columns[i] = new column_class(nm, name, sensor_weight_flags, cparms, n_gates, gate_weight_flags, gparms); } } /* * layer_class::~layer_class() * * Delete a layer. * */ layer_class::~layer_class() { int i; #ifdef DEBUG cout << "*** ~layer_class() ***" nl; #endif /* Delete each column. */ for(i = 0; i < num_columns; ++i) delete columns[i]; } /* * layer_class::init_weights() //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class) * * Initialize all weights in the layer. * */ void layer_class::init_weights() { int i; #ifdef DEBUG cout << "*** layer_class::init_weights() ***" nl; //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class) #endif /* Loop through each column. */ for(i = 0; i < used_columns; ++i) columns[i]->init_weights(); //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class) } /* * layer_class::clear_activities() //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class) * * Initialize all weights in the layer. * */ void layer_class::clear_activities() { int i; #ifdef DEBUG cout << "*** layer_class::clear_activities() ***" nl; //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class) #endif /* Loop through each column. */ for(i = 0; i < num_columns; ++i) columns[i]->clear_activities(); //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class) } /* * layer_class::forward_mem() //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class) * * Initialize all weights in the layer. * */ void layer_class::forward_mem() { int i; #ifdef DEBUG cout << "*** layer_class::forward_mem() ***" nl; //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class) #endif /* Loop through each column. */ for(i = 0; i < used_columns; ++i) columns[i]->forward_mem(); //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class) } /* * layer_class::forward_act() //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class) * * Initialize all weights in the layer. * */ void layer_class::forward_act() { int i; #ifdef DEBUG cout << "*** layer_class::forward_act() ***" nl; //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class) #endif /* Loop through each column. */ for(i = 0; i < used_columns; ++i) columns[i]->forward_act(); //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class) } /* * name_class* layer_class::get_name() //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) * * Return the column name. */ name_class* layer_class::get_name() { return name; } /* * nsl_vector layer_class::get_collector() //OVERLOAD CALL: get_collector: layer.c(layer_class), column.c(column_class) * * Return a vector of collector activity levels. * */ nsl_vector layer_class::get_collector() { int i; nsl_vector out(num_columns); /* Loop through each column and get */ /* the collector value. */ for(i = 0; i < num_columns; ++i) out.elem(i) = columns[i]->get_collector()->elem(); //OVERLOAD CALL: get_collector: layer.c(layer_class), column.c(column_class) return out; } /* * nsl_vector layer_class::get_collector_mem() //OVERLOAD CALL: get_collector_mem: column.c(column_class), layer.c(layer_class) * * Return a vector of collector membrane potential levels. * */ nsl_vector layer_class::get_collector_mem() { int i; nsl_vector out(num_columns); /* Loop through each column and get */ /* the collector_mem value. */ for(i = 0; i < num_columns; ++i) out.elem(i) = columns[i]->get_collector_mem()->elem(); //OVERLOAD CALL: get_collector_mem: column.c(column_class), layer.c(layer_class) return out; } /* * nsl_vector layer_class::get_sensory() //OVERLOAD CALL: get_sensory: layer.c(layer_class), column.c(column_class) * * Return a vector of sensory activity levels. * */ nsl_vector layer_class::get_sensory() { int i; nsl_vector out(num_columns); /* Loop through each column and get */ /* the sensory value. */ for(i = 0; i < num_columns; ++i) out.elem(i) = columns[i]->get_sensory()->elem(); //OVERLOAD CALL: get_sensory: layer.c(layer_class), column.c(column_class) return out; } /* * nsl_vector layer_class::get_sensory_mem() //OVERLOAD CALL: get_sensory_mem: column.c(column_class), layer.c(layer_class) * * Return a vector of sensory membrane potential levels. * */ nsl_vector layer_class::get_sensory_mem() { int i; nsl_vector out(num_columns); /* Loop through each column and get */ /* the sensory_mem value. */ for(i = 0; i < num_columns; ++i) out.elem(i) = columns[i]->get_sensory_mem()->elem(); //OVERLOAD CALL: get_sensory_mem: column.c(column_class), layer.c(layer_class) return out; } /* * nsl_vector layer_class::get_output() //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class) * * Return a vector of output activity levels. * */ nsl_vector layer_class::get_output() { int i; nsl_vector out(num_columns); /* Loop through each column and get */ /* the output value. */ for(i = 0; i < num_columns; ++i) out.elem(i) = columns[i]->get_output()->elem(); //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class) return out; } /* * nsl_vector layer_class::get_output_mem() //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class) * * Return a vector of output membrane potential levels. * */ nsl_vector layer_class::get_output_mem() { int i; nsl_vector out(num_columns); /* Loop through each column and get */ /* the output_mem value. */ for(i = 0; i < num_columns; ++i) out.elem(i) = columns[i]->get_output_mem()->elem(); //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class) return out; } /* * connector_class* layer_class::get_column_connector(int index) * * Return the connector of the sensory unit of the specified column. * */ connector_class* layer_class::get_column_connector(int index) { /* Make sure it is a valid index. */ if(index < 0 || index >= num_columns) { cout << "layer_class::get_column_connector(): " << name << "error: index must be between 0 and " << num_columns-1 << "." nl; return NULL; } /* Return the column's connector. */ return columns[index]->get_sensory_connector(); } /* * connector_class* layer_class::get_gate_connector(int index, int gate, //OVERLOAD CALL: get_gate_connector: column.c(column_class), layer.c(layer_class) * int unit) * * Return the connector of the specified columns' gate. * */ connector_class* layer_class::get_gate_connector(int index, int gate, int unit) { /* Make sure it is a valid index. */ if(index < 0 || index >= num_columns) { cout << "layer_class::get_gate_connector(): " << name //OVERLOAD CALL: get_gate_connector: column.c(column_class), layer.c(layer_class) << "error: index must be between 0 and " << num_columns-1 << "." nl; return NULL; } /* Return the gate connector. */ return columns[index]->get_gate_connector(gate, unit); //OVERLOAD CALL: get_gate_connector: column.c(column_class), layer.c(layer_class) } /* * nsl_data* layer_class::get_column_output(int index) * * Return a pointer to the output of the column. * */ nsl_data* layer_class::get_column_output(int index) { /* Make sure it is a valid index. */ if(index < 0 || index >= num_columns) { cout << "layer_class::get_column_output(): " << name << " error: index must be between 0 and " << num_columns-1 << " (" << index << " given)." nl; return NULL; } /* Report the output. */ return columns[index]->get_output(); //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class) } /* * nsl_data* layer_class::get_column_name(int index) * * Return a pointer to the output of the column. * */ name_class* layer_class::get_column_name(int index) { /* Make sure it is a valid index. */ if(index < 0 || index >= num_columns) { cout << "layer_class::get_column_name(): " << name << " error: index must be between 0 and " << num_columns-1 << " (" << index << " given)." nl; return NULL; } /* Report the name. */ return columns[index]->get_name(); //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) } /* * void layer_class::report_column(int index, int gate_flag, int connector_flag) //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class) * * Give info on the column specified by <index>. * */ void layer_class::report_column(int index, int gate_flag, int connector_flag) { /* Make sure it is a valid index. */ if(index < 0 || index >= num_columns) { cout << "layer_class::report_column(): " << name //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class) << "error: index must be between 0 and " << num_columns-1 << "." nl; return; } /* Report the column. */ columns[index]->report_column(gate_flag, connector_flag); //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class) } /* * void layer_class::report_column(int index, int gate, int connector_flag) //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class) * * Give info on the gate specified by <index>, <gate>. * */ void layer_class::report_gate(int index, int gate, int connector_flag) { /* Make sure it is a valid index. */ if(index < 0 || index >= num_columns) { cout << "layer_class::report_gate(): " << name //OVERLOAD CALL: report_gate: column.c(column_class), gate.c(gate_class), layer.c(layer_class) << "error: index must be between 0 and " << num_columns-1 << "." nl; return; } /* Report the column's gate. */ columns[index]->report_gate(gate, connector_flag); //OVERLOAD CALL: report_gate: column.c(column_class), gate.c(gate_class), layer.c(layer_class) } /* * int layer_class::stuff(ifstream& netfile) //OVERLOAD CALL: stuff: gate.c(gate_class), layer.c(layer_class), column.c(column_class), connector.c(connector_class) * * Read the layer from the opened stream. * Return = 1 if no errors * = 0 otherwise. * */ int layer_class::stuff(ifstream& netfile) { int size; int i; char tmp[STRSIZE]; netfile >> size; /* Get number of columns */ /* Check to make sure it is legal. */ #ifdef DEBUG2 cout << "Reading layer " << name << ", size = " << size nl; #endif if(size < 0 || size > num_columns) { cout << "stuff(): " << name << ". Size must be between 0 and " //OVERLOAD CALL: stuff: gate.c(gate_class), layer.c(layer_class), column.c(column_class), connector.c(connector_class) << num_columns << " (" << size << ")." nl; return 0; } used_columns = size; /* Assume columns are number 0..size-1 */ /* Loop through each column and get */ /* from file */ for(i = 0; i < size; ++i) { /* Get the column header */ netfile >> tmp; if(strncmp(tmp, "column", STRSIZE)) { cout << "Stuffing layer " << name << ", expecting column, but got:" nl; cout << tmp nl; return 0; } netfile >> tmp; /* Get the column name and forget it*/ /* If an error then return 0. */ if(!columns[i]->stuff(netfile)) //OVERLOAD CALL: stuff: gate.c(gate_class), layer.c(layer_class), column.c(column_class), connector.c(connector_class) return 0; } return 1; } /* * int layer_class::get_num_columns() * * Return the size of the layer. * */ int layer_class::get_num_columns() { return(num_columns); }; /* * column_class* layer_class::get_column(int index) * * Return a pointer to the specified column. * Returns NULL if there was an error. * */ column_class* layer_class::get_column(int index) { if(index < 0 || index >= num_columns) { cout << "get_column(): bad index given. Should fall between 0 and " << num_columns-1 << " (received " << index << ")" nl; return(NULL); }; return(columns[index]); }; /* * void layer_class::stuff_pet_connector(connector_class* con, int type) * * Connect <con> to the pet elements of all columns (positive or negative * contribution determined by <type>). * */ void layer_class::stuff_pet_connector(connector_class* con, int type) { int i; nsl_data* val; for(i = 0; i < num_columns; ++i) { /* Positive or negative component? */ switch (type) { case PET_POS: val = columns[i]->get_pet_pos(); //OVERLOAD CALL: get_pet_pos: column.c(column_class), gate.c(gate_class) break; case PET_NEG: val = columns[i]->get_pet_neg(); //OVERLOAD CALL: get_pet_neg: column.c(column_class), gate.c(gate_class) break; default: cout << "layer_class::stuff_pet_connector() bad type (" << type << ")" nl; break; }; /* Add the connection to the pet element */ con->add_connection(val, columns[i]->get_name(), 0); //OVERLOAD CALL: add_connection: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class); get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) }; };