// Path: src/main/java/com/jfcorugedo/rserver/service/RService.java
// public interface RService {
// 
// 	/**
// 	 * Groups the given values in pairs based on the correlation between values.
// 	 * 
// 	 * For instance, given the following values:
// 	 * 
// 	 * {1.0, 2.0, 2.0, 1.0}
// 	 * 
// 	 * This function will return
// 	 * 
// 	 * [{0,3}, {1,2}]
// 	 * 
// 	 * So the first element in the values array must be paired with the fourth element of the array.
// 	 * Similarly, the second element of the array must be paired with the third element.
// 	 * 
// 	 * @param values Values to be paired
// 	 * @return List of pairs. Each element in the list will have to indexes that point at the elements
// 	 * of the input array that must be paired
// 	 */
// 	List<int[]> groupValues(List<double[]> values);
// 
// 	/**
// 	 * Groups the given values in pairs based on the correlation between values.
// 	 * 
// 	 * For instance, given the following values:
// 	 * 
// 	 * {"A", "B", "B", "A"}
// 	 * 
// 	 * This function will return
// 	 * 
// 	 * [{0,3}, {1,2}]
// 	 * 
// 	 * So the first element in the values array must be paired with the fourth element of the array.
// 	 * Similarly, the second element of the array must be paired with the third element.
// 	 * 
// 	 * @param values Values to be paired
// 	 * @return List of pairs. Each element in the list will have to indexes that point at the elements
// 	 * of the input array that must be paired
// 	 */
// 	List<int[]> groupDiscreteValues(List<String[]> values);
// 	
// 	/**
// 	 * Groups the given values in pairs based on the correlation between values.
// 	 * 
// 	 * For instance, given the following values:
// 	 * 
// 	 * {1.0, 2.0, 3.0, 4.0}, {"A", "A", "B", "B"}
// 	 * 
// 	 * This function will return
// 	 * 
// 	 * [{0,3}, {1,2}]
// 	 * 
// 	 * So the first element in the values array must be paired with the fourth element of the array.
// 	 * Similarly, the second element of the array must be paired with the third element.
// 	 * 
// 	 * @param values Values to be paired
// 	 * @return List of pairs. Each element in the list will have to indexes that point at the elements
// 	 * of the input array that must be paired
// 	 */
// 	List<int[]> groupMultipleValues(List<String[]> discreteValues, List<double[]> continuousValues);
// 	
// 	/**
// 	 * Computes the p-value, or observed significance level, of a two-sample Kolmogorov-Smirnov test 
// 	 * evaluating the null hypothesis that x and y are samples drawn from the same probability distribution.
// 	 *  
// 	 * @param x
// 	 * @param y
// 	 * @return
// 	 */
// 	double kolmogorovSmirnovTest(double[] x, double[] y);
// 
// 	
// 	/**
// 	 * This method returns the square root of the given value
// 	 * @param number
// 	 * @return
// 	 */
// 	double sqrt(double number);
// }


import java.util.Arrays;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.codahale.metrics.annotation.Timed;
import com.jfcorugedo.rserver.service.RService;
package com.jfcorugedo.rserver.generalization.algorithm;





@Component
public class KolmogorovSmirnovTestImpl implements KolmogorovSmirnovTest {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(KolmogorovSmirnovTestImpl.class);
	
	/** Name of the algorithm used to compare two samples */
	private static final String KS_TEST = "K-S test";
	
	@Inject
	private RService rService;
	
	/**
	 * This test try to test if the null hypothesis is truth or not.
	 * 
	 * The null hypothesis is that the samples are drawn from the same distribution.
	 * 
	 */
	@Override
	@Timed
	public boolean areGeneralizable(double[] x, double[] y){
		
		if(LOGGER.isDebugEnabled()) {
			LOGGER.debug("Calculating K-S test of \nx: {}\ny: {}", Arrays.toString(x), Arrays.toString(y));
		}
		
		double pValue = rService.kolmogorovSmirnovTest(x, y);
		
		if(LOGGER.isDebugEnabled()) {
			LOGGER.debug("K-S pValue calculated: {}", pValue);
		}
		
		//Accept null hypothesis: Both samples come from the same distribution
		return pValue > 0.05;
	}
	
