package fr.unistra.pelican.util.vectorial.orders; import java.util.Arrays; import fr.unistra.pelican.util.vectorial.VectorPixel; /** * This class represents a vector ordering realized by means of the distances relative to a reference vector; * in this case the median. * * @author E.A. * */ public class ReferenceBasedDistanceOrdering implements VectorialOrdering { private double[] d = null; /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#max(double[][]) */ public double[] max(double[][] p) { preprocess(p); int max = 0; for(int i = 1; i < p.length; i++){ if(d[max] < d[i]) max = i; } return p[max]; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#min(double[][]) */ public double[] min(double[][] p) { preprocess(p); int min = 0; for(int i = 1; i < p.length; i++){ if(d[min] > d[i]) min = i; } return p[min]; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#rank(double[][], int) */ public double[] rank(double[][] p,int r) { preprocess(p); // it might seem like trouble // to go into using subclasses // for a simple indexed sorting // but when the channel number goes up.. // quicksort will pay off. IndexedDouble[] id = new IndexedDouble[d.length]; for(int i = 0; i < d.length; i++) id[i] = new IndexedDouble(d[i],i); Arrays.sort(id); return p[id[r].i]; } private void preprocess(double[][] p) { d = new double[p.length]; // get every vector's cumulative distances for(int i = 0; i < p.length; i++){ d[i] = 0.0; for(int j = 0; j < p.length; j++){ if(j != i) d[i] += distance(p[i],p[j]); } } // smallest = median vector = reference vector (for now) int min = 0; for(int i = 1; i < p.length; i++){ if(d[min] > d[i]) min = i; } // put in d the distances from the reference vector for(int i = 0; i < p.length; i++) d[i] = distance(p[min],p[i]); } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#order(fr.unistra.pelican.util.vectorial.VectorPixel[]) */ public VectorPixel[] order(VectorPixel[] v) { double[][] p = new double[v.length][]; VectorPixel[] result = new VectorPixel[v.length]; for(int i = 0; i < v.length; i++) p[i] = v[i].getVector(); preprocess(p); IndexedDouble[] id = new IndexedDouble[d.length]; for(int i = 0; i < d.length; i++) id[i] = new IndexedDouble(d[i],i); Arrays.sort(id); for(int i = 0; i < v.length; i++) result[i] = v[id[i].i]; return result; } private double distance(double[] p1,double[] p2) { double dist = 0.0; for(int i = 0; i < p1.length; i++){ double tmp = p1[i] - p2[i]; dist += tmp * tmp; } return Math.sqrt(dist); } private class IndexedDouble implements Comparable { double d; int i; IndexedDouble(double d,int i) { this.d = d; this.i = i; } public int compareTo(Object o){ IndexedDouble d = (IndexedDouble)o; if(this.d < d.d) return -1; else if(this.d > d.d) return 1; else return 0; } } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#max(double[], double[]) */ public double[] max(double[] p,double[] r) { return r; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#min(double[], double[]) */ public double[] min(double[] p,double[] r) { return p; } }