source: src/main/java/agents/Jama/CholeskyDecomposition.java@ 346

Last change on this file since 346 was 1, checked in by Wouter Pasman, 6 years ago

Initial import : Genius 9.0.0

File size: 5.5 KB
RevLine 
[1]1package agents.Jama;
2
3 /** Cholesky Decomposition.
4 <P>
5 For a symmetric, positive definite matrix A, the Cholesky decomposition
6 is an lower triangular matrix L so that A = L*L'.
7 <P>
8 If the matrix is not symmetric or positive definite, the constructor
9 returns a partial decomposition and sets an internal flag that may
10 be queried by the isSPD() method.
11 */
12
13public class CholeskyDecomposition implements java.io.Serializable {
14
15/* ------------------------
16 Class variables
17 * ------------------------ */
18
19 /** Array for internal storage of decomposition.
20 @serial internal array storage.
21 */
22 private double[][] L;
23
24 /** Row and column dimension (square matrix).
25 @serial matrix dimension.
26 */
27 private int n;
28
29 /** Symmetric and positive definite flag.
30 @serial is symmetric and positive definite flag.
31 */
32 private boolean isspd;
33
34/* ------------------------
35 Constructor
36 * ------------------------ */
37
38 /** Cholesky algorithm for symmetric and positive definite matrix.
39 Structure to access L and isspd flag.
40 @param Arg Square, symmetric matrix.
41 */
42
43 public CholeskyDecomposition (Matrix Arg) {
44
45
46 // Initialize.
47 double[][] A = Arg.getArray();
48 n = Arg.getRowDimension();
49 L = new double[n][n];
50 isspd = (Arg.getColumnDimension() == n);
51 // Main loop.
52 for (int j = 0; j < n; j++) {
53 double[] Lrowj = L[j];
54 double d = 0.0;
55 for (int k = 0; k < j; k++) {
56 double[] Lrowk = L[k];
57 double s = 0.0;
58 for (int i = 0; i < k; i++) {
59 s += Lrowk[i]*Lrowj[i];
60 }
61 Lrowj[k] = s = (A[j][k] - s)/L[k][k];
62 d = d + s*s;
63 isspd = isspd & (A[k][j] == A[j][k]);
64 }
65 d = A[j][j] - d;
66 isspd = isspd & (d > 0.0);
67 L[j][j] = Math.sqrt(Math.max(d,0.0));
68 for (int k = j+1; k < n; k++) {
69 L[j][k] = 0.0;
70 }
71 }
72 }
73
74/* ------------------------
75 Temporary, experimental code.
76 * ------------------------ *\
77
78 \** Right Triangular Cholesky Decomposition.
79 <P>
80 For a symmetric, positive definite matrix A, the Right Cholesky
81 decomposition is an upper triangular matrix R so that A = R'*R.
82 This constructor computes R with the Fortran inspired column oriented
83 algorithm used in LINPACK and MATLAB. In Java, we suspect a row oriented,
84 lower triangular decomposition is faster. We have temporarily included
85 this constructor here until timing experiments confirm this suspicion.
86 *\
87
88 \** Array for internal storage of right triangular decomposition. **\
89 private transient double[][] R;
90
91 \** Cholesky algorithm for symmetric and positive definite matrix.
92 @param A Square, symmetric matrix.
93 @param rightflag Actual value ignored.
94 @return Structure to access R and isspd flag.
95 *\
96
97 public CholeskyDecomposition (Matrix Arg, int rightflag) {
98 // Initialize.
99 double[][] A = Arg.getArray();
100 n = Arg.getColumnDimension();
101 R = new double[n][n];
102 isspd = (Arg.getColumnDimension() == n);
103 // Main loop.
104 for (int j = 0; j < n; j++) {
105 double d = 0.0;
106 for (int k = 0; k < j; k++) {
107 double s = A[k][j];
108 for (int i = 0; i < k; i++) {
109 s = s - R[i][k]*R[i][j];
110 }
111 R[k][j] = s = s/R[k][k];
112 d = d + s*s;
113 isspd = isspd & (A[k][j] == A[j][k]);
114 }
115 d = A[j][j] - d;
116 isspd = isspd & (d > 0.0);
117 R[j][j] = Math.sqrt(Math.max(d,0.0));
118 for (int k = j+1; k < n; k++) {
119 R[k][j] = 0.0;
120 }
121 }
122 }
123
124 \** Return upper triangular factor.
125 @return R
126 *\
127
128 public Matrix getR () {
129 return new Matrix(R,n,n);
130 }
131
132\* ------------------------
133 End of temporary code.
134 * ------------------------ */
135
136/* ------------------------
137 Public Methods
138 * ------------------------ */
139
140 /** Is the matrix symmetric and positive definite?
141 @return true if A is symmetric and positive definite.
142 */
143
144 public boolean isSPD () {
145 return isspd;
146 }
147
148 /** Return triangular factor.
149 @return L
150 */
151
152 public Matrix getL () {
153 return new Matrix(L,n,n);
154 }
155
156 /** Solve A*X = B
157 @param B A Matrix with as many rows as A and any number of columns.
158 @return X so that L*L'*X = B
159 @exception IllegalArgumentException Matrix row dimensions must agree.
160 @exception RuntimeException Matrix is not symmetric positive definite.
161 */
162
163 public Matrix solve (Matrix B) {
164 if (B.getRowDimension() != n) {
165 throw new IllegalArgumentException("Matrix row dimensions must agree.");
166 }
167 if (!isspd) {
168 throw new RuntimeException("Matrix is not symmetric positive definite.");
169 }
170
171 // Copy right hand side.
172 double[][] X = B.getArrayCopy();
173 int nx = B.getColumnDimension();
174
175 // Solve L*Y = B;
176 for (int k = 0; k < n; k++) {
177 for (int j = 0; j < nx; j++) {
178 for (int i = 0; i < k ; i++) {
179 X[k][j] -= X[i][j]*L[k][i];
180 }
181 X[k][j] /= L[k][k];
182 }
183 }
184
185 // Solve L'*X = Y;
186 for (int k = n-1; k >= 0; k--) {
187 for (int j = 0; j < nx; j++) {
188 for (int i = k+1; i < n ; i++) {
189 X[k][j] -= X[i][j]*L[i][k];
190 }
191 X[k][j] /= L[k][k];
192 }
193 }
194
195
196 return new Matrix(X,n,nx);
197 }
198 private static final long serialVersionUID = 1;
199
200}
201
Note: See TracBrowser for help on using the repository browser.