package trust.jfcm.learning;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeMap;
import trust.jfcm.CognitiveMap;
import trust.jfcm.Concept;
import trust.jfcm.FcmConnection;
import trust.jfcm.WeightedConnection;
public class FcmLearning extends CognitiveMap{
/**
* Training Set
*/
FcmTrainingSet trainingSet;
/**
* Delta on the weight normalized over the connections
*/
LinkedList<Double> Delta_Weights;
/**
* Internal variable counting the number of learning concepts in the map.
*/
private int num_learningConcepts;
/**
* Constructor
*/
public FcmLearning(){
super();
num_learningConcepts = 0;
trainingSet = new FcmTrainingSet(this);
Delta_Weights = new LinkedList<Double>();
}
/**
* Return the training set
* @return
*/
public FcmTrainingSet getTrainingSet(){
return trainingSet;
}
/**
* Set the training set
* @param set
*/
public void setTrainingSet(FcmTrainingSet set){
trainingSet = set;
}
/**
* Add a generic concept to the map
*/
@Override
public void addConcept(Concept c) {
super.addConcept(c);
if(c instanceof LearningConcept)
num_learningConcepts++;
}
/**
* Add a new instance to the training set.
* @param inputs: map of input concepts.
* @param outputs: map of output concepts.
*/
public void addTrainingInstance(HashMap<String, Double> inputs, HashMap<String, Double> outputs){
//System.out.println("Adding entry: "+inputs+ " "+outputs);
trainingSet.addEntry(inputs, outputs);
}
/**
* Remove all instances from the current training set.
*/
public void cleanTrainingSet(){
trainingSet.empty();
}
/**
* Add a new delta weight after a training epoch
* @param delta
*/
public void addDeltaWeight(double delta){
Delta_Weights.add(new Double(delta));
}
/**
* Get the list of delta weights
* @return List of delta weights
*/
public LinkedList<Double> getDeltaWeight(){
return Delta_Weights;
}
/**
* Same method of the super class resetting also the errors
*/
public void resetConcepts() {
Iterator<Concept> iter = concepts.values().iterator();
while (iter.hasNext()) {
Concept concept = iter.next();
concept.setOutput(0.0);
concept.setPrevOutput(0.0);
concept.setPrevOutput(null);
if(concept instanceof LearningConcept){
LearningConcept lc = (LearningConcept) concept;
lc.error = 0;
lc.error_calculated = false;
}
//concept.setFixedOutput(false);
}
}
/**
* Clone
*/
@SuppressWarnings("unchecked")
public Object clone(){
FcmLearning map = new FcmLearning();
map.name = new String(this.name);
map.Delta_Weights = (LinkedList<Double>) Delta_Weights.clone();
/* clone concepts */
map.concepts = new TreeMap<String, Concept>();
Iterator<String> it = this.concepts.keySet().iterator();
while(it.hasNext()){
Concept c = (Concept) this.concepts.get(it.next()).clone();
map.addConcept(c);
}
/* clone connections */
Iterator<FcmConnection> iter = this.getConnectionsIterator();
while(iter.hasNext()){
FcmConnection old_conn = (FcmConnection) iter.next();
WeightedConnection new_conn = (WeightedConnection) old_conn.clone();
new_conn.setFrom(map.getConcept(old_conn.getFrom().getName()));
new_conn.setTo(map.getConcept(old_conn.getTo().getName()));
map.addConnection(new_conn);
map.connect(new_conn.getFrom().getName(), new_conn.getName(), new_conn.getTo().getName());
}
map.resetConcepts();
map.trainingSet = (FcmTrainingSet) trainingSet.clone();
map.trainingSet.setMap(map);
map.num_learningConcepts = this.num_learningConcepts;
return map;
}
public String printConnections() {
Collection<FcmConnection> cons = getConnections().values();
String res ="";
for(FcmConnection f : cons){
if(f instanceof LearningWeightedConnection){
LearningWeightedConnection w = (LearningWeightedConnection) f;
LearningConcept from = (LearningConcept)w.getFrom();
LearningConcept to = (LearningConcept)w.getTo();
res += " LearningConnection from "+
from.getName()+
"("+from.getTrainingFunction()+") "+
"to "+to.getName()+"("+to.getTrainingFunction()+") "+
" with weight "+w.getWeight()+
" / "+w.getWeightUncertainty()+"\n";
}
else{
WeightedConnection w = (WeightedConnection) f;
res += " Connection from "+w.getFrom().getName()+" to "+w.getTo().getName()+ " with weight "+w.getWeight()+"\n";
}
}
return res;
}
public void printErrorFlag() {
Iterator<Concept> iter = concepts.values().iterator();
while (iter.hasNext()) {
Concept concept = iter.next();
if(concept instanceof LearningConcept){
LearningConcept lc = (LearningConcept) concept;
System.out.println(" "+lc.getName()+": "+lc.isErrorCalculated());
}
//concept.setFixedOutput(false);
}
}
public int getNumLearningConcepts() {
return num_learningConcepts;
}
}