	@Override
	public String getAlgorithm() {
		
// Path: src/main/java/com/jfcorugedo/rserver/service/RService.java
// public interface RService {
// 
// 	/**
// 	 * Groups the given values in pairs based on the correlation between values.
// 	 * 
// 	 * For instance, given the following values:
// 	 * 
// 	 * {1.0, 2.0, 2.0, 1.0}
// 	 * 
// 	 * This function will return
// 	 * 
// 	 * [{0,3}, {1,2}]
// 	 * 
// 	 * So the first element in the values array must be paired with the fourth element of the array.
// 	 * Similarly, the second element of the array must be paired with the third element.
// 	 * 
// 	 * @param values Values to be paired
// 	 * @return List of pairs. Each element in the list will have to indexes that point at the elements
// 	 * of the input array that must be paired
// 	 */
// 	List<int[]> groupValues(List<double[]> values);
// 
// 	/**
// 	 * Groups the given values in pairs based on the correlation between values.
// 	 * 
// 	 * For instance, given the following values:
// 	 * 
// 	 * {"A", "B", "B", "A"}
// 	 * 
// 	 * This function will return
// 	 * 
// 	 * [{0,3}, {1,2}]
// 	 * 
// 	 * So the first element in the values array must be paired with the fourth element of the array.
// 	 * Similarly, the second element of the array must be paired with the third element.
// 	 * 
// 	 * @param values Values to be paired
// 	 * @return List of pairs. Each element in the list will have to indexes that point at the elements
// 	 * of the input array that must be paired
// 	 */
// 	List<int[]> groupDiscreteValues(List<String[]> values);
// 	
// 	/**
// 	 * Groups the given values in pairs based on the correlation between values.
// 	 * 
// 	 * For instance, given the following values:
// 	 * 
// 	 * {1.0, 2.0, 3.0, 4.0}, {"A", "A", "B", "B"}
// 	 * 
// 	 * This function will return
// 	 * 
// 	 * [{0,3}, {1,2}]
// 	 * 
// 	 * So the first element in the values array must be paired with the fourth element of the array.
// 	 * Similarly, the second element of the array must be paired with the third element.
// 	 * 
// 	 * @param values Values to be paired
// 	 * @return List of pairs. Each element in the list will have to indexes that point at the elements
// 	 * of the input array that must be paired
// 	 */
// 	List<int[]> groupMultipleValues(List<String[]> discreteValues, List<double[]> continuousValues);
// 	
// 	/**
// 	 * Computes the p-value, or observed significance level, of a two-sample Kolmogorov-Smirnov test 
// 	 * evaluating the null hypothesis that x and y are samples drawn from the same probability distribution.
// 	 *  
// 	 * @param x
// 	 * @param y
// 	 * @return
// 	 */
// 	double kolmogorovSmirnovTest(double[] x, double[] y);
// 
// 	
// 	/**
// 	 * This method returns the square root of the given value
// 	 * @param number
// 	 * @return
// 	 */
// 	double sqrt(double number);
// }


// Path: src/main/java/com/jfcorugedo/rserver/generalization/algorithm/KolmogorovSmirnovTestImpl.java
import java.util.Arrays;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.codahale.metrics.annotation.Timed;
import com.jfcorugedo.rserver.service.RService;

package com.jfcorugedo.rserver.generalization.algorithm;





@Component
public class KolmogorovSmirnovTestImpl implements KolmogorovSmirnovTest {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(KolmogorovSmirnovTestImpl.class);
	
	/** Name of the algorithm used to compare two samples */
	private static final String KS_TEST = "K-S test";
	
	@Inject
	private RService rService;
	
	/**
	 * This test try to test if the null hypothesis is truth or not.
	 * 
	 * The null hypothesis is that the samples are drawn from the same distribution.
	 * 
	 */
	@Override
	@Timed
	public boolean areGeneralizable(double[] x, double[] y){
		
		if(LOGGER.isDebugEnabled()) {
			LOGGER.debug("Calculating K-S test of \nx: {}\ny: {}", Arrays.toString(x), Arrays.toString(y));
		}
		
		double pValue = rService.kolmogorovSmirnovTest(x, y);
		
		if(LOGGER.isDebugEnabled()) {
			LOGGER.debug("K-S pValue calculated: {}", pValue);
		}
		
		//Accept null hypothesis: Both samples come from the same distribution
		return pValue > 0.05;
	}
	
	@Override
	public String getAlgorithm() {
		
		return KS_TEST;