package edu.uky.ai.ml.nn;

import java.util.ArrayList;

/**
 * A neuron is the fundamental building block of a neural network and is meant
 * to roughly parallel a biological neuron.  A neuron has a value as well as
 * some number of edges leading to and from it.
 * 
 * @author Stephen G. Ware
 */
public class Neuron {

	/** All edges leading to this neuron from another neuron */
	public final Iterable<Edge> parents = new ArrayList<>();
	
	/** All edges leading away from this neuron to another neuron */
	public final Iterable<Edge> children = new ArrayList<>();
	
	/** This neuron's value */
	double value;
	
	/** True if the current vaule can be trusted, false if it must be recomputed */
	boolean valid = false;
	
	/**
	 * Returns the current value of this neuron based on the input it is
	 * receiving from its parents and its activation functions, which in this
	 * case is the sigmoid function.
	 * 
	 * @return the neuron's value
	 */
	public double getValue() {
		if(valid)
			return value;
		double sum = 0;
		for(Edge edge : parents)
			sum += edge.parent.getValue() * edge.weight;
		value = (1.0 / (1.0 + Math.exp(-sum)));
		valid = true;
		return value;
	}
	
	/**
	 * Alerts this neuron that some upstream value has changed and that it must
	 * recalculate its value.
	 */
	final void invalidate() {
		valid = false;
		for(Edge edge : children)
			edge.child.invalidate();
	}
}
