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 }