package fr.unistra.pelican.util.data;
import fr.unistra.pelican.util.Offset;
/**
*
* @author Régis Witz
*/
public class HistogramData extends DoubleArrayData {
@Override
public double distance( Data data ) {
Double[] h1 = this.values;
Double[] h2 = ( ( DoubleArrayData ) data ).values; // let's be permissive..
int bins = h1.length;
if ( bins != h2.length ) {
System.err.println("Incompatible histogram bin numbers : "+bins+" vs "+h2.length +".");
return 1.0;
}
double distance = 0.0;
for ( int i = 0 ; i < bins ; i++ ) distance += Math.abs( h1[i]-h2[i] );
if ( bins > 0 ) distance /= bins;
assert 0 <= distance && distance <= 1 :
this.getClass().getName() + " distance €[0;1] unverified : " + distance + ".";
return distance;
}
public void normalize() {
if ( this.values == null ) return;
int len = this.values.length;
double norm = 0;
for ( int i = 0 ; i < len ; i++ ) norm += this.values[i]*this.values[i];
norm = Math.sqrt( norm );
if ( norm == 0 ) return;
if ( norm != 1 ) for ( int i = 0 ; i < len ; i++ ) this.values[i] /= norm;
}
@SuppressWarnings( "unchecked" )
public static HistogramData getParsedInstance( String [] words, Offset c ) {
HistogramData data = null;
Double [] values;
assert words[c.offset].startsWith(
"<DATA="+new HistogramData().getClass().getName() ) :
"Wrong position of offset " + c.offset + ": \"" + words[c.offset] + "\".";
c.offset++; // pass <Data=...>
if ( c.offset < words.length ) {
data = new HistogramData();
try {
Class desc = Class.forName( words[c.offset++] );
data.setDescriptor( desc );
} catch( ClassNotFoundException ex ) { ex.printStackTrace(); }
values = new Double[ Integer.parseInt( words[c.offset++] ) ];
for ( int i = 0 ; i < values.length ; i++ )
values[i] = Double.parseDouble( words[c.offset++] );
c.offset++; // pass </DATA>
data.setValues( values );
}
return data;
}
@Override
public HistogramData clone() {
HistogramData data = new HistogramData();
data.setDescriptor( this.getDescriptor() );
data.setValues( this.values.clone() );
return data;
}
}