public class ClassifierData {

    public ITaskLoss taskLoss;
    public IUpdateRule updateRule;
    public IInference inference;
    public IKernel kernel;
    public IFeatureFunctions phi;
    public List<Double> arguments;
    public int iteration = 0;
    public String verbose = "";
} public class Consts {

    // GENERALS
	public static final String SPACE = " ";
    public static final String TAB = "\t";
    public static final String COMMA_NOTE = ",";
	public static final String CLASSIFICATION_SPLITTER = "-";
	public static final String COLON_SPLITTER = ":";
    public static final String PARAMS_SPLITTER = ";";
	public static final String NEW_LINE = "line.separator";
    public static final int ERROR_NUMBER = -1;

    // DUMMY
    public static final int MIN_GAP_START_DUMMY = 3;
    public static final int MIN_GAP_END_DUMMY = 3;

    // VOWEL DURATION
    public static final int MIN_VOWEL = 9;  //min training set: 45 frames
	public static final int MAX_VOWEL = 92; //max training set: 459 frames
    public static final int MIN_GAP_START = 10;
    public static final int MIN_GAP_END = 10;

    public static final double MEAN_VOWEL_LENGTH = 41.787; //pre calculated from the training set
    public static final double STD_VOWEL_LENGTH = 12.918; //pre calculated from the training set
    public static final double MAX_VOWEL_LENGTH = 38; //pre calculated from the training set

    // MODELS NUMBER OF PARAMETERS
    public static final int PA_PARAMS_SIZE = 1; //The number params 4 PA
    public static final int SVM_PARAMS_SIZE = 2; //The number params 4 SVM
    public static final int DL_PARAMS_SIZE = 2; //The number params 4 Direct Loss
    public static final int CRF_PARAMS_SIZE = 2; //The number params 4 CRF
    public static final int RL_PARAMS_SIZE = 2; //The number params 4 Ramp Loss
    public static final int PL_PARAMS_SIZE = 6; //The number params 4 Probit Loss
    public static final int SP_PARAMS_SIZE = 0; //The number params 0 Perceptron
    public static final int ORBIT_PARAMS_SIZE = 2; //The number params 4 orbit
    public static final int MULTICLASS_REGECT_SIZE = 4; //The number params 4 multiclass regect

    // KERNEL DEFAULT PARAMETERS
    public static double SIGMA = 1;

    //OCR
    public static final String END_NOTE = "$";
} public class ErrorConstants {

	public static final String GENERAL_ERROR = "Error: ";
	public static final String RAW_DATA_EMPTY_ERROR = "Raw data is empty";
	public static final String VECTOR_CONVERT_ERROR = "Error converting vector: ";
	public static final String PARSE_CLASSIFICATION_ERROR = "Error with the classification of example: ";
	public static final String PHI_VECTOR_DATA = "Phi vector data empty";
	
	public static final String MULTIPLE_VECTORS_SIZE_ERROR = "The vectors doesn't have the same size";
	public static final String MULTIPLE_VECTORS_EMPTY_ERROR = "The vectors are empty";
	
	public static final String UPDATE_ARGUMENTS_ERROR = "Size of arguments is not valid";
	public static final String UPDATE_DIVIDE_ZERO_ERROR = "Phi difference multiple return 0";
	
	public static final String PHI_DATA_ERROR = "Phi data is null";
	public static final String EPOCH_ERROR = "Epoch is a negative number";
	
	public static final String SIZE_OF_TRAIN_ERROR = "Train size is 0";
	public static final String GAP_START_SIZE_ERROR = "Gap start can not be 0";
	public static final String GAP_END_SIZE_ERROR = "Gap end can not be 0";
	public static final String ZERO_DIVIDING = "Can not divide by zero";
	
	public static final String CONFIG_ERROR = "Can not convert config file";
	public static final String CONFIG_ARGUMENTS_ERROR = "Invalid number of arguments";
    public static final String CONFIG_ARGUMENTS_TYPE_ERROR = "Invalid type of arguments";
	
	public static final String WRONG_TEST_VALUES = "Invalid test values";
	public static final String WRONG_TRAIN_VALUES = "Invalid train values";

    public static final String WEIGHTS_VALUES = "Error converting weights file.";
    public static final String SORT_ERROR = "Error, sorting the scores map.";
} public abstract class Example {

    public String path;
    private String label;
    private int fold;
    public int sizeOfVector;

	//C'tor
	public Example() {
        label = "";
        sizeOfVector = 0;
	}

	//===========GETTERS AND SETTERS=========//
	public Vector getFeatures(){return null;}
	public void setFeatures(Vector features){}

    public ArrayList<Vector> getFeatures2D(){return null;}
    public void setFeatures2D(ArrayList<Vector> features){}
    public ArrayList<Integer> getLabels2D(){return null;}
    public void setLabels2D(ArrayList<Integer> rankLabels){}

    public String getLabel() {
        return label;
    }
    public void setLabel(String label) {
        this.label = label;
    }

    public int getFold() { return fold; }
    public void setFold(int fold) { this.fold = fold; }
} public class PredictedLabels extends TreeMap<String, Double>{

    //default c'tor
    public PredictedLabels(){
    }

    public PredictedLabels(MapValueComparatorAscending vc){
        super(vc);
    }

    public PredictedLabels(MapValueComparatorDescending vc){
        super(vc);
    }

    public PredictedLabels(MapKeyComparatorAscending vc){
        super(vc);
    }
} public class Vector extends HashMap<Integer, Double> implements Serializable{

    private static final long serialVersionUID = 1L;
    private int maxIndex;
    public Vector(){this.maxIndex = -1;}
    public Vector(Vector v){
        super(v);
    }

    @Override
    public Double put(Integer key, Double value){
        super.put(key, value);
        if(maxIndex < key) maxIndex = key;
        return value;
    }

    // getter
    public int getMaxIndex() {
        return maxIndex;
    }
    public void resetMaxIndex(){
        this.maxIndex = -1;
    }
} public class Logger {

    private static final String directory = "log";
    private static final String log_file = "files.log";

    /**
     * Write the message into the standard output
     * @param message - the message to be written
     */
    public static void info(String message){
        System.out.print(System.getProperty(Consts.NEW_LINE) + message);
    }

    /**
     * Write the message into the standard output without new line at the end
     * @param message - the message to be written
     */
    public static void info_no_new_line(String message){
        System.out.print(message);
    }

    /**
     * Write the message into the standard output with the data and time attached
     * @param message - the message to be written
     */
    public static void infoTime(String message){
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        //get current date time with Date()
        Date date = new Date();
        if(message.isEmpty() || message.equals(""))
            message = "None,";
        System.out.print(System.getProperty(Consts.NEW_LINE) + message + " " + dateFormat.format(date));
    }

    /**
     * Writes only the data and time to the standard output
     */
    public static void time(){
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        //get current date time with Date()
        Date date = new Date();
        System.out.print(System.getProperty(Consts.NEW_LINE)  + dateFormat.format(date));
    }

    /**
     * Write the message into the standard output with the data and time attached
     * @param msg - the message to be written
     * @param example - a running id
     */
    public static void timeExampleStandard(String msg, int example){
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        //get current date time with Date()
        Date date = new Date();
        System.out.print(System.getProperty(Consts.NEW_LINE) + msg+example+", "+dateFormat.format(date));
    }

    /**
     * Write the message into the standard output as a progress bar
     * @param msg - the message to be written
     */
    public static void progressMessage(String msg){
        System.out.print("\r" + msg + " ");
    }

    /**
     * Write the message into the standard error
     * @param message - the message to be written
     */
    public static void error(String message){
        System.err.println("Error: "+message);
    }



    /**
     * Write the message into the files.log in the lod directory(if doesn't exists the program creates the dir)
     * @param message - tha message to ve written
     * @throws IOException
     */
    public static void log2File(String message) throws IOException
    {
        // create the log directory if does noe exists
        File dir = new File(directory);
        if(!dir.exists())
            dir.mkdir();

        // Create file stream
        File file = new File(directory+"/"+log_file);
        FileWriter fstream = new FileWriter(file,true);
        BufferedWriter out = new BufferedWriter(fstream);
        //writes the message
        out.write(message);
        out.write(System.getProperty(Consts.NEW_LINE));
        //close all the file descriptors
        out.close();
        fstream.close();
    }

    /**
     * clean the log directory
     */
    public static void clean(){
        File dir = new File(directory);
        if(dir.exists() && dir.isDirectory()) {
            String[]entries = dir.list();
            for(String s: entries){
                File currentFile = new File(dir.getPath(),s);
                currentFile.delete();
            }
            dir.delete();
        }

        dir.mkdir();
    }
} public class MathHelpers {

    /**
     * multiple two double vectors
     * @param v1 first vector
     * @param v2 second vector
     * @return the result
     */
	public static double multipleVectors(Vector v1, Vector v2)
	{
		double result = 0;
        Double num;

		//validation
		if(v1.size() == 0 || v2.size() == 0) {
            Logger.error(ErrorConstants.MULTIPLE_VECTORS_EMPTY_ERROR);
			return 0;
		}

        if(v1.size() <= v2.size()) {
            //multiple the vectors
            for (Integer key : v1.keySet()) {
                num = v2.get(key);
                if (num != null)
                    result += (v1.get(key) * v2.get(key));
            }
        } else {
            //multiple the vectors
            for (Integer key : v2.keySet()) {
                num = v1.get(key);
                if (num != null)
                    result += (v1.get(key) * v2.get(key));
            }
        }

		return result;
	}

    /**
     * add scalar to a double vector
     * @param v1 vector
     * @param scalar scalar
     * @return the result
     */
	public static Vector addScalar2Vectors(Vector v1, double scalar)
	{
        Vector result = new Vector();

		if(v1.size() == 0) {
			Logger.error(ErrorConstants.MULTIPLE_VECTORS_EMPTY_ERROR);
			return null;
		}

		//multiple the vectors
		for(Integer key : v1.keySet())
			result.put(key, v1.get(key) + scalar);

		return result;
	}

    /**
     * add scalar to a double vector
     * @param v1 vector
     * @param scalar scalar
     * @return the result
     */
	public static Vector mulScalarWithVectors(Vector v1, double scalar)
	{
        Vector result = new Vector();

		if(v1.size() == 0) {
			Logger.error(ErrorConstants.MULTIPLE_VECTORS_EMPTY_ERROR);
			return null;
		}

		//multiple the vectors
        for(Integer key : v1.keySet())
            result.put(key, v1.get(key) * scalar);

		return result;
	}

    /**
     * add scalar to a double vector
     * @param v1 first vector
     * @param v2 second vector
     * @return the result
     */
	public static Vector subtract2Vectors(Vector v1, Vector v2)
	{
        Vector result = new Vector ();
        Double num;

		//validation
		if(v1.size() == 0 || v2.size() == 0) {
			Logger.error(ErrorConstants.MULTIPLE_VECTORS_EMPTY_ERROR);
			return null;
		}

		//subtract the vectors
		for(Integer key : v1.keySet()){
            num = v2.get(key);
            if(num != null)
			    result.put(key, v1.get(key)-v2.get(key));
            else
                result.put(key, v1.get(key));
        }

        for(Integer key : v2.keySet()){
            num = v1.get(key);
            if(num == null)
                result.put(key, (-1)*v2.get(key));
        }

		return result;
	}

    /**
     * add scalar to a double vector
     * @param v1 first vector
     * @param v2 second vector
     * @return the result
     */
	public static Vector add2Vectors(Vector v1, Vector v2)
	{
        Vector result = new Vector();
        Double num;
		//validation
        if(v1.size() == 0 || v2.size() == 0) {
            Logger.error(ErrorConstants.MULTIPLE_VECTORS_EMPTY_ERROR);
            return null;
        }

		//add the vectors
        for(Integer key : v1.keySet()){
            num = v2.get(key);
            if(num != null)
                result.put(key, v1.get(key)+v2.get(key));
            else
                result.put(key, v1.get(key));
        }

        for(Integer key : v2.keySet()){
            num = v1.get(key);
            if(num == null)
                result.put(key, v2.get(key));
        }

		return result;
	}

    /**
     * Preform sigmoid functions
     * @param x value
     * @return the sigmoid result
     */
    public static double sigmoid(double x) {
        return (1/( 1 + Math.pow(Math.E,(-1*x))));
    }
} public class MapValueComparatorAscending implements Comparator<String>{

    Map<String, Double> base;

    public MapValueComparatorAscending(Map<String, Double> base) {
        this.base = base;
    }

    @Override
    public int compare(String a, String b) {
        if (base.get(a) > base.get(b)) {
            return 1;
        } else {
            return -1;
        }
    }
} public class MapValueComparatorDescending implements Comparator<String>{

    Map<String, Double> base;

    public MapValueComparatorDescending(Map<String, Double> base) {
        this.base = base;
    }

    @Override
    public int compare(String a, String b) {
        if (base.get(a) <= base.get(b)) {
            return 1;
        } else {
            return -1;
        }
    }
}
import com.structed.data.entities.PredictedLabels;
import com.structed.data.entities.Vector;
import com.structed.data.Logger;
import com.structed.utils.MathHelpers;
import com.structed.utils.comperators.MapValueComparatorAscending;
import com.structed.utils.comperators.MapValueComparatorDescending;
import java.util.TreeMap;
import com.structed.models.ClassifierData;
import com.structed.constants.Consts;
import com.structed.constants.ErrorConstants;
import com.structed.data.entities.Example;
/*
 * The MIT License (MIT)
 *
 * StructED - Machine Learning Package for Structured Prediction
 *
 * Copyright (c) 2015 Yossi Adi, E-Mail: yossiadidrum@gmail.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.structed.models.inference;



/**
 * Vowel Duration inference example
 */
public class InferenceVowelDurationData implements IInference {

    //predict function
    //argmax(yS,yE) (W*Phi(Xi,yS,yE)) + Task Loss
    //this function assumes that the argument vector has already been converted to phi vector
    //return null on error
    public PredictedLabels predictForTrain(Example vector, Vector W, String realClass, ClassifierData classifierData, double epsilonArgMax)
    {
        try{
            double maxVal = 0;
            String maxLabel = "";
            boolean isFirst = true;

            //validation
            if(vector.sizeOfVector<=0)
            {
                Logger.error(ErrorConstants.PHI_VECTOR_DATA);
                return null;
            }

            //loop over all the classifications of this specific example
            for(int i=Consts.MIN_GAP_START ; i<vector.sizeOfVector-(Consts.MIN_GAP_END) ; i++)