1 package de.desy.acop.video.analysis;
2
3
4
5
6
7
8
9
10
11
12
13 public class LUDecomposition {
14
15
16 private double[][] LU;
17
18 private int m;
19
20 private int pivsign;
21
22 private int[] pivot;
23
24
25
26
27
28
29
30
31 public LUDecomposition(double[][] A) throws MathException {
32 LU = getMatrixCopy(A);
33 m = A.length;
34 pivot = new int[m];
35 for (int i = 0; i < m; i++) {
36 pivot[i] = i;
37 }
38 pivsign = 1;
39 decompose();
40 }
41
42
43
44
45
46
47 private void decompose() throws MathException {
48 double[] LUrowi;
49 double[] LUcolj = new double[m];
50
51 for (int j = 0; j < m; j++) {
52 for (int i = 0; i < m; i++) {
53 LUcolj[i] = LU[i][j];
54 }
55 for (int i = 0; i < m; i++) {
56 LUrowi = LU[i];
57 int kmax = Math.min(i,j);
58 double s = 0.0;
59 for (int k = 0; k < kmax; k++) {
60 s += LUrowi[k] * LUcolj[k];
61 }
62 LUrowi[j] = LUcolj[i] -= s;
63 }
64 int p = j;
65 for (int i = j + 1; i < m; i++) {
66 if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {
67 p = i;
68 }
69 }
70 if (p != j) {
71 for (int k = 0; k < m; k++) {
72 double t = LU[p][k];
73 LU[p][k] = LU[j][k];
74 LU[j][k] = t;
75 }
76 int k = pivot[p];
77 pivot[p] = pivot[j];
78 pivot[j] = k;
79 pivsign = -pivsign;
80 }
81
82 if (j < m & LU[j][j] != 0.0) {
83 for (int i = j + 1; i < m; i++) {
84 LU[i][j] /= LU[j][j];
85 }
86 }
87 }
88 if (isSingular()) {
89 throw new MathException("Matrix is singular.");
90 }
91 }
92
93
94
95
96
97
98 public boolean isSingular() {
99 for (int j = 0; j < m; j++) {
100 if (LU[j][j] == 0) return true;
101 }
102 return false;
103 }
104
105
106
107
108
109
110
111
112 public double[] solve(double[] b) throws MathException {
113 if (b.length != m) {
114 throw new MathException("Vector dimension must equal LU dimension (" + m +").");
115 }
116
117 double[] x = new double[pivot.length];
118 for (int i = 0; i < x.length; i++) {
119 x[i] = b[pivot[i]];
120 }
121
122
123 for (int k = 0; k < m; k++) {
124 for (int i = k + 1; i < m; i++) {
125 x[i] -= x[k] * LU[i][k];
126 }
127 }
128
129 for (int k = m - 1; k >= 0; k--) {
130 x[k] /= LU[k][k];
131 for (int i = 0; i < k; i++) {
132 x[i] -= x[k] * LU[i][k];
133 }
134 }
135 return x;
136 }
137
138
139
140
141
142
143 private double[][] getMatrixCopy(double[][] A) {
144 int m = A.length;
145 double[][] C = new double[m][m];
146 for (int i = 0; i < m; i++) {
147 for (int j = 0; j < m; j++) {
148 C[i][j] = A[i][j];
149 }
150 }
151 return C;
152 }
153 }