001 package jcolibri.method.retrieve.NNretrieval.similarity.local; 002 003 004 005 import jcolibri.method.retrieve.NNretrieval.similarity.LocalSimilarityFunction; 006 007 008 /** 009 * This function computes the similarity between two enum values as their cyclic 010 * distance. 011 * 012 * @author Juan A. Recio-García 013 */ 014 public class EnumCyclicDistance implements LocalSimilarityFunction { 015 016 017 018 /** 019 * Applies the similarity. 020 * 021 * @param o1 022 * Enum. 023 * @param o2 024 * Enum. 025 * @return the result to apply the similarity. 026 */ 027 public double compute(Object o1, Object o2) throws jcolibri.exception.NoApplicableSimilarityFunctionException{ 028 if ((o1 == null) || (o2 == null)) 029 return 0; 030 if(!(o1 instanceof Enum)) 031 throw new jcolibri.exception.NoApplicableSimilarityFunctionException(this.getClass(), o1.getClass()); 032 if(!(o2 instanceof Enum)) 033 throw new jcolibri.exception.NoApplicableSimilarityFunctionException(this.getClass(), o2.getClass()); 034 035 Enum e1 = (Enum)o1; 036 Enum e2 = (Enum)o2; 037 038 double size = e1.getDeclaringClass().getEnumConstants().length; 039 double distance = Math.abs(e1.ordinal() - e2.ordinal()); 040 double cyclicDistance = size - distance; 041 042 if(distance <= cyclicDistance) 043 return 1 - distance / size; 044 else 045 return 1 - cyclicDistance / size; 046 } 047 048 /** Applicable to Enum */ 049 public boolean isApplicable(Object o1, Object o2) 050 { 051 if((o1==null)&&(o2==null)) 052 return true; 053 else if(o1==null) 054 return o2 instanceof Enum; 055 else if(o2==null) 056 return o1 instanceof Enum; 057 else 058 return (o1 instanceof Enum)&&(o2 instanceof Enum); 059 } 060 061 }