/** * */ package fr.unistra.pelican.util.vectorial.ordering; import fr.unistra.pelican.InvalidParameterException; /** * Ordering for astronomical multiband images. * Each band is weighted by the deviation of noise in this band (assuming background has been removed). * * Let v=[v1,...,vn] and v'=[v'1,...,v'2] be the 2 vectors to compare. * Let o=[o1,...,on] be the deviation in each band. * Let !x! stands for the ceil of x * Let E(v)=�||[v1/(k*o1),...,vn/(k*on)]||� be the truncated weighted energy of vector v * The comparison is defined by the lexicographical ordering of vector * V(v) = [E(v),!v1/(k*o1)!,...,!vn/(k*on)!,v1,...,vn] * Thus coming from a vectors of n components the ordering implies vectors of 2n+1 components. * * * * Moreover the band can be reordered using ordering field. The specified ordering should put he band with best resolution at first and so on. * * For example given a 3 band image with deviations of noise [5,7,3] and resolution [1.2,2.0,0.8], you can construct an ordering with * new AstronomicalOrdering([5,7,3],k,[2,0,1]) with k a value of your choice. * * You can access statistics on the behavior of the ordering through the static fields of the class. * * @author Benjamin Perret * */ public class AstronomicalOrdering extends VectorialOrdering { /** * deviation of noise (assumed Gaussian) in each band */ private double [] deviation; /** * reordering of bands */ private int [] ordering; /** * Gives for each element the number of times it determined an inequality */ private static long resolvedAtComponent []; /** * Number of comparisons computed */ private static long totalComparisions=0; /** * Number of times comparison concluded to equality */ private static long totalEqualities=0; /** * @return the totalEqualities */ public static long getTotalEqualities() { return totalEqualities; } /** * @return the totalComparisions */ public static long getTotalComparisions() { return totalComparisions; } /** * @return the equalities */ public static long[] getResolvedAtComponent() { return resolvedAtComponent.clone(); } /** * @param wheight */ public AstronomicalOrdering(double[] deviation, double confidenceFactor, int [] ordering) { super(); this.ordering=ordering; if (deviation.length!=ordering.length) throw new InvalidParameterException("Error during creation of Astronomical Ordering : variance and ordering must have same length."); if(confidenceFactor<=0.0) throw new InvalidParameterException("Error during creation of Astronomical Ordering : confidence factor may be strictly positive."); double [] op=deviation.clone(); for(int i=0;i<deviation.length;i++) op[ordering[i]]=deviation[i]*confidenceFactor; this.deviation=op; if(resolvedAtComponent==null || resolvedAtComponent.length!=2*deviation.length+1) resolvedAtComponent =new long[2*op.length+1]; } /** * Computed weighted truncated energy of given vector * @param o * @return */ private double energy(double [] o) { double e=0.0; for(int i=0;i<o.length;i++) { double v=o[ordering[i]]/deviation[i]; e+=v*v; } return Math.ceil(Math.sqrt(e)); } /* (non-Javadoc) * @see fr.unistra.pelican.algorithms.experimental.perret.CC.Ordering.VectorialOrdering#compare(double[], double[]) */ @Override public int compare(double[] o1, double[] o2) { totalComparisions++; int a = Double .compare(energy(o1), energy(o2)); if (a != 0) { resolvedAtComponent[0]++; return a; } else { for (int i = 0; i < o1.length; i++) { int c = Double.compare(Math.ceil(o1[ordering[i]]/deviation[i]), Math.ceil(o2[ordering[i]]/deviation[i])); if (c != 0) { resolvedAtComponent[ordering[i]+1]++; return c; } } for (int i = 0; i < o1.length; i++) { int c = Double.compare(o1[ordering[i]], o2[ordering[i]]); if (c != 0) { resolvedAtComponent[o1.length+ordering[i]+1]++; return c; } } } totalEqualities++; return 0; } }