/**
* @author Steven L. Moxley
* @version 1.0
*/
package org.futurist.neuralnet.node;
import java.util.ArrayList;
import org.futurist.neuralnet.Edge;
public class DirectedSumNode extends DirectedNode {
/**
* Constructor to create an abstract Node.
* @param i the 3-dimensional coordinate ID assigned to this Node.
* @param v the initial value stored by this Node.
*/
public DirectedSumNode(ArrayList<Integer> i, Double v) {
super(i, v);
}
/**
* Constructor to create an abstract Node.
* @param i the 3-dimensional coordinate ID assigned to this Node.
* @param v the initial value stored by this Node.
* @param t the firing threshold of this Node.
* @param in the synaptic Edges from which this Node receives action potentials
* @param out the synaptic Edges to which this Node sends action potentials
*/
public DirectedSumNode(ArrayList<Integer> i, Double v, Double t, ArrayList<Edge> in, ArrayList<Edge> out) {
super(i, v, t, in, out);
}
/**
* Receives a signal from the given synapse. Note that the <code>Edge</code> must already be connected to this Node as an input neuron because this is a <code>DirectedNode</code>.
* @param i the Edge containing the synaptic input to be received.
*/
public void receiveActionPotential(Edge i) {
if(inputs.contains(i)) {
//System.out.print(this + "'s previous accumulated action potential was " + sum + " and is now " );
value += i.getInput().getValue() * i.getWeight();
//System.out.println(sum + " after receiving action potential from " + i + ".");
} else {
//System.out.println(this + "rejects " + i + "'s action potential because it is not connected!");
}
}
/**
* Send a signal to the given synapse. Note that the <code>Edge</code> must already be connected to this Node as an output neuron because this is an <code>DirectedNode</code>.
* @param o the Edge containing the synaptic input to be sent.
*/
public void sendActionPotential(Edge o) {
for(Edge i : inputs) {
receiveActionPotential(i);
}
if(sigmoidFire() && outputs.contains(o)) {
//System.out.println(this + " is firing an action potential of " + value + "!");
o.getOutput().receiveActionPotential(o);
numFires++;
value = 0.0; // reset accumulated action potential level after firing
}
}
/**
* Determines whether or not this Node has a high enough stored value to meet the firing threshold and send an action potential.
* @return true if value >= threshold; returns false otherwise
*/
public boolean fire() {
if(value >= threshold) {
//System.out.println(this + " has accumulated enough action potential to reach its threshold.");
run();
return true;
} else {
//System.out.println("Action potential " + sum + " is below the threshold of " + threshold + ".");
return false;
}
}
/**
* Determines whether or not the sigmoid of the value stored by this Node is enough to meet the firing threshold and send an action potential.
* @return true if sigmoid(value) >= threshold; returns false otherwise
*/
public boolean sigmoidFire() {
if(sigmoid(value) >= threshold) {
//System.out.println(this + " has accumulated enough action potential to reach its threshold.");
return true;
} else {
//System.out.println("Action potential " + sum + " is below the threshold of " + threshold + ".");
return false;
}
}
}