mev-4.0.01/source/org/tigr/microarray/mev/cluster/algorithm/impl/SOM.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 /*
2 26 Feb 07 jari 2 Copyright @ 1999-2003, The Institute for Genomic Research (TIGR).
2 26 Feb 07 jari 3 All rights reserved.
2 26 Feb 07 jari 4 */
2 26 Feb 07 jari 5 /*
2 26 Feb 07 jari 6  * $RCSfile: SOM.java,v $
2 26 Feb 07 jari 7  * $Revision: 1.3 $
2 26 Feb 07 jari 8  * $Date: 2005/03/10 15:45:19 $
2 26 Feb 07 jari 9  * $Author: braistedj $
2 26 Feb 07 jari 10  * $State: Exp $
2 26 Feb 07 jari 11  */
2 26 Feb 07 jari 12 package org.tigr.microarray.mev.cluster.algorithm.impl;
2 26 Feb 07 jari 13
2 26 Feb 07 jari 14 import java.util.ArrayList;
2 26 Feb 07 jari 15 import java.util.Random;
2 26 Feb 07 jari 16
2 26 Feb 07 jari 17 import org.tigr.microarray.mev.cluster.Cluster;
2 26 Feb 07 jari 18 import org.tigr.microarray.mev.cluster.Node;
2 26 Feb 07 jari 19 import org.tigr.microarray.mev.cluster.NodeList;
2 26 Feb 07 jari 20 import org.tigr.microarray.mev.cluster.NodeValue;
2 26 Feb 07 jari 21 import org.tigr.microarray.mev.cluster.NodeValueList;
2 26 Feb 07 jari 22 import org.tigr.microarray.mev.cluster.algorithm.AbortException;
2 26 Feb 07 jari 23 import org.tigr.microarray.mev.cluster.algorithm.AbstractAlgorithm;
2 26 Feb 07 jari 24 import org.tigr.microarray.mev.cluster.algorithm.AlgorithmData;
2 26 Feb 07 jari 25 import org.tigr.microarray.mev.cluster.algorithm.AlgorithmEvent;
2 26 Feb 07 jari 26 import org.tigr.microarray.mev.cluster.algorithm.AlgorithmException;
2 26 Feb 07 jari 27 import org.tigr.microarray.mev.cluster.algorithm.AlgorithmParameters;
2 26 Feb 07 jari 28 import org.tigr.util.FloatMatrix;
2 26 Feb 07 jari 29
2 26 Feb 07 jari 30 public class SOM extends AbstractAlgorithm {
2 26 Feb 07 jari 31     
2 26 Feb 07 jari 32     private static final int INDEX_X = 0;
2 26 Feb 07 jari 33     private static final int INDEX_Y = 1;
2 26 Feb 07 jari 34     private static final int WINNER_INFO_SIZE = 2;
2 26 Feb 07 jari 35     
2 26 Feb 07 jari 36     private boolean stop = false;
2 26 Feb 07 jari 37     
2 26 Feb 07 jari 38     private int function;
2 26 Feb 07 jari 39     private int dim_x;
2 26 Feb 07 jari 40     private int dim_y;
2 26 Feb 07 jari 41     private float factor;
2 26 Feb 07 jari 42     private boolean absolute;
2 26 Feb 07 jari 43     private String topology;
2 26 Feb 07 jari 44     private boolean somGenes;
2 26 Feb 07 jari 45     
2 26 Feb 07 jari 46     private int number_of_genes;
2 26 Feb 07 jari 47     private int number_of_samples;
2 26 Feb 07 jari 48     
2 26 Feb 07 jari 49     private FloatMatrix expMatrix;
2 26 Feb 07 jari 50     private float[][][] somCodes;
2 26 Feb 07 jari 51     private int validN;
2 26 Feb 07 jari 52
2 26 Feb 07 jari 53     private int hcl_function;
2 26 Feb 07 jari 54     private boolean hcl_absolute;    
2 26 Feb 07 jari 55     
2 26 Feb 07 jari 56     public AlgorithmData execute(AlgorithmData data) throws AlgorithmException {
2 26 Feb 07 jari 57         
2 26 Feb 07 jari 58         AlgorithmParameters map = data.getParams();
2 26 Feb 07 jari 59         
2 26 Feb 07 jari 60         function = map.getInt("distance-function", EUCLIDEAN);
2 26 Feb 07 jari 61         factor   = map.getFloat("distance-factor", 1.0f);
2 26 Feb 07 jari 62         absolute = map.getBoolean("distance-absolute", false);
2 26 Feb 07 jari 63         somGenes = map.getBoolean("som-cluster-genes", true);
2 26 Feb 07 jari 64         
2 26 Feb 07 jari 65         dim_x = map.getInt("dimension-x", 0);
2 26 Feb 07 jari 66         dim_y = map.getInt("dimension-y", 0);
2 26 Feb 07 jari 67         int iterations = map.getInt("iterations", 0);
2 26 Feb 07 jari 68         topology = map.getString("topology");
2 26 Feb 07 jari 69         boolean adoptType = topology != null ? topology.compareTo("rectangular")==0 : true;
2 26 Feb 07 jari 70         boolean is_neighborhood_bubble = map.getBoolean("is_neighborhood_bubble", true);
2 26 Feb 07 jari 71         boolean is_random_vector = map.getBoolean("is_random_vector", true);
2 26 Feb 07 jari 72         float radius = map.getFloat("radius", 0.0f);
2 26 Feb 07 jari 73         float alpha  = map.getFloat("alpha" , 0.0f);
2 26 Feb 07 jari 74         
2 26 Feb 07 jari 75         // hcl parameters
2 26 Feb 07 jari 76         boolean hierarchical_tree = map.getBoolean("hierarchical-tree", false);
2 26 Feb 07 jari 77         int method_linkage = map.getInt("method-linkage", 0);
2 26 Feb 07 jari 78         boolean calculate_genes = map.getBoolean("calculate-genes", false);
2 26 Feb 07 jari 79         boolean calculate_experiments = map.getBoolean("calculate-experiments", false);
2 26 Feb 07 jari 80         
2 26 Feb 07 jari 81         this.expMatrix = data.getMatrix("experiment");
2 26 Feb 07 jari 82         
2 26 Feb 07 jari 83         hcl_function = map.getInt("hcl-distance-function", EUCLIDEAN);
2 26 Feb 07 jari 84         hcl_absolute = map.getBoolean("hcl-distance-absolute", false);
2 26 Feb 07 jari 85         
2 26 Feb 07 jari 86         number_of_genes   = this.expMatrix.getRowDimension();
2 26 Feb 07 jari 87         number_of_samples = this.expMatrix.getColumnDimension();
2 26 Feb 07 jari 88         
2 26 Feb 07 jari 89         if (is_random_vector) {
2 26 Feb 07 jari 90             this.somCodes = randomVectorInit();
2 26 Feb 07 jari 91         } else {
2 26 Feb 07 jari 92             this.somCodes = randomGeneInit();
2 26 Feb 07 jari 93         }
2 26 Feb 07 jari 94         
2 26 Feb 07 jari 95         int[] winner_info = new int[WINNER_INFO_SIZE];
2 26 Feb 07 jari 96         float cRadius = radius;
2 26 Feb 07 jari 97         float cAlpha = alpha;
2 26 Feb 07 jari 98         AlgorithmEvent event = new AlgorithmEvent(this, AlgorithmEvent.SET_UNITS, 200, "Training...");
2 26 Feb 07 jari 99         fireValueChanged(event);
2 26 Feb 07 jari 100         event.setId(AlgorithmEvent.PROGRESS_VALUE);
2 26 Feb 07 jari 101         event.setIntValue(0);
2 26 Feb 07 jari 102         int sample = 0;
2 26 Feb 07 jari 103         long progress = iterations/200;
2 26 Feb 07 jari 104         for (int i=0; i<iterations; i++) {
2 26 Feb 07 jari 105             if (stop) {
2 26 Feb 07 jari 106                 throw new AbortException();
2 26 Feb 07 jari 107             }
2 26 Feb 07 jari 108             if (i%progress == 0) {
2 26 Feb 07 jari 109                 event.setIntValue(event.getIntValue()+1);
2 26 Feb 07 jari 110                 fireValueChanged(event);
2 26 Feb 07 jari 111             }
2 26 Feb 07 jari 112             /* Radius decreases linearly to one */
2 26 Feb 07 jari 113             cRadius = 1.0f + (radius - 1.0f)*(float)(iterations-i)/(float)iterations;
2 26 Feb 07 jari 114             /* Calculate Learning rate */
2 26 Feb 07 jari 115             cAlpha = linearAlpha(i, iterations, alpha);
2 26 Feb 07 jari 116             /* Find the best match */
2 26 Feb 07 jari 117             findWinnerEuclidean(winner_info, sample);
2 26 Feb 07 jari 118             /* Adapt the units */
2 26 Feb 07 jari 119             if (is_neighborhood_bubble) {
2 26 Feb 07 jari 120                 bubbleAdapt(sample, winner_info, cRadius, cAlpha, adoptType);
2 26 Feb 07 jari 121             } else {
2 26 Feb 07 jari 122                 gaussianAdapt(sample, winner_info, cRadius, cAlpha, adoptType);
2 26 Feb 07 jari 123             }
2 26 Feb 07 jari 124             sample++;
2 26 Feb 07 jari 125             if (sample >= number_of_genes) {
2 26 Feb 07 jari 126                 sample = 0;
2 26 Feb 07 jari 127             }
2 26 Feb 07 jari 128         }
2 26 Feb 07 jari 129         
2 26 Feb 07 jari 130         // clustering...
2 26 Feb 07 jari 131         SOMMatrix clusters = new SOMMatrix(dim_x, dim_y, 0);
2 26 Feb 07 jari 132         FloatMatrix u_matrix = new FloatMatrix(dim_x, dim_y);
2 26 Feb 07 jari 133         calculateClusters(clusters, u_matrix);
2 26 Feb 07 jari 134         
2 26 Feb 07 jari 135         AlgorithmData result = new AlgorithmData();
2 26 Feb 07 jari 136         FloatMatrix matrix = new FloatMatrix(dim_x*dim_y, number_of_samples);
2 26 Feb 07 jari 137         // copying somCodes
2 26 Feb 07 jari 138         for (int i=0; i<number_of_samples; i++) {
2 26 Feb 07 jari 139             for (int x=0; x<dim_x; x++) {
2 26 Feb 07 jari 140                 for (int y=0; y<dim_y; y++) {
2 26 Feb 07 jari 141                     matrix.set(x*dim_y+y, i, somCodes[x][y][i]);
2 26 Feb 07 jari 142                 }
2 26 Feb 07 jari 143             }
2 26 Feb 07 jari 144         }
2 26 Feb 07 jari 145         result.addMatrix("codes", matrix);
2 26 Feb 07 jari 146         
2 26 Feb 07 jari 147         // means, variances...
2 26 Feb 07 jari 148         FloatMatrix means     = new FloatMatrix(dim_x*dim_y, number_of_samples);
2 26 Feb 07 jari 149         FloatMatrix variances = new FloatMatrix(dim_x*dim_y, number_of_samples);
2 26 Feb 07 jari 150         int[] features;
2 26 Feb 07 jari 151         int dimension;
2 26 Feb 07 jari 152         
2 26 Feb 07 jari 153         Cluster result_cluster = new Cluster();
2 26 Feb 07 jari 154         NodeList nodeList = result_cluster.getNodeList();
2 26 Feb 07 jari 155         
2 26 Feb 07 jari 156         for (int x=0; x<dim_x; x++) {
2 26 Feb 07 jari 157             for (int y=0; y<dim_y; y++) {
2 26 Feb 07 jari 158                 // copying the clusters
2 26 Feb 07 jari 159                 features = getFeatures(clusters.getArrayList(x, y));
2 26 Feb 07 jari 160                 
2 26 Feb 07 jari 161                 dimension = x*dim_y+y;
2 26 Feb 07 jari 162                 fillMean(means.A[dimension], features);
2 26 Feb 07 jari 163                 fillVariance(variances.A[dimension], means.A[dimension], features);
2 26 Feb 07 jari 164                 
2 26 Feb 07 jari 165                 Node node = new Node(features);
2 26 Feb 07 jari 166                 nodeList.addNode(node);
2 26 Feb 07 jari 167             }
2 26 Feb 07 jari 168         }
2 26 Feb 07 jari 169         if (hierarchical_tree) {
2 26 Feb 07 jari 170             calculateHierarchicalTrees(result_cluster, method_linkage, calculate_genes, calculate_experiments);
2 26 Feb 07 jari 171         }
2 26 Feb 07 jari 172         
2 26 Feb 07 jari 173         result.addCluster("cluster", result_cluster);
2 26 Feb 07 jari 174         result.addMatrix("clusters_means", means);
2 26 Feb 07 jari 175         result.addMatrix("clusters_variances", variances);
2 26 Feb 07 jari 176         // copying the u-matrix
2 26 Feb 07 jari 177         result.addMatrix("u_matrix", u_matrix);
2 26 Feb 07 jari 178         
2 26 Feb 07 jari 179         return result;
2 26 Feb 07 jari 180     }
2 26 Feb 07 jari 181     
2 26 Feb 07 jari 182     private void calculateHierarchicalTrees(Cluster cluster, int method, boolean genes, boolean experiments) throws AlgorithmException {
2 26 Feb 07 jari 183         NodeList nodeList = cluster.getNodeList();
2 26 Feb 07 jari 184         
2 26 Feb 07 jari 185         AlgorithmEvent event = new AlgorithmEvent(this, AlgorithmEvent.SET_UNITS, nodeList.getSize(), "Calculate Hierarchical Trees");
2 26 Feb 07 jari 186         fireValueChanged(event);
2 26 Feb 07 jari 187         event.setId(AlgorithmEvent.PROGRESS_VALUE);
2 26 Feb 07 jari 188         
2 26 Feb 07 jari 189         Node node;
2 26 Feb 07 jari 190         for (int i=0; i<nodeList.getSize(); i++) {
2 26 Feb 07 jari 191             if (stop) {
2 26 Feb 07 jari 192                 throw new AbortException();
2 26 Feb 07 jari 193             }
2 26 Feb 07 jari 194             event.setIntValue(i);
2 26 Feb 07 jari 195             fireValueChanged(event);
2 26 Feb 07 jari 196             
2 26 Feb 07 jari 197             node = nodeList.getNode(i);
2 26 Feb 07 jari 198             node.setValues(calculateHierarchicalTree(node.getFeaturesIndexes(), method, genes, experiments));
2 26 Feb 07 jari 199         }
2 26 Feb 07 jari 200     }
2 26 Feb 07 jari 201     
2 26 Feb 07 jari 202     private NodeValueList calculateHierarchicalTree(int[] features, int method, boolean genes, boolean experiments) throws AlgorithmException {
2 26 Feb 07 jari 203         NodeValueList nodeList = new NodeValueList();
2 26 Feb 07 jari 204         AlgorithmData data = new AlgorithmData();
2 26 Feb 07 jari 205         FloatMatrix experiment;
2 26 Feb 07 jari 206         if(somGenes)
2 26 Feb 07 jari 207             experiment = getSubExperiment(this.expMatrix, features);
2 26 Feb 07 jari 208         else
2 26 Feb 07 jari 209             experiment = getSubExperimentReducedCols(this.expMatrix, features);
2 26 Feb 07 jari 210         
2 26 Feb 07 jari 211         data.addMatrix("experiment", experiment);
2 26 Feb 07 jari 212         data.addParam("hcl-distance-function", String.valueOf(this.hcl_function));
2 26 Feb 07 jari 213         data.addParam("hcl-distance-absolute", String.valueOf(this.hcl_absolute));
2 26 Feb 07 jari 214         data.addParam("method-linkage", String.valueOf(method));
2 26 Feb 07 jari 215         HCL hcl = new HCL();
2 26 Feb 07 jari 216         AlgorithmData result;
2 26 Feb 07 jari 217         if (genes) {
2 26 Feb 07 jari 218             data.addParam("calculate-genes", String.valueOf(true));
2 26 Feb 07 jari 219             result = hcl.execute(data);
2 26 Feb 07 jari 220             validate(result);
2 26 Feb 07 jari 221             addNodeValues(nodeList, result);
2 26 Feb 07 jari 222         }
2 26 Feb 07 jari 223         if (experiments) {
2 26 Feb 07 jari 224             data.addParam("calculate-genes", String.valueOf(false));
2 26 Feb 07 jari 225             result = hcl.execute(data);
2 26 Feb 07 jari 226             validate(result);
2 26 Feb 07 jari 227             addNodeValues(nodeList, result);
2 26 Feb 07 jari 228         }
2 26 Feb 07 jari 229         return nodeList;
2 26 Feb 07 jari 230     }
2 26 Feb 07 jari 231     
2 26 Feb 07 jari 232     private void addNodeValues(NodeValueList target_list, AlgorithmData source_result) {
2 26 Feb 07 jari 233         target_list.addNodeValue(new NodeValue("child-1-array", source_result.getIntArray("child-1-array")));
2 26 Feb 07 jari 234         target_list.addNodeValue(new NodeValue("child-2-array", source_result.getIntArray("child-2-array")));
2 26 Feb 07 jari 235         target_list.addNodeValue(new NodeValue("node-order", source_result.getIntArray("node-order")));
2 26 Feb 07 jari 236         target_list.addNodeValue(new NodeValue("height", source_result.getMatrix("height").getRowPackedCopy()));
2 26 Feb 07 jari 237     }
2 26 Feb 07 jari 238     
2 26 Feb 07 jari 239     private FloatMatrix getSubExperiment(FloatMatrix experiment, int[] features) {
2 26 Feb 07 jari 240         FloatMatrix subExperiment = new FloatMatrix(features.length, experiment.getColumnDimension());
2 26 Feb 07 jari 241         for (int i=0; i<features.length; i++) {
2 26 Feb 07 jari 242             subExperiment.A[i] = experiment.A[features[i]];
2 26 Feb 07 jari 243         }
2 26 Feb 07 jari 244         return subExperiment;
2 26 Feb 07 jari 245     }
2 26 Feb 07 jari 246     
2 26 Feb 07 jari 247     /**
2 26 Feb 07 jari 248      *  Creates a matrix with reduced columns (samples) as during experiment clustering
2 26 Feb 07 jari 249      */
2 26 Feb 07 jari 250     private FloatMatrix getSubExperimentReducedCols(FloatMatrix experiment, int[] features) {
2 26 Feb 07 jari 251         FloatMatrix copyMatrix = experiment.copy();
2 26 Feb 07 jari 252         FloatMatrix subExperiment = new FloatMatrix(features.length, copyMatrix.getColumnDimension());
2 26 Feb 07 jari 253         for (int i=0; i<features.length; i++) {
2 26 Feb 07 jari 254             subExperiment.A[i] = copyMatrix.A[features[i]];
2 26 Feb 07 jari 255         }
2 26 Feb 07 jari 256         subExperiment = subExperiment.transpose();
2 26 Feb 07 jari 257         return subExperiment;
2 26 Feb 07 jari 258     }
2 26 Feb 07 jari 259     
2 26 Feb 07 jari 260     /**
2 26 Feb 07 jari 261      * Checking the result of hcl algorithm calculation.
2 26 Feb 07 jari 262      * @throws AlgorithmException, if the result is incorrect.
2 26 Feb 07 jari 263      */
2 26 Feb 07 jari 264     private void validate(AlgorithmData result) throws AlgorithmException {
2 26 Feb 07 jari 265         if (result.getIntArray("child-1-array") == null) {
2 26 Feb 07 jari 266             throw new AlgorithmException("parameter 'child-1-array' is null");
2 26 Feb 07 jari 267         }
2 26 Feb 07 jari 268         if (result.getIntArray("child-2-array") == null) {
2 26 Feb 07 jari 269             throw new AlgorithmException("parameter 'child-2-array' is null");
2 26 Feb 07 jari 270         }
2 26 Feb 07 jari 271         if (result.getIntArray("node-order") == null) {
2 26 Feb 07 jari 272             throw new AlgorithmException("parameter 'node-order' is null");
2 26 Feb 07 jari 273         }
2 26 Feb 07 jari 274         if (result.getMatrix("height") == null) {
2 26 Feb 07 jari 275             throw new AlgorithmException("parameter 'height' is null");
2 26 Feb 07 jari 276         }
2 26 Feb 07 jari 277     }
2 26 Feb 07 jari 278     
2 26 Feb 07 jari 279     public void abort() {
2 26 Feb 07 jari 280         stop = true;
2 26 Feb 07 jari 281     }
2 26 Feb 07 jari 282     
2 26 Feb 07 jari 283     private int[] getFeatures(ArrayList source) {
2 26 Feb 07 jari 284         int[] cluster = new int[source.size()];
2 26 Feb 07 jari 285         for (int i=0; i<cluster.length; i++) {
2 26 Feb 07 jari 286             cluster[i] = ((Float)source.get(i)).intValue();
2 26 Feb 07 jari 287         }
2 26 Feb 07 jari 288         return cluster;
2 26 Feb 07 jari 289     }
2 26 Feb 07 jari 290     
2 26 Feb 07 jari 291     private float[][][] randomGeneInit() {
2 26 Feb 07 jari 292         Random random = new Random(System.currentTimeMillis());
2 26 Feb 07 jari 293         float[][][] somCodes = new float[dim_x][dim_y][number_of_samples];
2 26 Feb 07 jari 294         int gene;
2 26 Feb 07 jari 295         for (int y=0; y<dim_y; y++) {
2 26 Feb 07 jari 296             for (int x=0; x<dim_x; x++) {
2 26 Feb 07 jari 297                 gene = (int)(random.nextFloat()*number_of_genes);
2 26 Feb 07 jari 298                 for (int k=0; k<number_of_samples; k++) {
2 26 Feb 07 jari 299                     somCodes[x][y][k] = this.expMatrix.get(gene, k);
2 26 Feb 07 jari 300                 }
2 26 Feb 07 jari 301             }
2 26 Feb 07 jari 302         }
2 26 Feb 07 jari 303         return somCodes;
2 26 Feb 07 jari 304     }
2 26 Feb 07 jari 305     
2 26 Feb 07 jari 306     private float[][][] randomVectorInit() {
2 26 Feb 07 jari 307         float[][][] somCodes = new float[dim_x][dim_y][number_of_samples];
2 26 Feb 07 jari 308         float[] maxValue = new float[number_of_samples];
2 26 Feb 07 jari 309         float[] minValue = new float[number_of_samples];
2 26 Feb 07 jari 310         int i, j, k;
2 26 Feb 07 jari 311         for (i=0; i<number_of_samples; i++) {
2 26 Feb 07 jari 312             minValue[i] = Float.MAX_VALUE;
2 26 Feb 07 jari 313             maxValue[i] = Float.MIN_VALUE;
2 26 Feb 07 jari 314         }
2 26 Feb 07 jari 315         float dummy;
2 26 Feb 07 jari 316         for (i=0; i<number_of_genes; i++) {
2 26 Feb 07 jari 317             for (j=0; j<number_of_samples; j++) {
2 26 Feb 07 jari 318                 dummy = expMatrix.get(i, j);
2 26 Feb 07 jari 319                 if (!Float.isNaN(dummy)) {
2 26 Feb 07 jari 320                     if (maxValue[j] < dummy) {
2 26 Feb 07 jari 321                         maxValue[j] = dummy;
2 26 Feb 07 jari 322                     }
2 26 Feb 07 jari 323                     if (minValue[j] > dummy) {
2 26 Feb 07 jari 324                         minValue[j] = dummy;
2 26 Feb 07 jari 325                     }
2 26 Feb 07 jari 326                 }
2 26 Feb 07 jari 327             }
2 26 Feb 07 jari 328         }
2 26 Feb 07 jari 329         
2 26 Feb 07 jari 330         float value;
2 26 Feb 07 jari 331         Random random = new Random(System.currentTimeMillis());
2 26 Feb 07 jari 332         for (i=0; i<dim_x; i++) {
2 26 Feb 07 jari 333             for (j=0; j<dim_y; j++) {
2 26 Feb 07 jari 334                 for (k=0; k<number_of_samples; k++) {
2 26 Feb 07 jari 335                     value = minValue[k]+(maxValue[k]-minValue[k])*random.nextFloat();
2 26 Feb 07 jari 336                     somCodes[i][j][k] = value;
2 26 Feb 07 jari 337                 }
2 26 Feb 07 jari 338             }
2 26 Feb 07 jari 339         }
2 26 Feb 07 jari 340         return somCodes;
2 26 Feb 07 jari 341     }
2 26 Feb 07 jari 342     
2 26 Feb 07 jari 343     
2 26 Feb 07 jari 344     /**
2 26 Feb 07 jari 345      * find_winner_euc - finds the winning entry (1 nearest neighbour) in
2 26 Feb 07 jari 346      * codebook using euclidean distance. Information about the winning
2 26 Feb 07 jari 347      * entry is saved in the winner_info structure. Return 1 (the number
2 26 Feb 07 jari 348      * of neighbours) when successful and 0 when winner could not be found
2 26 Feb 07 jari 349      * (for example, all components of data vector have been masked off)
2 26 Feb 07 jari 350      */
2 26 Feb 07 jari 351     private final float findWinnerEuclidean(int[] winner_info, int sample) {
2 26 Feb 07 jari 352         winner_info[INDEX_X] = -1;
2 26 Feb 07 jari 353         winner_info[INDEX_Y] = -1;
2 26 Feb 07 jari 354         float winner_distance = -1.0f;
2 26 Feb 07 jari 355         
2 26 Feb 07 jari 356         if (number_of_samples == 1) {
2 26 Feb 07 jari 357             return winner_distance;
2 26 Feb 07 jari 358         }
2 26 Feb 07 jari 359         
2 26 Feb 07 jari 360         int x, y, i;
2 26 Feb 07 jari 361         double difference;
2 26 Feb 07 jari 362         double diffsf = Double.MAX_VALUE;
2 26 Feb 07 jari 363         
2 26 Feb 07 jari 364         FloatMatrix dummyMatrix = new FloatMatrix(1, number_of_samples);
2 26 Feb 07 jari 365         
2 26 Feb 07 jari 366         for (y=0; y<dim_y; y++) {
2 26 Feb 07 jari 367             for (x=0; x<dim_x; x++) {
2 26 Feb 07 jari 368                 for (i = 0; i < number_of_samples; i++) {
2 26 Feb 07 jari 369                     dummyMatrix.set(0, i, somCodes[x][y][i]);
2 26 Feb 07 jari 370                 }
2 26 Feb 07 jari 371                 difference = ExperimentUtil.geneDistance(expMatrix, dummyMatrix, sample, 0, function, factor, absolute);
2 26 Feb 07 jari 372                 /* If distance is smaller than previous distances */
2 26 Feb 07 jari 373                 if (difference <= diffsf) {
2 26 Feb 07 jari 374                     winner_info[INDEX_X] = x;
2 26 Feb 07 jari 375                     winner_info[INDEX_Y] = y;
2 26 Feb 07 jari 376                     diffsf = difference;
2 26 Feb 07 jari 377                     winner_distance = (float)difference;
2 26 Feb 07 jari 378                 }
2 26 Feb 07 jari 379             }
2 26 Feb 07 jari 380         }
2 26 Feb 07 jari 381         return winner_distance;
2 26 Feb 07 jari 382     }
2 26 Feb 07 jari 383     
2 26 Feb 07 jari 384     private void bubbleAdapt(int sample, int[] winner_info, float radius, float alpha, boolean rectangular) {
2 26 Feb 07 jari 385         long index = 0;
2 26 Feb 07 jari 386         int tx, ty, xdim, ydim;
2 26 Feb 07 jari 387         int x, y;
2 26 Feb 07 jari 388         for (y=0; y<dim_y; y++) {
2 26 Feb 07 jari 389             for (x=0; x<dim_x; x++) {
2 26 Feb 07 jari 390                 if (rectangular) {
2 26 Feb 07 jari 391                     if (rectangularDistance(winner_info, x, y) <= radius) {
2 26 Feb 07 jari 392                         adaptVector(sample, x, y, alpha);
2 26 Feb 07 jari 393                     }
2 26 Feb 07 jari 394                 } else {
2 26 Feb 07 jari 395                     if (hexagonalDistance(winner_info, x, y) <= radius) {
2 26 Feb 07 jari 396                         adaptVector(sample, x, y, alpha);
2 26 Feb 07 jari 397                     }
2 26 Feb 07 jari 398                 }
2 26 Feb 07 jari 399             }
2 26 Feb 07 jari 400         }
2 26 Feb 07 jari 401     }
2 26 Feb 07 jari 402     
2 26 Feb 07 jari 403     private void gaussianAdapt(int sample, int[] winner_info, float radius, float alpha, boolean rectangular) {
2 26 Feb 07 jari 404         long index = 0;
2 26 Feb 07 jari 405         int tx, ty, xdim, ydim;
2 26 Feb 07 jari 406         float dd, alp;
2 26 Feb 07 jari 407         int x, y;
2 26 Feb 07 jari 408         for (y=0; y<dim_y; y++) {
2 26 Feb 07 jari 409             for (x=0; x<dim_x; x++) {
2 26 Feb 07 jari 410                 if (rectangular) {
2 26 Feb 07 jari 411                     dd = rectangularDistance(winner_info, x, y);
2 26 Feb 07 jari 412                 } else {
2 26 Feb 07 jari 413                     dd = hexagonalDistance(winner_info, x, y);
2 26 Feb 07 jari 414                 }
2 26 Feb 07 jari 415                 alp = alpha*(float)Math.exp((float)(-dd*dd/(2.0*radius*radius)));
2 26 Feb 07 jari 416                 adaptVector(sample, x, y, alp);
2 26 Feb 07 jari 417             }
2 26 Feb 07 jari 418         }
2 26 Feb 07 jari 419     }
2 26 Feb 07 jari 420     
2 26 Feb 07 jari 421     private float rectangularDistance(int[] winner_info, int tx, int ty) {
2 26 Feb 07 jari 422         float ret, diff;
2 26 Feb 07 jari 423         diff = winner_info[INDEX_X] - tx;
2 26 Feb 07 jari 424         ret = diff * diff;
2 26 Feb 07 jari 425         diff = winner_info[INDEX_Y] - ty;
2 26 Feb 07 jari 426         ret += diff * diff;
2 26 Feb 07 jari 427         ret = (float)Math.sqrt((float)ret);
2 26 Feb 07 jari 428         return(ret);
2 26 Feb 07 jari 429     }
2 26 Feb 07 jari 430     
2 26 Feb 07 jari 431     private float hexagonalDistance(int[] winner_info, int tx, int ty) {
2 26 Feb 07 jari 432         float ret, diff;
2 26 Feb 07 jari 433         diff = winner_info[INDEX_X] - tx;
2 26 Feb 07 jari 434         if (((winner_info[INDEX_Y] - ty) % 2) != 0) {
2 26 Feb 07 jari 435             if ((winner_info[INDEX_Y] % 2) == 0) {
2 26 Feb 07 jari 436                 diff -= 0.5;
2 26 Feb 07 jari 437             } else {
2 26 Feb 07 jari 438                 diff += 0.5;
2 26 Feb 07 jari 439             }
2 26 Feb 07 jari 440         }
2 26 Feb 07 jari 441         ret = diff * diff;
2 26 Feb 07 jari 442         diff = winner_info[INDEX_Y] - ty;
2 26 Feb 07 jari 443         ret += 0.75 * diff * diff;
2 26 Feb 07 jari 444         ret = (float)Math.sqrt((float) ret);
2 26 Feb 07 jari 445         return(ret);
2 26 Feb 07 jari 446     }
2 26 Feb 07 jari 447     
2 26 Feb 07 jari 448     /* adapt_vector - move a codebook vector towards another vector */
2 26 Feb 07 jari 449     private void adaptVector(int sample, int x, int y, float alpha) {
2 26 Feb 07 jari 450         int i;
2 26 Feb 07 jari 451         for (i = 0; i < number_of_samples; i++) {
2 26 Feb 07 jari 452             if (Float.isNaN(expMatrix.get(sample, i))) {
2 26 Feb 07 jari 453                 continue; // ignore vector components that have 1 in mask
2 26 Feb 07 jari 454             } else {
2 26 Feb 07 jari 455                 somCodes[x][y][i] = somCodes[x][y][i] + alpha*(expMatrix.get(sample, i)-somCodes[x][y][i]);
2 26 Feb 07 jari 456             }
2 26 Feb 07 jari 457         }
2 26 Feb 07 jari 458     }
2 26 Feb 07 jari 459     
2 26 Feb 07 jari 460     private float linearAlpha(long currentIteration, long iterations, float alpha) {
2 26 Feb 07 jari 461         return(alpha*(float)(iterations-currentIteration)/(float)iterations);
2 26 Feb 07 jari 462     }
2 26 Feb 07 jari 463     
2 26 Feb 07 jari 464     private void calculateClusters(SOMMatrix clusters, FloatMatrix u_matrix) throws AlgorithmException {
2 26 Feb 07 jari 465         AlgorithmEvent event = new AlgorithmEvent(this, AlgorithmEvent.SET_UNITS, number_of_genes, "Creation of the clusters...");
2 26 Feb 07 jari 466         fireValueChanged(event);
2 26 Feb 07 jari 467         event.setId(AlgorithmEvent.PROGRESS_VALUE);
2 26 Feb 07 jari 468         
2 26 Feb 07 jari 469         SOMMatrix distances = new SOMMatrix(dim_x, dim_y, 0);
2 26 Feb 07 jari 470         for (int y=0; y<dim_y; y++) {
2 26 Feb 07 jari 471             for (int x=0; x<dim_x; x++) {
2 26 Feb 07 jari 472                 u_matrix.set(x, y, 0f);
2 26 Feb 07 jari 473             }
2 26 Feb 07 jari 474         }
2 26 Feb 07 jari 475         float winner_distance;
2 26 Feb 07 jari 476         float max_winner_distance = 0f;
2 26 Feb 07 jari 477         int[] winner_info = new int[WINNER_INFO_SIZE];
2 26 Feb 07 jari 478         int counter;
2 26 Feb 07 jari 479         for (int i=0; i<number_of_genes; i++) {
2 26 Feb 07 jari 480             if (stop) {
2 26 Feb 07 jari 481                 throw new AbortException();
2 26 Feb 07 jari 482             }
2 26 Feb 07 jari 483             winner_distance = findWinnerEuclidean(winner_info, i);
2 26 Feb 07 jari 484             if (winner_info[INDEX_X]==-1 || winner_info[INDEX_Y]==-1) {
2 26 Feb 07 jari 485             } else {
2 26 Feb 07 jari 486                 max_winner_distance = Math.max(winner_distance, max_winner_distance);
2 26 Feb 07 jari 487                 
2 26 Feb 07 jari 488                 if (winner_distance > u_matrix.get(winner_info[INDEX_X], winner_info[INDEX_Y])) {
2 26 Feb 07 jari 489                     u_matrix.set(winner_info[INDEX_X], winner_info[INDEX_Y], winner_distance);
2 26 Feb 07 jari 490                 }
2 26 Feb 07 jari 491                 counter = 0;
2 26 Feb 07 jari 492                 for (int j=0; j < distances.getDimension(winner_info[INDEX_X], winner_info[INDEX_Y]); j++) {
2 26 Feb 07 jari 493                     if (winner_distance < distances.getValue(winner_info[INDEX_X], winner_info[INDEX_Y], j)) {
2 26 Feb 07 jari 494                         break;
2 26 Feb 07 jari 495                     }
2 26 Feb 07 jari 496                     counter++;
2 26 Feb 07 jari 497                 }
2 26 Feb 07 jari 498                 distances.insertValue(winner_info[INDEX_X], winner_info[INDEX_Y], counter, winner_distance);
2 26 Feb 07 jari 499                 clusters.insertValue(winner_info[INDEX_X], winner_info[INDEX_Y], counter, i);
2 26 Feb 07 jari 500             }
2 26 Feb 07 jari 501             event.setIntValue(i);
2 26 Feb 07 jari 502             fireValueChanged(event);
2 26 Feb 07 jari 503         }
2 26 Feb 07 jari 504         for (int y = 0; y < dim_y; y++) {
2 26 Feb 07 jari 505             for (int x = 0; x < dim_x; x++) {
2 26 Feb 07 jari 506                 u_matrix.set(x, y, u_matrix.get(x, y)/max_winner_distance);
2 26 Feb 07 jari 507             }
2 26 Feb 07 jari 508         }
2 26 Feb 07 jari 509     }
2 26 Feb 07 jari 510     
2 26 Feb 07 jari 511     private void fillMean(float[] means, int[] cluster) {
2 26 Feb 07 jari 512         float currentMean;
2 26 Feb 07 jari 513         int n = cluster.length;
2 26 Feb 07 jari 514         validN = 0;
2 26 Feb 07 jari 515         float value;
2 26 Feb 07 jari 516         for (int i=0; i<number_of_samples; i++) {
2 26 Feb 07 jari 517             currentMean = 0f;
2 26 Feb 07 jari 518             validN = 0;
2 26 Feb 07 jari 519             for (int j=0; j<n; j++) {
2 26 Feb 07 jari 520                 value = expMatrix.get(cluster[j], i);
2 26 Feb 07 jari 521                 if (!Float.isNaN(value)) {
2 26 Feb 07 jari 522                     currentMean += value;
2 26 Feb 07 jari 523                     validN++;
2 26 Feb 07 jari 524                 }
2 26 Feb 07 jari 525             }
2 26 Feb 07 jari 526               means[i] = currentMean/(float)validN;               
2 26 Feb 07 jari 527         }
2 26 Feb 07 jari 528     }
2 26 Feb 07 jari 529     
2 26 Feb 07 jari 530     private void fillVariance(float[] variances, float[] means, int[] cluster) {
2 26 Feb 07 jari 531         for (int i=0; i<number_of_samples; i++) {
2 26 Feb 07 jari 532             variances[i] = getSampleVariance(cluster, i, means[i]);
2 26 Feb 07 jari 533         }        
2 26 Feb 07 jari 534     }
2 26 Feb 07 jari 535     
2 26 Feb 07 jari 536     private float getSampleNormalizedSum(int[] cluster, int column, float mean) {
2 26 Feb 07 jari 537         float sum = 0f;
2 26 Feb 07 jari 538         float value;
2 26 Feb 07 jari 539         validN = 0;
2 26 Feb 07 jari 540         for (int i=0; i<cluster.length; i++) {
2 26 Feb 07 jari 541             value = expMatrix.get(cluster[i], column);
2 26 Feb 07 jari 542             if (!Float.isNaN(value)) {
2 26 Feb 07 jari 543                 sum += Math.pow(value-mean, 2);
2 26 Feb 07 jari 544                 validN++;
2 26 Feb 07 jari 545             }
2 26 Feb 07 jari 546         }
2 26 Feb 07 jari 547         return sum;
2 26 Feb 07 jari 548     }
2 26 Feb 07 jari 549     
2 26 Feb 07 jari 550     private float getSampleVariance(int[] cluster, int column, float mean) {
2 26 Feb 07 jari 551         if(validN > 1)
2 26 Feb 07 jari 552         return(float)Math.sqrt(getSampleNormalizedSum(cluster, column, mean)/(float)(validN-1));
2 26 Feb 07 jari 553         else
2 26 Feb 07 jari 554             return 0f;
2 26 Feb 07 jari 555     }
2 26 Feb 07 jari 556     
2 26 Feb 07 jari 557     /*private void print3DArray(String title, float[][][] array) {
2 26 Feb 07 jari 558         for (int i=0; i<dim_x; i++) {
2 26 Feb 07 jari 559             for (int j=0; j<dim_y; j++) {
2 26 Feb 07 jari 560                 for (int k=0; k<array[i][j].length; k++) {
2 26 Feb 07 jari 561                     System.out.println(title+" array["+i+"]["+j+"]["+k+"]="+array[i][j][k]);
2 26 Feb 07 jari 562                 }
2 26 Feb 07 jari 563             }
2 26 Feb 07 jari 564         }
2 26 Feb 07 jari 565     }*/
2 26 Feb 07 jari 566 }