1 package baseCode.math.distribution;
2
3 import cern.colt.matrix.DoubleMatrix2D;
4 import cern.colt.matrix.impl.DenseDoubleMatrix2D;
5 import cern.colt.matrix.linalg.Algebra;
6 import cern.colt.matrix.linalg.CholeskyDecomposition;
7 import cern.jet.random.Gamma;
8 import cern.jet.random.Normal;
9 import cern.jet.random.engine.RandomEngine;
10
11 /***
12 * Wishart distribution, used to simulate covariance matrices.
13 * <p>
14 * Based on method in Odell and Feiveson JASA 1966 p.199-203
15 * <p>
16 * The interface is modeled after ContinuousDistribution from colt, which unfortunately is designed only for univariate
17 * distributions.
18 * <hr>
19 * <p>
20 * Copyright (c) 2004 Columbia University
21 *
22 * @author pavlidis
23 * @version $Id: Wishart.java,v 1.1 2005/01/16 03:51:11 pavlidis Exp $
24 */
25 public class Wishart {
26
27 private Gamma rgamma;
28 int s;
29 double df;
30 DoubleMatrix2D cov;
31 DoubleMatrix2D chol;
32 private DoubleMatrix2D mat;
33 private Normal rnorm;
34 private Algebra a = new Algebra();
35 private RandomEngine r;
36
37 /***
38 * @param s
39 * @param df
40 * @param covariance
41 * @param randomGenerator
42 */
43 public Wishart( double df, DoubleMatrix2D covariance, RandomEngine randomGenerator ) {
44 this.s = covariance.columns();
45 if ( s != covariance.rows() ) throw new IllegalArgumentException( "Covariance matrix must be square" );
46 if ( df <= s - 1 ) throw new IllegalArgumentException( "df must be greater than s - 1" );
47 if ( randomGenerator == null ) throw new IllegalArgumentException( "Null random number generator" );
48
49 this.r = randomGenerator;
50 this.df = df;
51 this.cov = covariance;
52
53 rgamma = new Gamma( 1, 1, r );
54 rnorm = new Normal( s * ( s - 1.0 ) / 2.0, 1.0, r );
55
56 CholeskyDecomposition c = new CholeskyDecomposition( covariance );
57 chol = a.transpose( c.getL() );
58 mat = new DenseDoubleMatrix2D( this.s, this.s );
59 }
60
61 /***
62 * Based on R code from Francesca Dominici, <a
63 * href="http://www.biostat.jhsph.edu/~fdominic/teaching/BM/bm.html">http://www.biostat.jhsph.edu/~fdominic/teaching/BM/bm.html
64 * </a>
65 * <p>
66 * Returns
67 *
68 * <pre>
69 *
70 *
71 *
72 *
73 *
74 *
75 * w=(RU)'RU
76 *
77 *
78 *
79 *
80 *
81 *
82 * </pre>
83 *
84 * where
85 *
86 * <pre>
87 *
88 *
89 *
90 *
91 *
92 *
93 *
94 *
95 * Cov=U'U (U is upper triang)
96 *
97 *
98 *
99 * </pre>
100 *
101 * and where upper-tri R is
102 *
103 * <pre>
104 *
105 *
106 * R_ij˜N(0,1), i<j ; (R_ii)ˆ2˜Chisq(nu-s+i)
107 *
108 *
109 *
110 * </pre>
111 *
112 * @param s
113 * @param nu
114 * @param covariance
115 * @return
116 */
117 public DoubleMatrix2D nextDoubleMatrix() {
118 mat.assign( 0.0 );
119
120
121 for ( int i = 0; i < s; i++ ) {
122 mat.setQuick( i, i, Math.sqrt( 2 * rgamma.nextDouble( s, ( df + 1.0 - i ) / 2.0 ) ) );
123 for ( int j = i + 1; j < s; j++ ) {
124 mat.setQuick( i, j, rnorm.nextDouble() );
125 }
126 }
127
128 mat = a.mult( mat, chol );
129 return a.mult( a.transpose( mat ).copy(), mat );
130
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 }