package fr.unistra.pelican.util.data.distances; import fr.unistra.pelican.util.data.Data; /** * Abstract class representing a distance to be computed between two given data * in PELICAN. Possible use is to consider data as feature and to compute * distance between features. * * The exact distance measure has to be specified in the subclasses. * * @author lefevre * */ public abstract class Distance { /** * Abstract method representing the distance measure to be overriden by the * subclass * * @param d1 First data * @param d2 Second data * @return Distance between <tt>d1</tt> and <tt>d2</tt>. */ public abstract double distance(Data d1, Data d2); /** * Static method able to return the required distance measure adapted to the data type * @param dist Class representing the distance measure * @param data Data on which will be computed the distance measure * @param params Optional parameters to the constructor of the distance measure : take care of (Object) vs (Object[]) * @return the instance of the distance measure adapted to the data type */ public static Distance forName( Class<?> dist, Data data, Object... params) { Distance d = null; String sData = data.getClass().getSimpleName(); String sDist = dist.getSimpleName(); String sPack = dist.getPackage().getName(); String name = sPack + "." + sData.substring(0, sData.length() - 4) + sDist; try { // Constructeur sans paramètre if (params==null) d = (Distance) Class.forName(name).newInstance(); else { // Constructeur avec paramètres, on récupère les types des paramètres Class<?>[] cParams=new Class[params.length]; for (int i=0;i<params.length;i++) cParams[i]=params[i].getClass(); d=(Distance)Class.forName(name).getConstructor(cParams).newInstance(params); } } catch (Exception e) { if (e instanceof ClassNotFoundException) System.err.println("Distance " + sDist + " is not defined for " + sData + " in package " + sPack); if (e instanceof NoSuchMethodException) System.err.println("Bad call to the constructor of class " + name + " (check the parameters)"); else e.printStackTrace(); } return d; } }