//package solver;
//
//import gurobi.GRB;
//import gurobi.GRBEnv;
//import gurobi.GRBException;
//import gurobi.GRBLinExpr;
//import gurobi.GRBModel;
//import gurobi.GRBQuadExpr;
//import gurobi.GRBVar;
//
//import java.util.ArrayList;
//import java.util.List;
//
//import svm.DualConstraint;
//import svm.DualQPSolver;
//import svm.Mode;
//import svm.SVMStructKernel;
//import base.Example;
//import base.Structure;
//
//public class GurobiDual<X extends Structure,Y extends Structure> extends DualQPSolver<X,Y>
//{
//	private static final double TOL = 1E-6;
//	
//	public GurobiDual(Mode m){
//		super(m);
//	}
//	public double solve(List<DualConstraint<X, Y>> constraints, List<Example<X, Y>> data, ArrayList<Double> alphas, double C, SVMStructKernel<X, Y> svm,int iter)
//	{
//		// First of all, compute the inner products, assuming symmetric kernel
//
//		// updateH(constraints, data, svm);
//
//		// System.out.println("{");
//		// for(int i=0;i<H.size();i++)
//		// System.out.println(constraints.get(i).loss+"\t"+H.get(i).toString());
//		// System.out.println("}");
//		GRBEnv env;
//		try
//		{
//			env = new GRBEnv("qp.log");
//			// env.set(GRB.IntParam.BarHomogeneous,1);
//			env.set(GRB.IntParam.LogToConsole, 0);
//			// env.set(GRB.DoubleParam.FeasibilityTol,env.get(GRB.DoubleParam.FeasibilityTol)*0.01);
//			GRBModel model = new GRBModel(env);
//			GRBVar[] varAlpha = new GRBVar[constraints.size()];
//			for (int i = 0; i < varAlpha.length; i++)
//			{
//				GRBVar alphai;
//				if (i < alphas.size())
//					alphai = model.addVar(0, Double.POSITIVE_INFINITY, alphas.get(i), GRB.CONTINUOUS, "alpha" + i);
//				else
//					alphai = model.addVar(0, Double.POSITIVE_INFINITY, 0, GRB.CONTINUOUS, "alpha" + varAlpha.length);
//				varAlpha[i] = alphai;
//			}
//			GRBVar beta = model.addVar(0, Double.POSITIVE_INFINITY, 0, GRB.CONTINUOUS, "beta");
//			model.update();
//			GRBQuadExpr obj = new GRBQuadExpr();
//			for (int i = 0; i < constraints.size(); i++)
//			{
//				obj.addTerm(constraints.get(i).loss, varAlpha[i]);
//				for (int j = 0; j < constraints.size(); j++)
//				{
//					obj.addTerm(-0.5 * H.get(i).get(j), varAlpha[i], varAlpha[j]);
//				}
//			}
//			model.setObjective(obj, GRB.MAXIMIZE);
//
//			GRBLinExpr alphaConstraint = new GRBLinExpr();
//			alphaConstraint.addTerms(constants(1, varAlpha.length), varAlpha);
//			alphaConstraint.addTerm(1, beta);
//			model.addConstr(alphaConstraint, GRB.EQUAL, C, null);
//			model.optimize();
//
//			alphas.clear();
//			for (int i = 0; i < constraints.size(); i++)
//			{
//				alphas.add(varAlpha[i].get(GRB.DoubleAttr.X));
//				if(alphas.get(i)>0.0000001)
//					constraints.get(i).lastUsed = iter;
//				// System.out.print(alphas.get(i)+",\t");
//			}
//			// System.out.println();
//			if (beta.get(GRB.DoubleAttr.X) > TOL)
//				return 0;
//			double sslack = 0;
//			// double alphasum = 0;
//			double maxAlpha = 0;
//			for (int i = 0; i < constraints.size(); i++)
//			{
//				// alphasum+=alphas.get(i);
//				if (alphas.get(i) > 1E-6)
//				{
//					double slack = constraints.get(i).loss;
//					for (int j = 0; j < constraints.size(); j++)
//					{
//						slack -= alphas.get(j) * H.get(i).get(j);
//					}
//					if (alphas.get(i) > maxAlpha)
//					{
//						sslack = slack;
//						maxAlpha = alphas.get(i);
//					}
//					// System.out.println("possible slack: " + slack);
//
//				}
//			}
//			// System.out.println("How abut dem alphas and betas: " +alphasum+" \t "+beta.get(GRB.DoubleAttr.X));
//
//			return sslack;
//		}
//
//		catch (GRBException e)
//		{
//			// TODO Auto-generated catch block
//			System.out.println("Error Code: " + e.getErrorCode());
//
//			e.printStackTrace();
//		}
//		return 0;
//	}
//}
