/* * file: gate.c * * [DEFINE DESCRIPTION = Gate class (part of the column object)] * * Name Date Description * -------------- -------- ------------------------------------- * Andrew H. Fagg 09/05/93 Original * * * * * * */ #include "nsl_include.h" #include "gate.h" #include "alib.h" #include "gen.h" /* #define DEBUG */ /*#define DEBUG2 */ /* * gate_class::gate_class(char* local_name, name_class* parent, * short weight_flags, gate_parms_class* pparms) * * Create a gate type: initialize name, connectors, and parms. * */ gate_class::gate_class(char* local_name, name_class* parent, short weight_flags, gate_parms_class* pparms) { name = new name_class(local_name, parent); #ifdef DEBUG cout << "*** gate_class::gate_class() :" << name << " ***" nl; #endif /* Create connectors. */ priming_connector = new connector_class(weight_flags); support_connector = new connector_class(weight_flags); /* NULL weight vectors for now. */ priming_weights = NULL; support_weights = NULL; /* Parameters. */ parms = pparms; } /* * gate_class::~gate_class() * * Gate class destructor : delete allocated vars. */ gate_class::~gate_class() { delete priming_connector; delete support_connector; if(priming_weights != NULL) delete priming_weights; if(support_weights != NULL) delete support_weights; delete name; } /* * void gate_class::init_weights() //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class) * * Intialize the weight vectors. First create, and then set * the vectors to the initial values stored in the connectors. * */ void gate_class::init_weights() { #ifdef DEBUG cout << "*** Init weights for " << name << " ***" nl; #endif int weight_size; /* Priming connector */ /* How big is vector? */ weight_size = priming_connector->get_num_connections(); //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class) if(weight_size != 0) { /* Create weight vector */ priming_weights = new nsl_vector(weight_size); /* Get initial values. */ *priming_weights = priming_connector->get_initial_weights(0,0,0); } /* Support connector */ /* How big is vector? */ weight_size = support_connector->get_num_connections(); //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class) if(weight_size != 0) { /* Create weight vector */ support_weights = new nsl_vector(weight_size); /* Get initial values. */ *support_weights = support_connector->get_initial_weights(0,0,0); } } /* * void gate_class::clear_activities() //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class) * * Clear the activity levels of the priming and support units. * */ void gate_class::clear_activities() { #ifdef DEBUG cout << "*** gate_class::clear_activities() : " << name << " ***" nl; //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class) #endif prime_mem = 0; prime = 0; support_mem = 0; support = 0; pet_pos = 0; pet_neg = 0; } /* * void gate_class:forward() * * Update the activity levels of the priming and support units. * */ void gate_class::forward() { #ifdef DEBUG cout << "*** gate_class:forward() " << name << " ***" nl; #endif pet_pos = 0; pet_neg = 0; /* Priming unit membrane potential. */ if(priming_connector->get_num_connections() > 0) //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class) { prime_mem = (*priming_weights ^ priming_connector->get_values()).sum(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) /* Compute synaptic activity */ if(parms->pet_flag->elem() == 1.0) { pet_pos = pet_pos + NSLramp(*priming_weights ^ priming_connector->get_values()).sum(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) pet_neg = pet_neg + NSLramp(- *priming_weights ^ priming_connector->get_values()).sum(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) }; } else /* No inputs */ prime_mem = 0; /* Activity level */ prime = NSLsat(prime_mem, parms->pr_kx1->elem(), parms->pr_kx2->elem(), parms->pr_ky1->elem(), parms->pr_ky2->elem()); /* Support unit membrane potential. */ if(support_connector->get_num_connections() > 0) //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class) { support_mem = (*support_weights ^ support_connector->get_values()).sum() //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) + prime - threshold; /* Compute synaptic activity */ if(parms->pet_flag->elem() == 1.0) { pet_pos = pet_pos + NSLramp(*support_weights ^ support_connector->get_values()).sum(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) pet_neg = pet_neg + NSLramp(- *support_weights ^ support_connector->get_values()).sum(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) }; } else /* No inputs */ support_mem = prime - threshold; /* Activity level */ support = NSLramp(support_mem, parms->support_kx1->elem(), parms->support_ky1->elem(), parms->support_ky2->elem()); } /* * name_class* gate_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 gate name. */ name_class* gate_class::get_name() { return name; } /* * nsl_data* gate_class::get_prime() * * Return a pointer to the activation level of the gate. * */ nsl_data* gate_class::get_prime() { return ′ } /* * nsl_data* gate_class::get_prime_mem() * * Return a pointer to the membrane potential level of the gate. * */ nsl_data* gate_class::get_prime_mem() { return &prime_mem; } /* * nsl_data* gate_class::get_support() * * Return a pointer to the activation level of the gate. * */ nsl_data* gate_class::get_support() { return &support; } /* * nsl_data* gate_class::get_support_mem() * * Return a pointer to the membrane potential level of the gate. * */ nsl_data* gate_class::get_support_mem() { return &support_mem; } /* * nsl_vector* gate_class::get_priming_weights() * * Return a pointer to the priming weight vector. * */ nsl_vector* gate_class::get_priming_weights() { return priming_weights; } /* * nsl_vector* gate_class::get_support_weights() * * Return a pointer to the support weight vector. * */ nsl_vector* gate_class::get_support_weights() { return support_weights; } /* * nsl_vector* gate_class::get_priming_inputs() * * Return a pointer to the current priming inputs into the gate. * */ /* nsl_vector* gate_class::get_priming_inputs() { return priming_connector->get_values(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) } */ /* * nsl_vector* gate_class::get_support_inputs() * * Return a pointer to the current support inputs into the gate. * */ /* nsl_vector* gate_class::get_support_inputs() { return support_connector->get_values(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) } */ /* * connector_class* gate_class::get_priming_connector() * * Return a pointer to the gate priming connector. * */ connector_class* gate_class::get_priming_connector() { return priming_connector; } /* * connector_class* gate_class::get_support_connector() * * Return a pointer to the gate support connector. * */ connector_class* gate_class::get_support_connector() { return support_connector; } /* * connector_class* gate_class::get_connector(int unit) * * Return the specified connector * */ connector_class* gate_class::get_connector(int unit) { switch(unit) { case SUPPORT: return support_connector; case PRIME: return priming_connector; default: cout << "gate_class::get_connector(): " << name << "Error - illegal unit specified." nl; return NULL; } } /* * void gate_class::report_gate(int connector_flag) //OVERLOAD CALL: report_gate: column.c(column_class), gate.c(gate_class), layer.c(layer_class) * * Print out all unit state information. * */ void gate_class::report_gate(int connector_flag) { cout << "--------------------------" nl; cout << "Unit: " << name nl; cout << "prime mem = \t" << prime_mem; cout << "prime act = \t" << prime; cout << "support mem = \t" << support_mem; cout << "support act = \t" << support; cout << "threshold = \t" << threshold; cout nl; if(connector_flag) { cout << "Priming Connector" nl; if(priming_connector->get_num_connections()) //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class) { nsl_vector tmp = priming_connector->get_values(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) priming_connector->report_state(priming_weights, &tmp, NULL, NULL); //OVERLOAD CALL: report_state: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class) } else cout << "Empty" nl; cout << "Support Connector" nl; if(support_connector->get_num_connections()) //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class) { nsl_vector tmp2 = support_connector->get_values(); //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class) support_connector->report_state(support_weights, &tmp2, NULL, NULL); //OVERLOAD CALL: report_state: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class) } else cout << "Empty" nl; cout nl; } } int gate_class::stuff(ifstream& netfile) { float val; char tmp[STRSIZE]; #ifdef DEBUG2 cout << "Stuffing gate " << name nl; #endif netfile >> val; /* Get the threshold */ threshold = val; netfile >> tmp; /* priming connector header: 'priming' */ if(strncmp(tmp, "priming", STRSIZE)) { cout << "Stuffing gate " << name << ", expected priming, but got:" nl; cout << tmp nl; return 0; } netfile >> tmp; /* Get 'connector' */ if(strncmp(tmp, "connector", STRSIZE)) { cout << "Stuffing gate (priming) " << name << ", expected connector, but got:" nl; cout << tmp nl; return 0; } /* Get the connector */ if(!priming_connector->stuff(netfile)) //OVERLOAD CALL: stuff: gate.c(gate_class), layer.c(layer_class), column.c(column_class), connector.c(connector_class) return 0; netfile >> tmp; /* support connector header: 'support' */ if(strncmp(tmp, "support", STRSIZE)) { cout << "Stuffing gate " << name << ", expected support, but got:" nl; cout << tmp nl; return 0; } netfile >> tmp; /* Get 'connector' */ if(strncmp(tmp, "connector", STRSIZE)) { cout << "Stuffing gate (support) " << name << ", expected connector, but got:" nl; cout << tmp nl; return 0; } /* Get the connector */ if(!support_connector->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; }; /* * float gate_class::get_pet_pos() //OVERLOAD CALL: get_pet_pos: column.c(column_class), gate.c(gate_class) * * Return the positive contribution to the pet measure. * */ float gate_class::get_pet_pos() { return(pet_pos.elem()); }; /* * float gate_class::get_pet_neg() //OVERLOAD CALL: get_pet_neg: column.c(column_class), gate.c(gate_class) * * Return the negative contribution to the pet measure. * */ float gate_class::get_pet_neg() { return(pet_neg.elem()); };