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;
103
104 }
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;
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
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++ ) {
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++ ) {
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 }