package ann;
import java.util.Collection;
import java.util.Vector;
public class Node {
private TransferFunc tfunc;
private double inputValue;
private double outputValue;
private double gradient;
private double learningRate;
private int layerDepth;
private int layerMaxDepth;
private boolean bias;
private Vector links;
private double targetValue;
private int id;
private static int counter=0;
public Node(int layerDepth, int layerMaxDepth, TransferFunc tfunc, double learningRate, boolean bias) {
this.links=new Vector();
this.layerDepth=layerDepth;
this.layerMaxDepth=layerMaxDepth;
this.learningRate=learningRate;
this.tfunc=tfunc;
this.bias=bias;
if(bias)
outputValue=1;
id=counter++;
}
public void connectToNode(Node n) {
Link newLink=new Link(this,n);
addLink(newLink);
n.addLink(newLink);
}
public void addLink(Link newLink) {
links.add(newLink);
}
public double getInputValue() {
return inputValue;
}
public void setInputValue(double value) {
this.inputValue=value;
if(layerDepth != 0)
this.outputValue=tfunc.f(value);
else
this.outputValue=inputValue;
}
public double getOutputValue() {
return outputValue;
}
public void updateValue() {
if(layerDepth !=0 && !bias) {
inputValue=0;
boolean gotLink=false;
for(Link link: links) {
if(link.getToNode().equals(this)) {
inputValue+=link.getWeight()*link.getFromNode().getOutputValue();
gotLink=true;
}
}
if(gotLink)
outputValue=tfunc.f(inputValue);
}
}
public void updateWeightChanges() {
if(layerDepth!=0) {
for(Link link: links) {
if(link.getToNode().equals(this)) {
link.setWeightChange(learningRate*gradient*link.getFromNode().getOutputValue());
}
}
}
}
public void updateGradient() {
if(layerDepth==layerMaxDepth-1) {
if(!bias)
gradient=(targetValue-outputValue)*tfunc.fd(inputValue);
}
else if(layerDepth!=0) {
double tmpSum=0;
for(Link link:links) {
if(link.getFromNode().equals(this)) {
tmpSum+=link.getToNode().getGradient()*link.getWeight();
}
}
gradient=tfunc.fd(inputValue)*tmpSum;
}
System.out.println("new gradient for node "+id+" is "+gradient);
}
private double getGradient() {
return gradient;
}
public String toString() {
return Double.toString(outputValue);
}
public boolean isBiasNode() {
return bias;
}
public void applyWeightChanges() {
for(Link link:links) {
if(link.getFromNode().equals(this))
link.applyWeightChange();
}
}
public void setTargetValue(double targetValue) {
this.targetValue=targetValue;
}
public double getError() {
return targetValue-outputValue;
}
public Vector getLinks() {
Vector tmpLinks=new Vector();
for(int i=0;i