package classification;

public class Classify {

	private double[] scores;

	public double Get_Score_Value (int position)
	{
		return scores[position];
	}

	public void Alloc_Scores (int size) {
		scores = new double[size];
	}
	
	public int Get_Size () {
		return scores.length;
	}
	
	/*SVM equation: f(i) = \sum_{i \in n} \alpha_{i} * y_{i} * K(x_{i},x) - b, )*/
	/*y_{i} is the class (binaire) of the trained sample {+1 or -1} (letter or not).*/
	/*\alpha_{i} is the SVM weight learned in the training classification.*/
	/*x_{i} is the data (region descriptor) to be classified where i = {0, 1, 2, n}*/
	/*K(,) is the kernel function. A radial basis function in this case given by: exp(-(||x_{i} - x_{j}||^2)/2*sigma^2)*/
	/*Where score[i] belongs to [-1, ..., 1] and -1 means that there is a very 
	 *good recognized character in Region_{i} and 1 a definitely a non-character.*/
	public void classify_rbf (SVM samples, Features features)
	{
		
		if (features.Get_Descriptor_Size() != samples.Get_Sample_Size()) {
			System.err.println("error: svm samples and region samples have different size");
			System.exit(1);
		}

		int offset = features.Get_Descriptor_Size();
		
		scores = new double[features.Get_Number_of_Regions()];
		
		for (int i = 0; i < features.Get_Number_of_Regions(); i++) { scores[i] = 0.0; }
	
		/*Computing f(0), f(1), ..., f(i). For each image region i to be classified {features[r_{0}, r_{1}, ..., r_{i}]}*/
		for(int i = 0, f_jump = 0; i < features.Get_Number_of_Regions(); i++, f_jump += offset) {
	
			/*Decreasing the -b*/
			scores[i] = -samples.Get_SVM_B_Parameter();
		
			/*Computing f(i)*/
			for(int j = 0, s_jump = 0; j < samples.Get_Number_of_Samples(); j++, s_jump += offset) {

				double sum = 0.0;

				/*Eucledian distance between one svm trained sample and one image region to be classified: ||x_{i} - x_{j}||^2*/
				for(int k = 0; k < samples.Get_Sample_Size(); k++) {
					double fi = features.Get_Data(k + f_jump);
					double si = samples.Get_Trained_Samples(k + s_jump);
					sum += (fi - si)*(fi - si);
				}
				scores[i] += samples.Get_Alpha(j) * Math.exp(-samples.Get_SVM_G_Parameter()*sum);
			}
		}
	}
}
