gt: 							for (int j = a + 1; j < nr_class; j++) {
context: /*
   *  RapidMiner
   *
   *  Copyright (C) 2001-2014 by RapidMiner and the contributors
   *
   *  Complete list of developers available at our web site:
   *
   *       http://rapidminer.com
   *
   *  This program is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU Affero General Public License as published by
   *  the Free Software Foundation, either version 3 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU Affero General Public License for more details.
   *
   *  You should have received a copy of the GNU Affero General Public License
   *  along with this program.  If not, see http://www.gnu.org/licenses/.
   */
  package com.rapidminer.operator.learner.functions.kernel;
  
  import libsvm.Svm;
  import libsvm.svm_model;
  import libsvm.svm_node;
  import libsvm.svm_parameter;
  
  import com.rapidminer.example.Attribute;
  import com.rapidminer.example.AttributeRole;
  import com.rapidminer.example.Attributes;
  import com.rapidminer.example.Example;
  import com.rapidminer.example.ExampleSet;
  import com.rapidminer.example.FastExample2SparseTransform;
  import com.rapidminer.example.table.AttributeFactory;
  import com.rapidminer.operator.UserError;
  import com.rapidminer.operator.learner.FormulaProvider;
  import com.rapidminer.tools.Ontology;
  import com.rapidminer.tools.Tools;
  
  /**
   * A model generated by the <a href="http://www.csie.ntu.edu.tw/~cjlin/libsvm">libsvm</a> by Chih-Chung Chang and
   * Chih-Jen Lin.
   * 
   * @author Ingo Mierswa
   */
  public class LibSVMModel extends KernelModel implements FormulaProvider {
  
  	private static final long serialVersionUID = -2654603017217487365L;
  
  	private svm_model model;
  
  	private int numberOfAttributes;
  
  	private boolean confidenceForMultiClass = true;
  
  	public LibSVMModel(ExampleSet exampleSet, svm_model model, int numberOfAttributes, boolean confidenceForMultiClass) {
  		super(exampleSet);
  		this.model = model;
  		this.numberOfAttributes = numberOfAttributes;
  		this.confidenceForMultiClass = confidenceForMultiClass;
  	}
  
  	@Override
  	public boolean isClassificationModel() {
  		return getLabel().isNominal();
  	}
  
  	@Override
  	public double getAlpha(int index) {
  		return model.sv_coef[0][index];
  	}
  
  	@Override
  	public String getId(int index) {
  		return null;
  	}
  
  	@Override
  	public int getNumberOfSupportVectors() {
  		return model.SV.length;
  	}
  
  	@Override
  	public int getNumberOfAttributes() {
  		return numberOfAttributes;
  	}
  
  	@Override
  	public double getBias() {
  		if (this.model.rho.length > 0)
  			return this.model.rho[0];
  		else
  			return 0.0d;
  	}
  
  	@Override
  	public SupportVector getSupportVector(int index) {
  		svm_node[] nodes = this.model.SV[index];
  		double[] x = new double[getNumberOfAttributes()];
  		for (int i = 0; i < nodes.length; i++)
  			x[nodes[i].index] = nodes[i].value;
  		return new SupportVector(x, getRegressionLabel(index), Math.abs(getAlpha(index)));
  	}
  
  	@Override
  	public double getAttributeValue(int exampleIndex, int attributeIndex) {
  		double[] dense = new double[numberOfAttributes];
  		svm_node[] node = model.SV[exampleIndex];
  		for (int i = 0; i < node.length; i++) {
  			dense[node[i].index] = node[i].value;
  		}
  		return dense[attributeIndex];
  	}
  
  	@Override
  	public String getClassificationLabel(int index) {
  		double functionValue = getRegressionLabel(index);
  		if (!Double.isNaN(functionValue))
  			return getLabel().getMapping().mapIndex((int) functionValue);
  		else
  			return "?";
  	}
  
  	@Override
  	public double getRegressionLabel(int index) {
  		if (model.labelValues != null)
  			return model.labelValues[index];
  		else
  			return Double.NaN;
  	}
  
  	@Override
  	public double getFunctionValue(int index) {
  		if (getLabel().isNominal()) {
  			double[] classProbs = new double[getLabel().getMapping().size()];
  			Svm.svm_predict_probability(model, model.SV[index], classProbs);
  			return classProbs[0];
  		} else {
  			return Svm.svm_predict(model, model.SV[index]);
  		}
  	}
  
  	@Override
  	public ExampleSet performPrediction(ExampleSet exampleSet, Attribute predictedLabel) throws UserError {
  		FastExample2SparseTransform ripper = new FastExample2SparseTransform(exampleSet);
  		Attribute label = getLabel();
  
  		// check if one class SVM is used
  		if (model.param.svm_type == LibSVMLearner.SVM_TYPE_ONE_CLASS) {
  			// if yes, then clear predictedLabel mapping: We use a fixed one
  			predictedLabel.getMapping().getValues().clear();
  			predictedLabel.getMapping().getValues().add("outside");
  			predictedLabel.getMapping().getValues().add("inside");
  
  			// create own confidence attribute
  			Attribute confidenceAttribute = AttributeFactory.createAttribute(Attributes.CONFIDENCE_NAME + "(inside)", Ontology.REAL);
  			exampleSet.getExampleTable().addAttribute(confidenceAttribute);
  			AttributeRole confidenceRole = new AttributeRole(confidenceAttribute);
  			confidenceRole.setSpecial(Attributes.CONFIDENCE_NAME + "_inside");
  			exampleSet.getAttributes().add(confidenceRole);
  
  			// now calculate weights
  			int counter = 0;
  			double[] allConfidences = new double[exampleSet.size()];
  			int[] allLabels = new int[exampleSet.size()];
  			double maxConfidence = Double.NEGATIVE_INFINITY;
  			double minConfidence = Double.POSITIVE_INFINITY;
  			double confidence;
  
  			for (Example example : exampleSet) {
  				svm_node[] currentNodes = LibSVMLearner.makeNodes(example, ripper);
  
  				double[] prob = new double[1];
  				Svm.svm_predict_values(model, currentNodes, prob);
  
  				allLabels[counter] = (prob[0] >= 0) ? 1 : 0;
  				allConfidences[counter] = prob[0];
  				minConfidence = Math.min(minConfidence, prob[0]);
  				maxConfidence = Math.max(maxConfidence, prob[0]);
  				
  				counter++;
  			}
  
  			counter = 0;
  			for (Example example : exampleSet) {
  				confidence = allConfidences[counter]; // (allConfidences[counter] - minConfidence) / (maxConfidence - minConfidence);
  				example.setValue(predictedLabel, allLabels[counter]);
  				example.setValue(confidenceAttribute, confidence);
  				counter++;
  			}
  
  		} else {
  			// performing regular classification or regression
  
  			Attribute[] confidenceAttributes = null;
  			if (label.isNominal() && label.getMapping().size() >= 2) {
  				confidenceAttributes = new Attribute[model.label.length];
  				for (int j = 0; j < model.label.length; j++) {
  					String labelName = label.getMapping().mapIndex(model.label[j]);
  					confidenceAttributes[j] = exampleSet.getAttributes().getSpecial(Attributes.CONFIDENCE_NAME + "_" + labelName);
  				}
  			}
  
  			for (Example example : exampleSet) {
  				if (label.isNominal()) {
  					// set prediction
  					svm_node[] currentNodes = LibSVMLearner.makeNodes(example, ripper);
  
  					// set class probs (properly calculated during training)
  					if ((model.probA != null) && (model.probB != null)) {
  						double[] classProbs = new double[model.nr_class];
  						int nr_class = model.nr_class;
  						double[] dec_values = new double[nr_class * (nr_class - 1) / 2];
  						Svm.svm_predict_values(model, currentNodes, dec_values);
  
  						double min_prob = 1e-7;
  						double[][] pairwise_prob = new double[nr_class][nr_class];
  
  						int k = 0;
  						for (int a = 0; a < nr_class; a++)
  