View Javadoc

1   package baseCode.math;
2   
3   import baseCode.dataStructure.matrix.AbstractNamedDoubleMatrix;
4   import baseCode.dataStructure.matrix.DenseDoubleMatrix2DNamed;
5   import baseCode.dataStructure.matrix.SparseDoubleMatrix2DNamed;
6   import cern.colt.function.DoubleFunction;
7   import cern.colt.list.DoubleArrayList;
8   import cern.colt.matrix.DoubleMatrix1D;
9   import cern.jet.math.Functions;
10  
11  /***
12   * <hr>
13   * <p>
14   * Copyright (c) 2004 Columbia University
15   * 
16   * @author pavlidis
17   * @version $Id: MatrixStats.java,v 1.10 2004/08/17 21:17:40 pavlidis Exp $
18   */
19  public class MatrixStats {
20  
21     /***
22      * @todo this is pretty inefficient - calls new
23      * @param data DenseDoubleMatrix2DNamed
24      * @return DenseDoubleMatrix2DNamed
25      */
26     public static DenseDoubleMatrix2DNamed correlationMatrix(
27           AbstractNamedDoubleMatrix data ) {
28        DenseDoubleMatrix2DNamed result = new DenseDoubleMatrix2DNamed( data
29              .rows(), data.rows() );
30  
31        for ( int i = 0; i < data.rows(); i++ ) {
32           DoubleArrayList irow = new DoubleArrayList( data.getRow( i ) );
33           for ( int j = i + 1; j < data.rows(); j++ ) {
34              DoubleArrayList jrow = new DoubleArrayList( data.getRow( j ) );
35              double c = DescriptiveWithMissing.correlation( irow, jrow );
36              result.setQuick( i, j, c );
37              result.setQuick( j, i, c );
38           }
39        }
40        result.setRowNames( data.getRowNames() );
41        result.setColumnNames( data.getRowNames() );
42  
43        return result;
44     }
45  
46     /***
47      * @param data DenseDoubleMatrix2DNamed
48      * @param threshold only correlations with absolute values above this level are stored.
49      * @return SparseDoubleMatrix2DNamed
50      */
51     public static SparseDoubleMatrix2DNamed correlationMatrix(
52           AbstractNamedDoubleMatrix data, double threshold ) {
53        SparseDoubleMatrix2DNamed result = new SparseDoubleMatrix2DNamed( data
54              .rows(), data.rows() );
55  
56        for ( int i = 0; i < data.rows(); i++ ) {
57           DoubleArrayList irow = new DoubleArrayList( data.getRow( i ) );
58           for ( int j = i + 1; j < data.rows(); j++ ) {
59              DoubleArrayList jrow = new DoubleArrayList( data.getRow( j ) );
60              double c = DescriptiveWithMissing.correlation( irow, jrow );
61              if ( Math.abs( c ) > threshold ) {
62                 result.setQuick( i, j, c );
63                 result.setQuick( j, i, c );
64              }
65           }
66        }
67        result.setRowNames( data.getRowNames() );
68        result.setColumnNames( data.getRowNames() );
69  
70        return result;
71     }
72  
73     /***
74      * Find the minimum of the entire matrix.
75      * 
76      * @param matrix DenseDoubleMatrix2DNamed
77      * @return the smallest value in the matrix
78      */
79     public static double min( AbstractNamedDoubleMatrix matrix ) {
80  
81        int totalRows = matrix.rows();
82        int totalColumns = matrix.columns();
83  
84        double min = Double.MAX_VALUE;
85  
86        for ( int i = 0; i < totalRows; i++ ) {
87           for ( int j = 0; j < totalColumns; j++ ) {
88              double val = matrix.getQuick( i, j );
89              if ( Double.isNaN( val ) ) {
90                 continue;
91              }
92  
93              if ( val < min ) {
94                 min = val;
95              }
96  
97           }
98        }
99        if ( min == Double.MAX_VALUE ) {
100          return Double.NaN;
101       }
102       return min; // might be NaN if all values are missing
103 
104    } // end min
105 
106    /***
107     * Compute the maximum value in the matrix.
108     * 
109     * @param matrix DenseDoubleMatrix2DNamed
110     * @return the largest value in the matrix
111     */
112    public static double max( AbstractNamedDoubleMatrix matrix ) {
113 
114       int totalRows = matrix.rows();
115       int totalColumns = matrix.columns();
116 
117       double max = -Double.MAX_VALUE;
118 
119       for ( int i = 0; i < totalRows; i++ ) {
120          for ( int j = 0; j < totalColumns; j++ ) {
121             double val = matrix.getQuick( i, j );
122             if ( Double.isNaN( val ) ) {
123                continue;
124             }
125 
126             if ( val > max ) {
127                max = val;
128             }
129          }
130       }
131 
132       if ( max == -Double.MAX_VALUE ) {
133          return Double.NaN;
134       }
135 
136       return max; // might be NaN if all values are missing
137 
138    }
139 
140    /***
141     * Normalize a matrix in place to be a transition matrix. Assumes that values operate such that small values like p
142     * values represent closer distances, and the values are probabilities.
143     * <p>
144     * Each point is first transformed via v' = exp(-v/sigma). Then the values for each node's edges are adjusted to sum
145     * to 1.
146     * 
147     * @param matrixToNormalize
148     * @param sigma a scaling factor for the input values.
149     */
150    public static void rbfNormalize(
151          AbstractNamedDoubleMatrix matrixToNormalize, final double sigma ) {
152 
153       // define the function we will use.
154       DoubleFunction f = new DoubleFunction() {
155          public double apply( double value ) {
156             return Math.exp( -value / sigma );
157          }
158       };
159 
160       for ( int j = 0; j < matrixToNormalize.rows(); j++ ) { // do each row in turn ...
161 
162          DoubleMatrix1D row = matrixToNormalize.viewRow( j );
163          row.assign( f );
164          double sum = row.zSum();
165          row.assign( Functions.div( sum ) );
166 
167       }
168    }
169 
170    /***
171     * Normalize a count matrix in place to be a transition matrix. Assumes that the values are defined as "bigger is better"
172     * 
173     * @param matrixToNormalize
174     * @param sigma
175     */
176    public static void countsNormalize (
177          AbstractNamedDoubleMatrix matrixToNormalize, final double sigma ) {
178 
179       final double min = MatrixStats.min( matrixToNormalize );
180       DoubleFunction f = new DoubleFunction() {
181          public double apply( double value ) {
182             return value - min + 1;
183          }
184       };
185 
186       for ( int j = 0; j < matrixToNormalize.rows(); j++ ) { // do each row in turn ...
187          DoubleMatrix1D row = matrixToNormalize.viewRow( j );
188          row.assign( f );
189          double sum = row.zSum();
190          row.assign( Functions.div( sum ) );
191       }
192    }
193 
194 }