// Path: ensemble-clustering/src/main/java/com/oculusinfo/ml/feature/bagofwords/distance/CosineDistance.java
// public class CosineDistance extends DistanceFunction<BagOfWordsFeature> {
// 	private static final long serialVersionUID = -635994591459075095L;
// 
// 	public CosineDistance() {
// 		this(1);
// 	}
// 	
// 	public CosineDistance(double weight) {
// 		super(weight);
// 	}
// 	
// 	@Override
// 	public double distance(BagOfWordsFeature x, BagOfWordsFeature y) {
// 		double dotprod = 0, xlength = 0, ylength = 0;
// 		
// 		for (FeatureFrequency xf : x.getValues()) {
// 			xlength += xf.frequency * xf.frequency;
// 			FeatureFrequency yf = y.getCount(xf.feature.getName());
// 			if (yf != null) dotprod += xf.frequency * yf.frequency;
// 		}
// 		for (FeatureFrequency yf : y.getValues()) {
// 			ylength += yf.frequency * yf.frequency;
// 		}
// 		// if both are empty then distance is max
// 		if (xlength == 0 || ylength == 0) return 1.0;
// 		
// 		return 1.0 - (dotprod / ( Math.sqrt(xlength) * Math.sqrt(ylength) ));
// 	}
// 
// }


import com.oculusinfo.ml.feature.bagofwords.BagOfWordsFeature;
import com.oculusinfo.ml.feature.bagofwords.distance.CosineDistance;
import java.util.Collections;
import junit.framework.Assert;
import org.junit.Test;
		t1.incrementValue("dog");
		
		BagOfWordsFeature t2 = new BagOfWordsFeature();
		t2.incrementValue("dog");
		
		CosineDistance d = new CosineDistance();
		double d1 = d.aveMinDistance(Collections.singletonList(t1), Collections.singletonList(t2));
		double d2 = d.aveMinDistance(Collections.singletonList(t2), Collections.singletonList(t1));
		 
		Assert.assertTrue(isEqual(d1, d2));
	}
	
	@Test
	public void testSymmetric2() {
		BagOfWordsFeature t1 = new BagOfWordsFeature();
		t1.setCount("dog", 10);
		t1.setCount("food", 5);
		t1.setCount("house", 1);
		t1.setCount("walk", 6);
		t1.setCount("yard", 8);
		
		BagOfWordsFeature t2 = new BagOfWordsFeature();
		t2.setCount("dog", 10);
		t2.setCount("food", 5);
		t2.setCount("house", 1);
		t2.setCount("walk", 6);
		t2.setCount("yard", 8);
		
		CosineDistance d = new CosineDistance();
		double d1 = d.aveMinDistance(Collections.singletonList(t1), Collections.singletonList(t2));
// Path: ensemble-clustering/src/main/java/com/oculusinfo/ml/feature/bagofwords/distance/CosineDistance.java
// public class CosineDistance extends DistanceFunction<BagOfWordsFeature> {
// 	private static final long serialVersionUID = -635994591459075095L;
// 
// 	public CosineDistance() {
// 		this(1);
// 	}
// 	
// 	public CosineDistance(double weight) {
// 		super(weight);
// 	}
// 	
// 	@Override
// 	public double distance(BagOfWordsFeature x, BagOfWordsFeature y) {
// 		double dotprod = 0, xlength = 0, ylength = 0;
// 		
// 		for (FeatureFrequency xf : x.getValues()) {
// 			xlength += xf.frequency * xf.frequency;
// 			FeatureFrequency yf = y.getCount(xf.feature.getName());
// 			if (yf != null) dotprod += xf.frequency * yf.frequency;
// 		}
// 		for (FeatureFrequency yf : y.getValues()) {
// 			ylength += yf.frequency * yf.frequency;
// 		}
// 		// if both are empty then distance is max
// 		if (xlength == 0 || ylength == 0) return 1.0;
// 		
// 		return 1.0 - (dotprod / ( Math.sqrt(xlength) * Math.sqrt(ylength) ));
// 	}
// 
// }


// Path: ensemble-clustering/src/test/java/com/oculusinfo/ml/distance/TestCosineDistance.java
import com.oculusinfo.ml.feature.bagofwords.BagOfWordsFeature;
import com.oculusinfo.ml.feature.bagofwords.distance.CosineDistance;
import java.util.Collections;
import junit.framework.Assert;
import org.junit.Test;

		t1.incrementValue("dog");
		
		BagOfWordsFeature t2 = new BagOfWordsFeature();
		t2.incrementValue("dog");
		
		CosineDistance d = new CosineDistance();
		double d1 = d.aveMinDistance(Collections.singletonList(t1), Collections.singletonList(t2));
		double d2 = d.aveMinDistance(Collections.singletonList(t2), Collections.singletonList(t1));
		 
		Assert.assertTrue(isEqual(d1, d2));
	}
	
	@Test
	public void testSymmetric2() {
		BagOfWordsFeature t1 = new BagOfWordsFeature();
		t1.setCount("dog", 10);
		t1.setCount("food", 5);
		t1.setCount("house", 1);
		t1.setCount("walk", 6);
		t1.setCount("yard", 8);
		
		BagOfWordsFeature t2 = new BagOfWordsFeature();
		t2.setCount("dog", 10);
		t2.setCount("food", 5);
		t2.setCount("house", 1);
		t2.setCount("walk", 6);
		t2.setCount("yard", 8);
		
		CosineDistance d = new CosineDistance();
		double d1 = d.aveMinDistance(Collections.singletonList(t1), Collections.singletonList(t2));
		double d2 = d.aveMinDistance(Collections.singletonList(t2), Collections.singletonList(t1));