package uk.ac.leeds.ccg.projects.MedAction.NeuralNetwork; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Vector; import uk.ac.leeds.ccg.andyt.grids.AbstractGrid2DSquareCellDouble; /** * Utilities for the NeuralNetwork package. */ public class Utilities { /** Creates a new instance of GeneticUtility */ public Utilities() { } public static int getBite(int value,int position) { return ( value & ( ( int ) Math.pow( 2, position ) ) ) >> position; } public static int randomInt(int size){ return new Double( Math.random() * size ).intValue(); } public static double getRMS( double[] fire, double[] target ) { double temp = 0.0d; for ( int i = 0; i < fire.length; i ++ ) { temp= temp + ( fire[i] - target[i] ) * ( fire[i] - target[i] ); } temp = Math.sqrt( temp / ( fire.length - 1 ) ); return temp; } public static double getRMS( double[][] fire, double[][] target ) { double noDataValue = Double.MIN_VALUE; return getRMS( fire, target, noDataValue ); } public static double getRMS( double[][] fire, double[][] target, double noDataValue ) { double RMSSum = 0.0; for ( int i = 0 ; i < fire[0].length ; i++ ){ double errorSquareSum = 0.0; int noDataCount = 0; for ( int j = 0 ; j < fire.length ; j ++ ) { if ( ( fire[j][i] == noDataValue ) || ( target[j][i] == noDataValue ) ) { noDataCount++; continue; } errorSquareSum = errorSquareSum + ( fire[j][i] - target[j][i] ) * ( fire[j][i] - target[j][i] ); } RMSSum = RMSSum + Math.sqrt( errorSquareSum / ( fire.length - 1 - noDataCount ) ); } return RMSSum / fire[0].length ; } /** * Returns a double[] thats values are those of a double[][] catenated * together */ public static double[] getSingleArray( double[][] multi, int index ) { double[] temp = new double[ multi.length ]; for ( int i=0;i 0.01 && round < maxRounds ) { round ++; cellIDIterator = cellIDs.iterator(); while( cellIDIterator.hasNext() ) { minDistance = Double.MAX_VALUE; cellKey = ( Integer ) cellIDIterator.next(); cellID = cellKey.intValue(); // Calculate the distances (and the minimum) for each cell to // means in meansHashSet, clear clusterIDHashSets. for ( gridID = 0; gridID < inputGrids.length; gridID ++ ) { data[ gridID ] = inputGrids[ gridID ].getCell( cellID ); } for ( gridID = inputGrids.length; gridID < dimension; gridID ++ ) { data[ gridID ] = outputGrids[ gridID ].getCell( cellID ); } for ( clusterID = 0; clusterID < numberOfClusters; clusterID ++ ) { means = ( double[] ) meansHashtable.get( clusterIDKeys[ clusterID ] ); for ( gridID = 0; gridID < dimension; gridID ++ ) { distances[ clusterID ] += ( data[ gridID ] - means[ gridID ] ) * ( data[ gridID ] - means[ gridID ] ); } distances[ clusterID ] = Math.sqrt( distances[ clusterID ] / dimension ); minDistance = Math.min( minDistance, distances[ clusterID ] ); ( ( HashSet ) clusterIDHashSets.get( clusterIDKeys[ clusterID ] ) ).clear(); } // Add cellID to clusterIDHashsets for that clusters with closest mean for ( clusterID = 0; clusterID < numberOfClusters; clusterID ++ ) { if ( distances[ clusterID ] == minDistance ) { ( ( HashSet ) clusterIDHashSets.get( clusterIDKeys[ clusterID ] ) ).add( cellKey ); } } } // Recalculate means from clusters for ( clusterID = 0; clusterID < numberOfClusters; clusterID ++ ) { cluster = ( HashSet ) clusterIDHashSets.get( clusterIDKeys[ clusterID ] ); clusterSize = cluster.size(); if ( clusterSize == 0 ) { // Cluster is empty! A new one is initialise at random. cellID = ( ( Integer ) cellIDMap.get( new Integer( ( int ) Math.ceil( Math.random() * cellCount ) ) ) ).intValue(); data = new double[ dimension ]; for ( gridID = 0; gridID < inputGrids.length; gridID ++ ) { data[ gridID ] = inputGrids[ gridID ].getCell( cellID ); } for ( gridID = inputGrids.length; gridID < dimension; gridID ++ ) { data[ gridID ] = outputGrids[ gridID ].getCell( cellID ); } } else { data = new double[ dimension ]; for ( gridID = 0; gridID < dimension; gridID ++ ) { data[ gridID ] = 0.0d; } while ( clusterIterator.hasNext() ) { cellID = ( ( Integer ) clusterIterator.next() ).intValue(); for ( gridID = 0; gridID < inputGrids.length; gridID ++ ) { data[ gridID ] += inputGrids[ gridID ].getCell( cellID ); } for ( gridID = inputGrids.length; gridID < dimension; gridID ++ ) { data[ gridID ] += outputGrids[ gridID ].getCell( cellID ); } } for ( gridID = 0; gridID < dimension; gridID ++ ) { data[ gridID ] /= clusterSize; } } means = ( double[] ) meansHashtable.get( clusterIDKeys[ clusterID ] ); difference = getDifference( means, data ); //meansHashtable.remove( clusterIDKeys[ clusterID ] ); meansHashtable.put( clusterIDKeys[ clusterID ], data ); } System.out.println( "K-Means Round " + round ); System.out.println( "Difference " + difference ); } return clusterIDHashSets; } private double getDifference( double[] double0, double[] double1 ) { int dimension = double0.length; double difference = 0.0d; for ( int i = 0; i < dimension; i ++ ) { difference += Math.abs( double0[ i ] - double1[ i ] ); } return difference / ( double ) dimension; } /*private double getDifferenceBetweenMeans( Hashtable oldM, Hashtable newM ) { Iterator oldMI = oldM.values().iterator(); int dimension = ( (double[]) oldMI.next() ).length; oldMI = oldM.values().iterator(); Iterator newMI = newM.values().iterator(); double totalDifference = 0.0d; while( oldMI.hasNext() ) { double[] oldMOne = (double[]) oldMI.next(); double[] newMOne = (double[]) newMI.next(); double difference = 0.0d; for ( int i = 0; i < dimension; i ++ ) { difference = difference + Math.abs( oldMOne[ i ] - newMOne[ i ] ); } totalDifference = totalDifference + difference/ dimension; } return totalDifference / oldM.size(); }*/ }