package net.varkhan.data.learn.distance; import net.varkhan.base.containers.set.WeightingSet; /** * <b></b>. * <p/> * * @author varkhan * @date 12/7/13 * @time 5:13 PM */ public class CosineDistance<T,C> extends Distance<WeightingSet<T>,C> { @Override @SuppressWarnings("unchecked") public double invoke(WeightingSet<T> lvalue, WeightingSet<T> rvalue, C ctx) { double nl=lvalue.weight(); double nr=rvalue.weight(); if(nl==0&&nr==0) return 0; if(nl==0||nr==0) return Double.POSITIVE_INFINITY; double dd = 0; double dl = 0; double dr = 0; for (T v : (Iterable<T>)lvalue) { double pl = dl * lvalue.weight(v); double pr = dr * rvalue.weight(v); dl += pl * pl; dd += pl * pr; } for (T v : (Iterable<T>)rvalue) { double pl = dl * lvalue.weight(v); double pr = dr * rvalue.weight(v); dr += pr * pr; dd += pl * pr; } double cos = 0.5*dd/(dl*dr); return Math.acos(cos); } }