Commit 5adc0c52 authored by lafabregue's avatar lafabregue

Full switch on DistanceModel usage

parent e1663488
......@@ -17,6 +17,7 @@ public abstract class Attribute implements Serializable {
public static final String INTERVAL_ATTRIBUTE = "INTERVAL ATTRIBUTE";
public static final String NULERICAL_ATTRIBUTE = "NUMERICAL ATTRIBUTE";
public static final String SEQUENCE_ATTRIBUTE = "SEQUENCE ATTRIBUTE";
public static final String MULTIDIM_SEQUENCE_ATTRIBUTE = "MULTIDIM SEQUENCE ATTRIBUTE";
public static final String STRUCTURED_ATTRIBUTE = "STRUCTURED ATTRIBUTE";
public static final String SYMBOLIC_ATTRIBUTE = "SYMBOLIC ATTRIBUTE";
public static final String SYMBOLIC_HISTOGRAMS_ATTRIBUTE = "SYMBOLIC HISTOGRAMS ATTRIBUTE";
......
......@@ -340,7 +340,7 @@ public class AttributeDCMDSequence extends Attribute {
@Override
public String getTypeAttribute() {
return Attribute.SEQUENCE_ATTRIBUTE;
return Attribute.MULTIDIM_SEQUENCE_ATTRIBUTE;
}
protected static int ArgMin3(final double a, final double b, final double c) {
......
package jcl.data.attribute;
import static jcl.data.distance.Tools.*;
import java.util.Arrays;
import jcl.data.distance.sequential.DistanceDTWHardConstrainedMD;
import jcl.data.distance.sequential.DistanceDTWMD;
import jcl.data.distance.sequential.ParameterDTWConstrained;
import jcl.data.distance.sequential.ParameterDTW;
import jcl.data.sequence.DoubleTabArrayList;
/**
* Cette classe permet d'instancier un attribut de type séquence de t-uplets
......@@ -31,10 +24,6 @@ public class AttributeHardConstrainedMultiDimSequence extends Attribute {
public final static int NB_ITERATIONS = 15;
private final static int RIEN = -1;
private final static int DIAGONALE = 0;
private final static int GAUCHE = 1;
private final static int HAUT = 2;
// contient une sequence de tuples.
double[][] sequence;
......@@ -161,7 +150,7 @@ public class AttributeHardConstrainedMultiDimSequence extends Attribute {
@Override
public String getTypeAttribute() {
return Attribute.SEQUENCE_ATTRIBUTE;
return Attribute.MULTIDIM_SEQUENCE_ATTRIBUTE;
}
public static final int ArgMin3(final double a, final double b, final double c) {
......
......@@ -16,8 +16,8 @@ import java.util.TreeMap;
import java.util.TreeSet;
import jcl.data.concepts.Concept;
import jcl.data.distance.DistanceSymbolicHistogram;
import jcl.data.distance.ParameterSymbolicHistogramDistance;
import jcl.data.distance.unitary.DistanceSymbolicHistogram;
import jcl.data.distance.unitary.ParameterSymbolicHistogramDistance;
import jcl.utils.Couple;
import org.jfree.chart.ChartFactory;
......
......@@ -93,7 +93,7 @@ public class AttributeMDMRHSequence extends Attribute {
@Override
public String getTypeAttribute() {
return Attribute.SEQUENCE_ATTRIBUTE;
return Attribute.MULTIDIM_SEQUENCE_ATTRIBUTE;
}
public static double Min3(final double a, final double b, final double c) {
......
......@@ -140,7 +140,7 @@ public class AttributeMDMRSequence extends Attribute {
@Override
public String getTypeAttribute() {
return Attribute.SEQUENCE_ATTRIBUTE;
return Attribute.MULTIDIM_SEQUENCE_ATTRIBUTE;
}
public static double Min3(final double a, final double b, final double c) {
......
......@@ -151,14 +151,9 @@ public class AttributeMultiDimSequence extends Attribute {
}
@Override
public String getTypeAttribute() {
return Attribute.SEQUENCE_ATTRIBUTE;
return Attribute.MULTIDIM_SEQUENCE_ATTRIBUTE;
}
public static int ArgMin3(final double a, final double b, final double c) {
......
package jcl.data.attribute;
import static jcl.data.distance.Tools.*;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.IOException;
import java.util.Arrays;
/**
* Cette classe permet d'instancier un attribut de type séquence de t-uplets
*
* @author Francois Petitjean
*
*/
public class AttributeMultiDimSequence extends Attribute {
static final long serialVersionUID = 1L;
/**
* Permet de savoir la taille des séquences à partir de laquelle des simplifications ont lieux. -1 pour ne pas opérer de simplification
*/
private static int simplifyFrom = -1;
/**
* Laissé pour rétro-compatibilité
*
* @deprecated
*/
@Deprecated
public final static int MEAN_DYNAMIC_TIME_WARPING = 2;
// contient une sequence de tuples.
public double[][] sequence;
/**
* Constructeur
*
* @param sequence tableau de Tuples à utiliser comme séquence
* @param mode distance à utiliser
* @param simplifyFrom taille des séquences à partir de laquelle il faut la simplifier
*/
public AttributeMultiDimSequence(final double[][] sequence, final int simplifyFrom) {
this.sequence = sequence;
AttributeMultiDimSequence.simplifyFrom = simplifyFrom;
}
public AttributeMultiDimSequence(final double[][] sequence) {
if(sequence.length==0 || sequence==null){
System.err.println("sequence longueur nulle");
}
this.sequence = sequence;
}
@Override
public Object clone() {
final double[][] newSequence = new double[sequence.length][sequence[0].length];
for (int i = 0; i < newSequence.length; i++) {
for (int j = 0; j < newSequence[i].length; j++) {
newSequence[i][j] = sequence[i][j];
}
}
return new AttributeMultiDimSequence(newSequence, AttributeMultiDimSequence.simplifyFrom);
}
/**
* @param n
* @return retourne le n-eme tuple de la sequence
*/
public double[] getItem(final int n) {
return sequence[n];
}
/**
* @return la longueur de la sequence
*/
public int getNbTuples() {
return this.sequence.length;
}
public int getTupleDimension() {
return this.sequence[0].length;
}
/**
* permet de reduire la longueur de la sequence de un, en moyennant les deux tuples les plus proches.
*/
public void simplifyOnce() {
if (this.getNbTuples() < 1) {
System.out.println("attention: simplification de séquence impossible");
System.out.println("AttributeMultiDimSequence.simplifyOnce()");
return;
}
// recherche du minimum entre deux tuples consécutifs dans la séquence
// locale
int minIndex = 0;
double minDist = distanceTo(sequence[0], sequence[1]);
double valueTemp;
for (int i = 1; i < this.sequence.length - 1; i++) {
valueTemp = distanceTo(sequence[i], sequence[i + 1]);
if (valueTemp < minDist) {
minIndex = i;
minDist = valueTemp;
}
}
// creation d'un tuple moyen
final double[] avgTuple = moyenne(sequence[minIndex], this.sequence[minIndex + 1]);
// creation d'une sequence modifiée
final double[][] newSeq = new double[sequence.length - 1][sequence[0].length];
for (int i = 0; i < newSeq.length; i++) {
if (i < minIndex) {
newSeq[i] = this.sequence[i];
} else if (i == minIndex) {
newSeq[minIndex] = avgTuple;
} else {
newSeq[i] = this.sequence[i + 1];
}
}
this.sequence = newSeq;
}
@Override
public boolean equals(final Attribute a) {
if (!(a instanceof AttributeMultiDimSequence)) {
return false;
}
final AttributeMultiDimSequence o = (AttributeMultiDimSequence) a;
int i;
if (this.sequence.length == o.sequence.length) {
i = 0;
while (i < this.sequence.length && sequence[i] == o.sequence[i]) {
i++;
}
if (i == this.sequence.length) {
return true;
} else {
return false;
}
} else {
return false;
}
}
@Override
public String getTypeAttribute() {
return Attribute.SEQUENCE_ATTRIBUTE;
}
public static int ArgMin3(final double a, final double b, final double c) {
return (a <= b) ? ((a <= c) ? 0 : 2) : (b <= c) ? 1 : 2;
}
public static int getSimplifyFrom() {
return AttributeMultiDimSequence.simplifyFrom;
}
/**
* Permet de fixer la taille des séquences à partir de laquelle des simplifications ont lieux. -1 pour ne pas opérer de simplification
*
* @param simplifyFrom
*/
public static void setSimplifyFrom(final int simplifyFrom) {
AttributeMultiDimSequence.simplifyFrom = simplifyFrom;
}
@Override
public boolean greater(final Attribute a) {
return false;
}
@Override
public void mul(final double d) {
}
@Override
public void setZero() {
}
@Override
public void add(final Attribute a) {
}
@Override
public void diff(final Attribute a) {
}
@Override
public double getValue() {
return 1.0;
}
@Override
public String toString() {
String str = "[";
for (final double[] t : this.sequence) {
str += "{";
for (double v : t) {
str += v + " ";
}
str += "}";
}
str += "]";
return str;
}
/**
* @return the sequence
*/
public double[][] getSequence() {
return this.sequence;
}
public static double[] moyenne(final double[]... tab) {
double[] res = new double[tab[0].length];
for (int j = 0; j < tab[0].length; j++) {
res[j] = 0.0;
}
for (int i = 0; i < tab.length; i++) {
for (int j = 0; j < tab[0].length; j++) {
res[j] += tab[i][j];
}
}
for (int j = 0; j < tab[0].length; j++) {
res[j] /= tab.length;
}
return res;
}
public void serialize(XMLEncoder encoder) throws IOException {
encoder.writeObject(sequence);
encoder.flush();
}
/**
* Permet de charger la séquence TODO : Problèmes de '0'
*
* @param decoder
*/
public AttributeMultiDimSequence(XMLDecoder decoder) {
double[][] seq = (double[][]) decoder.readObject();
int taille = seq.length;
for (int i = 0; i < seq.length; i++) {
if (seq[i] == null || seq[i].length == 0) {
taille = i;
break;
} else {
boolean test = true;
for (int j = 0; j < seq[i].length; j++) {
test = test && (seq[i][j] == 0);
}
if (test) {
taille = i;
break;
} else {
// System.out.println(seq[i][0]);
}
}
}
sequence = Arrays.copyOf(seq, taille);
}
<<<<<<< HEAD
=======
public static short[] dateAverageSequence(AttributeMultiDimSequence center, AttributeMultiDimSequence[] sequences, short[][] sensingDatesByCluster) {
short[] dates = new short[center.getNbTuples()];
/**
* Cette liste contiendra la liste des tuples associés à chaque point de l'ancien centre
*/
final ArrayList<Short>[] setOfDatesByElement = new ArrayList[center.getNbTuples()];
for (int i = 0; i < setOfDatesByElement.length; i++) {
setOfDatesByElement[i] = new ArrayList<Short>();
}
int nbTuplesAverageSeq, i, j, indiceRes;
double res = 0.0;
final int tailleCenter = center.getNbTuples();
int tailleT;
byte thread = getNextThread();
/**
* on construit les associations
*/
for (int s = 0; s < sequences.length; s++) {
final AttributeMultiDimSequence T = sequences[s];
tailleT = T.getNbTuples();
// Remplissage première colonne et première ligne de la
// matrice
AttributeMultiDimSequence.matriceW[thread][0][0] = distanceTo(center.sequence[0], T.sequence[0]);
AttributeMultiDimSequence.matriceChoix[thread][0][0] = AttributeMultiDimSequence.RIEN;
AttributeMultiDimSequence.optimalPathLength[thread][0][0] = 0;
for (i = 1; i < tailleCenter; i++) {
AttributeMultiDimSequence.matriceW[thread][i][0] = AttributeMultiDimSequence.matriceW[thread][i - 1][0] + distanceTo(center.sequence[i], T.sequence[0]);
AttributeMultiDimSequence.matriceChoix[thread][i][0] = AttributeMultiDimSequence.HAUT;
AttributeMultiDimSequence.optimalPathLength[thread][i][0] = i;
}
for (j = 1; j < tailleT; j++) {
AttributeMultiDimSequence.matriceW[thread][0][j] = AttributeMultiDimSequence.matriceW[thread][0][j - 1] + distanceTo(T.sequence[j], center.sequence[0]);
AttributeMultiDimSequence.matriceChoix[thread][0][j] = AttributeMultiDimSequence.GAUCHE;
AttributeMultiDimSequence.optimalPathLength[thread][0][j] = j;
}
// Calcul de la matrice
for (i = 1; i < tailleCenter; i++) {
for (j = 1; j < tailleT; j++) {
indiceRes = AttributeMultiDimSequence.ArgMin3(AttributeMultiDimSequence.matriceW[thread][i - 1][j - 1], AttributeMultiDimSequence.matriceW[thread][i][j - 1], AttributeMultiDimSequence.matriceW[thread][i - 1][j]);
AttributeMultiDimSequence.matriceChoix[thread][i][j] = indiceRes;
switch (indiceRes) {
case DIAGONALE:
res = AttributeMultiDimSequence.matriceW[thread][i - 1][j - 1];
AttributeMultiDimSequence.optimalPathLength[thread][i][j] = AttributeMultiDimSequence.optimalPathLength[thread][i - 1][j - 1] + 1;
break;
case GAUCHE:
res = AttributeMultiDimSequence.matriceW[thread][i][j - 1];
AttributeMultiDimSequence.optimalPathLength[thread][i][j] = AttributeMultiDimSequence.optimalPathLength[thread][i][j - 1] + 1;
break;
case HAUT:
res = AttributeMultiDimSequence.matriceW[thread][i - 1][j];
AttributeMultiDimSequence.optimalPathLength[thread][i][j] = AttributeMultiDimSequence.optimalPathLength[thread][i - 1][j] + 1;
break;
}
AttributeMultiDimSequence.matriceW[thread][i][j] = res + distanceTo(center.sequence[i], T.sequence[j]);
}
}
/*
* +1 car la case contient le nb de 'flêches' dans la matrice, il faut ajouter 1 pour le nb d'éléments
*/
nbTuplesAverageSeq = AttributeMultiDimSequence.optimalPathLength[thread][tailleCenter - 1][tailleT - 1] + 1;
i = tailleCenter - 1;
j = tailleT - 1;
for (int t = nbTuplesAverageSeq - 1; t >= 0; t--) {
setOfDatesByElement[i].add(sensingDatesByCluster[s][j]);
switch (AttributeMultiDimSequence.matriceChoix[thread][i][j]) {
case DIAGONALE:
i = i - 1;
j = j - 1;
break;
case GAUCHE:
j = j - 1;
break;
case HAUT:
i = i - 1;
break;
}
}
}
releaseThread(thread);
for (int t = 0; t < tailleCenter; t++) {
long sum = 0;
for (short date : setOfDatesByElement[t]) {
sum += date;
}
dates[t] = (short) Math.round(1.0 * sum / setOfDatesByElement[t].size());
}
return dates;
}
private synchronized static final byte getNextThread() {
byte thread = 0;
synchronized (busy) {
while (busy[thread])thread++;
busy[thread] = true;
}
return thread;
}
private static final void releaseThread(byte thread) {
synchronized (busy) {
busy[thread] = false;
}
}
public static void main(String[] args) {
// AttributeMultiDimSequence seq1 = new AttributeMultiDimSequence(new
// double[][] { { 2.0, 10 }, { 5.0, 3.3 } });
// AttributeMultiDimSequence seq2 = new AttributeMultiDimSequence(new
// double[][] { { 10.0, 10 }, { 5.0, 3.3 } });
// try {
// XMLEncoder enc = new XMLEncoder(new
// FileOutputStream("/tmp/test.xml"));
// seq1.serialize(enc);
// seq2.serialize(enc);
// enc.close();
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
//
// try {
// XMLDecoder dec = new XMLDecoder(new
// FileInputStream("/tmp/test.xml"));
// AttributeMultiDimSequence seq3 = new AttributeMultiDimSequence(dec);
// System.out.println(seq3.toString());
// AttributeMultiDimSequence seq4 = new AttributeMultiDimSequence(dec);
// System.out.println(seq4.toString());
// dec.close();
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
// AttributeMultiDimSequence seq1 = new AttributeMultiDimSequence(new double[][] { { 1.0 }, { 10.0 }, { 10.0 }, { 10.0 }, { 1.0 }, { 1.0 }, {
// 1.0 } });
// AttributeMultiDimSequence seq2 = new AttributeMultiDimSequence(new double[][] { { 1.0 }, { 1.0 }, { 1.0 }, { 10.0 }, { 1.0 } });
AttributeMultiDimSequence seq1 = new AttributeMultiDimSequence(new double[][] { { 0.0 }, { 0.0 }, { 0.0 }, { 3.0 }, { 1.0 } });
AttributeMultiDimSequence seq2 = new AttributeMultiDimSequence(new double[][] { { 0.0 }, { 0.0 }, { 3.0 }, { 1.0 }, { 0.0 } });
AttributeMultiDimSequence seq3 = new AttributeMultiDimSequence(new double[][] { { 0.0 }, { 0.0 }, { 3.0 }, { 3.0 }, { 1.0 } });
AttributeMultiDimSequence seq4 = new AttributeMultiDimSequence(new double[][] { { 0.0 }, { 1.0 }, { 1.0 }, { 1.0 }, { 0.0 } });
AttributeMultiDimSequence seq5 = new AttributeMultiDimSequence(new double[][] { { 0.0 }, { 0.0 }, { 0.0 }, { 3.0 }, { 0.0 } });
// System.out.println(DTWPageRank(seq1, seq2));
// System.out.println(DTWDistanceToDiagonal(seq1, seq2));
// System.out.println(DTWDistanceToDiagonal(seq2, seq1));
// System.out.println(DTWNbAssociations(seq1, seq2));
// System.out.println(DTWMeanSpeed(seq1, seq2));
// System.out.println(DTWMeanDistanceToDiagonal(seq1, seq2));
// System.out.println(DTWStandardDeviationToDiagonal(seq1, seq2));
// System.out.println(DTWMeanSpeed(seq1, seq2));
// System.out.println(DTWDatedIntegral(seq1, new short[] { 0, 2, 3, 4 }, seq2, new short[] { 0, 1, 2, 3, 4 }));
// System.out.println(DTWDatedTimeToGo(seq1, new short[] { 0, 2, 3, 4 }, seq2, new short[] { 0, 1, 2, 3, 4 }));
// System.out.println(DTWDatedMeanSpeed(seq1, new short[] { 0, 2, 3, 4 }, seq2, new short[] { 0, 1, 2, 3, 4 }));
AttributeMultiDimSequence.setMode(DTW_BARYCENTRE);
// System.out.println(seq1.distance(seq2));
AttributeMultiDimSequence[] tabSequence = { seq1, seq2, seq3, seq4, seq5 };
AttributeMultiDimSequence avg = DBAMean(seq2, tabSequence);
System.out.println("DBA mean : " +avg);
}
>>>>>>> master
}
class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "(" + x + "," + y + ")";
}
}
class Couple implements Comparable<Couple> {
public double x;
public double y;
public Couple(double x, double y) {
this.x = x;
this.y = y;
}
public Couple(Couple c) {
this.x = c.x;
this.y = c.y;
}
public String toString() {
return "(" + x + "," + y + ")";
}
@Override
public int compareTo(Couple o) {
if (x < o.x) {
return -1;
} else if (x == o.x) {
if (y < o.y) {
return -1;
} else if (y == o.y) {
return 0;
} else {
return 1;
}
} else {
return 1;
}
}
}
class Segment {
public double longueur;
public double acceleration;
public Segment(double longueur, double acceleration) {
this.longueur = longueur;
this.acceleration = acceleration;
}
public String toString() {
return "|acc = " + acceleration + " \t longueur = " + longueur + "|";
}
}
\ No newline at end of file
......@@ -2,8 +2,8 @@ package jcl.data.attribute;
import java.util.StringTokenizer;
import jcl.data.distance.CategorialDistance;
import jcl.data.distance.EmptyDistanceParameter;
import jcl.data.distance.unitary.CategorialDistance;
/**
* <p>
......
package jcl.data.distance;
import jcl.data.attribute.Attribute;
import jcl.weights.Weights;
/**
* Generic Distance interface.
......@@ -8,7 +9,11 @@ import jcl.data.attribute.Attribute;
* @param <A> Attribute
* @param <P> Parameter
*/
public interface Distance<A extends Attribute, P extends DistanceParameter> {
public abstract class Distance<A extends Attribute, P extends DistanceParameter> {
public abstract double compute(A a1, A a2, P p);
public double compute(A a1, A a2, P p, Weights w) {
return compute(a1, a2, p);
}