package org.data2semantics.mustard.experiments.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.data2semantics.mustard.kernels.FeatureInspector;
import org.data2semantics.mustard.kernels.Kernel;
import org.data2semantics.mustard.kernels.data.GraphData;
import org.data2semantics.mustard.kernels.graphkernels.FeatureVectorKernel;
import org.data2semantics.mustard.learners.Prediction;
import org.data2semantics.mustard.learners.SparseVector;
import org.data2semantics.mustard.learners.evaluation.EvaluationFunction;
import org.data2semantics.mustard.learners.liblinear.LibLINEAR;
import org.data2semantics.mustard.learners.liblinear.LibLINEARModel;
import org.data2semantics.mustard.learners.liblinear.LibLINEARParameters;


public class FeatureInspectionExperiment<D extends GraphData, K extends FeatureVectorKernel<D> & FeatureInspector>  {
	private D data;
	private List<Double> labels;
	private LibLINEARParameters svmParms;
	private List<K> kernels;
	private int maxFeatures;

	public FeatureInspectionExperiment(List<K> kernels, D data,	List<Double> labels, LibLINEARParameters svmParms, int maxFeatures) {
		this.data = data;
		this.labels = labels;
		this.svmParms = svmParms;
		this.kernels = kernels;
		this.maxFeatures = maxFeatures;
	}

	public void run() {
		List<Double> tempLabels = new ArrayList<Double>();
		tempLabels.addAll(labels);

		Map<Kernel, SparseVector[]> fvs = new HashMap<Kernel, SparseVector[]>();

		System.out.println("Computing FVs...");	
		for (FeatureVectorKernel<D> kernel : kernels) {
			SparseVector[] fv = kernel.computeFeatureVectors(data);
			fvs.put(kernel, fv);
		}
		for (Kernel k : fvs.keySet()) {
			List<SparseVector> tempFV = Arrays.asList(fvs.get(k));
			Collections.shuffle(tempFV, new Random(11));
			fvs.put(k, tempFV.toArray(new SparseVector[0]));
		}
		Collections.shuffle(tempLabels, new Random(11));		

		double[] target = new double[tempLabels.size()];
		for (int i = 0; i < target.length; i++) {
			target[i] = tempLabels.get(i);
		}

		System.out.println("Computing Model...");	
		LibLINEARModel model = LibLINEAR.trainLinearModelWithMultipleFeatureVectors(fvs, target, svmParms);		
		LibLINEARModel.WeightIndexPair[][] fws = model.getFeatureWeights();
		int[] intLabs = model.getLabels();
 
		// Sort them
		for (int i = 0; i < fws.length; i++) {
			FeatureInspector fi = (FeatureInspector) model.getKernelSetting();
			Arrays.sort(fws[i]);
			List<Integer> indices = new ArrayList<Integer>();

			System.out.println("Class " + intLabs[i]);
			System.out.print("Index: Weight - ");

			for (int k = 0; k < maxFeatures; k++) {
				if (fws[i][k].getWeight() > 0){
					indices.add(fws[i][k].getIndex());
					System.out.print(fws[i][k].getIndex() + ": " + fws[i][k].getWeight() + ", ");
				} else {
					break;
				}
			}
			System.out.println("");
			System.out.println("Labels        - " + fi.getFeatureDescriptions(indices));
		}	
	}
}
@@ -533,151 +533,20 @@
 ers.
-Prediction;%0D%0Aimport org.data2semantics.mustard.learners.SparseVector;%0D%0Aimport org.data2semantics.mustard.learners.evaluation.EvaluationFunction
+SparseVector
 ;%0D%0Ai
@@ -756,18 +756,16 @@
 ers;%0D%0A%0D%0A
-%0D%0A
 public c
@@ -870,17 +870,16 @@
 spector%3E
- 
  %7B%0D%0A%09pri
@@ -1079,17 +1079,17 @@
  D data,
-%09
+ 
 List%3CDou
@@ -1130,17 +1130,21 @@
 vmParms,
- 
+%0D%0A%09%09%09
 int maxF
@@ -1521,25 +1521,24 @@
 ng FVs...%22);
-%09
 %0D%0A%09%09for (Fea
@@ -1919,18 +1919,16 @@
 om(11));
-%09%09
 %0D%0A%0D%0A%09%09do
@@ -2105,17 +2105,16 @@
 el...%22);
-%09
 %0D%0A%09%09LibL
@@ -2208,18 +2208,16 @@
 mParms);
-%09%09
 %0D%0A%09%09LibL
@@ -2323,11 +2323,10 @@
 );%0D%0A
- 
 %0D%0A
+
 %09%09//
@@ -2531,16 +2531,228 @@
 %3E();%0D%0A%0D%0A
+%09%09%09//count the total number of features that are not zero%0D%0A%09%09%09int nonZeroFeatures = 0;%0D%0A%09%09%09for (int j = 0; j %3C fws%5Bi%5D.length; j++) %7B%0D%0A%09%09%09%09if (fws%5Bi%5D%5Bj%5D.getWeight() %3E 0) %7B%0D%0A%09%09%09%09%09nonZeroFeatures++;%0D%0A%09%09%09%09%7D%0D%0A%09%09%09%7D%0D%0A%0D%0A
 %09%09%09Syste
@@ -2782,24 +2782,66 @@
 + intLabs%5Bi%5D
+ + %22 (%22 + nonZeroFeatures + %22 features ) %22
 );%0D%0A%09%09%09Syste
@@ -2954,16 +2954,17 @@
 t() %3E 0)
+ 
 %7B%0D%0A%09%09%09%09%09
@@ -3236,12 +3236,11 @@
 );%0D%0A
+
 %09%09%7D
-%09
 %0D%0A%09%7D

Outputs the number of non-zero features