/** * @author Steven L. Moxley * @version 1.0 */ package org.futurist.neuralnet.node; import java.util.ArrayList; import org.futurist.neuralnet.Edge; public abstract class UndirectedNode extends Node { ArrayList<Edge> neighbors; /** * 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 UndirectedNode(ArrayList<Integer> i, Double v) { super(i, v); neighbors = new ArrayList<Edge>(); } /** * 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 e the synaptic Edges to which this Node is connected */ public UndirectedNode(ArrayList<Integer> i, Double v, Double t, ArrayList<Edge> e) { super(i, v, t); if(e == null) { neighbors = new ArrayList<Edge>(); } else { neighbors = e; } } /** * Returns this Node's axons and dendrites (synapses are directly connected neighbors). Note that this is the same as calling <code>getInputs()</code> or <code>getOutputs()</code> because this is an <code>UndirectedNode</code>. * @return this Node's synapses. */ public ArrayList<Edge> getNeighbors() { return neighbors; } /** * Returns this Node's dendrites (synapses that are directly connected neighbors). Note that this is the same as calling <code>getOutputs()</code> because this is an <code>UndirectedNode</code>. * @return this Node's synapses. */ public ArrayList<Edge> getInputs() { return getNeighbors(); } /** * Returns this Node's axons (synapses that are directly connected neighbors). Note that this is the same as calling <code>getIntputs()</code> because this is an <code>UndirectedNode</code>. * @return this Node's synapses. */ public ArrayList<Edge> getOutputs() { return getNeighbors(); } /** * Add a directly connected synaptic neighbor to this Node's existing <code>Edges</code>. Note that since this is an <code>UndirectedNode</code>, no distinction is made between dendrites (inputs) and axons (outputs). * @param e the synaptic <code>Edge</code> to add. */ public void addNeighbor(Edge e) { if(!neighbors.contains(e)) { neighbors.add(e); } else { System.out.println(e + " is already a neighbor."); } } /** * Remove a directly connected synaptic neighbor from this Node's existing <code>Edges</code>. Note that since this is an <code>UndirectedNode</code>, no distinction is made between dendrites (inputs) and axons (outputs). * @param e the synaptic <code>Edge</code> to remove. */ public void removeNeighbor(Edge e) { if(neighbors.contains(e)) { neighbors.remove(e); } else { System.out.println(e + " is not a neighbor."); } } /** * Returns this Node's degree centrality. * @return the degree centrality. */ public Integer getDegreeCentrality() { return neighbors.size(); } /** * Returns this <code>Node's</code> clustering coefficient. * @return the clustering coefficient. */ public Double getClusteringCoefficient() { ArrayList<Node> neighborhood = new ArrayList<Node>(neighbors.size()); int neighborEdges = 0; for(Edge e : neighbors) { neighborhood.add(e.getOutput()); } for(Node n : neighborhood) { for(Edge e : n.getOutputs()) { if(!e.getOutput().equals(this) && neighbors.contains(e.getOutput())) { neighborEdges++; } } } return new Double(neighborEdges / (Math.pow(neighbors.size(), 2) - neighbors.size())); } public abstract void receiveActionPotential(Edge input); public abstract void sendActionPotential(Edge output); public abstract boolean fire(); public abstract boolean sigmoidFire(); }