annotate src/samer/models/GaussianStats.java @ 0:bf79fb79ee13

Initial Mercurial check in.
author samer
date Tue, 17 Jan 2012 17:50:20 +0000
parents
children
rev   line source
samer@0 1 /*
samer@0 2 * Copyright (c) 2000, Samer Abdallah, King's College London.
samer@0 3 * All rights reserved.
samer@0 4 *
samer@0 5 * This software is provided AS iS and WITHOUT ANY WARRANTY;
samer@0 6 * without even the implied warranty of MERCHANTABILITY or
samer@0 7 * FITNESS FOR A PARTICULAR PURPOSE.
samer@0 8 */
samer@0 9
samer@0 10 package samer.models;
samer@0 11 import samer.core.*;
samer@0 12 import samer.maths.*;
samer@0 13 import samer.tools.*;
samer@0 14 import java.util.*;
samer@0 15
samer@0 16 /**
samer@0 17 Collect statistics about a vector: accumulates
samer@0 18 sums and sums of products, then computes mean
samer@0 19 and covariance.
samer@0 20
samer@0 21 This is NOT a model! Computing energies and probabilities
samer@0 22 directly from the first and second moments is horrible, since
samer@0 23 you need the inverse of the covariance matrix. You could,
samer@0 24 however, use this to train a Gaussian model.
samer@0 25 */
samer@0 26
samer@0 27 public class GaussianStats extends NullTask
samer@0 28 {
samer@0 29 VVector vector;
samer@0 30 VVector sumx;
samer@0 31 Matrix sumxx;
samer@0 32 int n, count;
samer@0 33 double [] _sumx, x;
samer@0 34 double [][] _sumxx;
samer@0 35 double [] sig;
samer@0 36
samer@0 37 public GaussianStats(VVector vec) throws Exception
samer@0 38 {
samer@0 39 n=vec.size();
samer@0 40 sumx = new VVector("t1",n); // first moment: sum
samer@0 41 sumxx = new Matrix("t2",n,n); // second moment: sum products
samer@0 42
samer@0 43 _sumx=sumx.array();
samer@0 44 _sumxx=sumxx.getArray();
samer@0 45 x=vec.array();
samer@0 46 vector=vec;
samer@0 47 sig= new double[n];
samer@0 48
samer@0 49 }
samer@0 50
samer@0 51 public void dispose() {
samer@0 52 sumx.dispose();
samer@0 53 sumxx.dispose();
samer@0 54 }
samer@0 55
samer@0 56 public void getMean(VVector mu) { getMean(mu.array()); mu.changed(); }
samer@0 57 public void getMean(double [] mu) { Mathx.mul(mu, _sumx, 1.0/count); }
samer@0 58 public void getCovariance(Matrix C) {
samer@0 59 // compute mean products
samer@0 60 C.assign(sumxx);
samer@0 61 C.timesEquals(1.0/count);
samer@0 62
samer@0 63 // subtract square mean from mean square
samer@0 64 double [][] _C=C.getArray();
samer@0 65
samer@0 66 for (int i=0; i<n; i++) {
samer@0 67 double tmp=_sumx[i]/count; // diagonal
samer@0 68 for (int j=0; j<i; j++) { // off diagonal
samer@0 69 _C[i][j] -= tmp*(_sumx[j]/count);
samer@0 70 _C[j][i] = _C[i][j];
samer@0 71 }
samer@0 72 _C[i][i] -= tmp*tmp;
samer@0 73 }
samer@0 74 C.changed();
samer@0 75 }
samer@0 76
samer@0 77 public void getCorrelation(Matrix R) {
samer@0 78 // compute mean products
samer@0 79 R.assign(sumxx);
samer@0 80 R.timesEquals(1.0/count);
samer@0 81
samer@0 82 double [][] _R=R.getArray();
samer@0 83
samer@0 84 // first get std devs and put 1s down diagonal
samer@0 85 for (int i=0; i<n; i++) {
samer@0 86 double tmp=_sumx[i]/count; // diagonal
samer@0 87 sig[i] = Math.sqrt(_R[i][i] - tmp*tmp);
samer@0 88 _R[i][i]=1;
samer@0 89 }
samer@0 90
samer@0 91 for (int i=0; i<n; i++) {
samer@0 92 double tmp=_sumx[i]/count;
samer@0 93 for (int j=0; j<i; j++) { // off diagonal
samer@0 94 _R[i][j] -= tmp*(_sumx[j]/count);
samer@0 95 _R[i][j] /= sig[i]*sig[j];
samer@0 96 _R[j][i] = _R[i][j];
samer@0 97 }
samer@0 98 }
samer@0 99 R.changed();
samer@0 100 }
samer@0 101
samer@0 102 public void reset() {
samer@0 103 Mathx.zero(_sumx);
samer@0 104 sumxx.zero(); count=0;
samer@0 105 }
samer@0 106
samer@0 107 public void starting() {}
samer@0 108 public void stopping() {}
samer@0 109 public void run()
samer@0 110 {
samer@0 111 Mathx.add(_sumx,x);
samer@0 112
samer@0 113 for (int i=0; i<n; i++) {
samer@0 114 double [] a=_sumxx[i];
samer@0 115 double k=x[i];
samer@0 116 for (int j=0; j<=i; j++) {
samer@0 117 a[j] += k*x[j];
samer@0 118 }
samer@0 119 }
samer@0 120 sumx.changed();
samer@0 121 sumxx.changed();
samer@0 122 count++;
samer@0 123 }
samer@0 124 }
samer@0 125