package version11_2_2_1.agnosticMemory;

import java.util.ArrayList;

public class SignatureSimplified {

	public ArrayList<Short> weightList;
	public ArrayList<Float> signature;

	public float bias;
	
	public float maxPattern1;					// maximum weight (used to normalize values in displayer)
	
	private float prediction=0;
	
	public SignatureSimplified(){
		weightList=new ArrayList<Short>();
		signature=new ArrayList<Float>();
		bias=0;
		maxPattern1=0;
		
		// test memory
		for (int i=0;i<100;i++){
			weightList.add((float)i);
			signature.add(i);
		}
	}
	
	/**
	 * predict the result of an interaction in a given context
	 * @param img : environmental context
	 * @return the certitude of success (1->absolute certitude of success, -1-> absolute certitude of failure 
	 */
	public float prediction(int[] img, boolean write){
		float result=0;
		for (int i=0;i<weightList.size();i++){
			result+=signature.get(i)*(float)img[weightList.get(i)];
		}
		//bias
		result+=bias;
		
		// activation function
		result= (float) ( 1 / (1+exp(-result)))*2-1;
		
		if (write) prediction=result;
		
		return result;
	}
	
	/**
	 * integrate the result of enaction cycle
	 * @param img : environmental context E_{t-1} 
	 * @param output result of enaction (success->1, failure->-1)
	 */
	public void learn(int[] img, float predict){

		//prediction(img, true);
		
		float delta=predict-prediction;

		if (Math.abs(delta)>=0.01){
			maxPattern1=0;
			
			for (int i=0;i<weightList.size();i++){
				
				signature.set(i, signature.get(i)+ (0.05f * delta * (float)img[weightList.get(i)]) );
				
				if (Math.abs(signature.get(i))>maxPattern1) maxPattern1=Math.abs(signature.get(i));
			}
			// bias
			bias+= 0.05 * delta * 1;
			
			
		}
	}
	
	public float getPrediction(){
		return prediction;
	}
	
	// fast exp function approximation
	public static double exp(double val) {
	    final long tmp = (long) (1512775 * val + (1072693248 - 60801));
	    return Double.longBitsToDouble(tmp << 32);
	}
	
}
