package svm.instances.binary;

import java.util.HashMap;

import svm.AbstractSVMStructInstance;
import svm.SVMStruct;
import base.DenseVector;
import base.SparseVector;

public class BinaryClassificationInstance extends AbstractSVMStructInstance<DenseVector, BinaryLabel>
{

	@Override
	public SparseVector phi(DenseVector x, BinaryLabel y)
	{
		// TODO Auto-generated method stub
		SparseVector p = new SparseVector();
		for(int i=0;i<x.length();i++)
			p.put("x"+i,x.x[i]*y.y);
		return p;
	}

	@Override
	public BinaryLabel predict(DenseVector x, SVMStruct svm)
	{
		SparseVector p = phi(x,BinaryLabel.YPOS);
		SparseVector n = phi(x,BinaryLabel.YNEG);
		HashMap<String,Integer> wMap = svm.wMap;
		double pV = p.multiply(svm.w, wMap);
		double nV = n.multiply(svm.w, wMap);
		if(pV>nV) return BinaryLabel.YPOS;
		return BinaryLabel.YNEG;
	}

	@Override
	public BinaryLabel marginRescaling(DenseVector x, BinaryLabel y, SVMStruct svm)
	{
		SparseVector p = phi(x,BinaryLabel.YPOS);
		SparseVector n = phi(x,BinaryLabel.YNEG);
		HashMap<String,Integer> wMap = svm.wMap;
		double pV = p.multiply(svm.w, wMap) + loss(y,BinaryLabel.YPOS);
		double nV = n.multiply(svm.w, wMap) + loss(y,BinaryLabel.YNEG);
		if(pV>nV) return BinaryLabel.YPOS;
		return BinaryLabel.YNEG;
	}

	@Override
	public BinaryLabel slackRescaling(DenseVector x, BinaryLabel y, SVMStruct svm)
	{
		SparseVector t = phi(x,y);
		SparseVector p = phi(x,BinaryLabel.YPOS);
		SparseVector n = phi(x,BinaryLabel.YNEG);
		p.subtract(t);
		n.subtract(t);	
		HashMap<String,Integer> wMap = svm.wMap;
		double pV = loss(y,BinaryLabel.YPOS)*(1+p.multiply(svm.w, wMap));
		double nV = loss(y,BinaryLabel.YNEG)+(1+n.multiply(svm.w, wMap));
		if(pV>nV) return BinaryLabel.YPOS;
		return BinaryLabel.YNEG;
	}

	@Override
	public double loss(BinaryLabel y, BinaryLabel predY)
	{
		if(y.y==predY.y)
			return 0;
		return 1;
	}

}
