-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqr_fact_househ.java
102 lines (82 loc) · 2.93 KB
/
qr_fact_househ.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import Jama.Matrix;
public class qr_fact_househ {
public Matrix matrix;
public Matrix vect;
public qr_fact_househ(Matrix matrix) {
//creates new vector of zeros
this.vect = new Matrix(1, matrix.getColumnDimension());
this.matrix = matrix.copy();
//loops through the columns
for (int j = 0; j < this.matrix.getColumnDimension(); j++) {
//loop to find the norm
double norm = 0;
for (int i = j; i < this.matrix.getRowDimension(); i++) {
norm += Math.pow(this.matrix.get(i, j), 2);
}
norm = Math.sqrt(norm);
//makes sure the sign of the norm is correct
int sign = 1;
if (this.matrix.get(j, j) < 0) {
sign = -1;
}
double v1 = this.matrix.get(j, j) + sign * norm;
double scalar = 1;
for (int i = j + 1; i < this.matrix.getRowDimension(); i++) {
this.matrix.set(i, j, (this.matrix.get(i, j) / v1));
scalar += Math.pow(this.matrix.get(i, j), 2);
}
vect.set(0, j, (2 / scalar));
//makes a new vector of zeros
Matrix w = new Matrix(1, this.matrix.getColumnDimension());
//grabs the significant vector for each new householder matrix
for (int i = j; i < this.matrix.getColumnDimension(); i++) {
w.set(0, i, this.matrix.get(j, i));
for (int k = j + 1; k < this.matrix.getRowDimension(); k++) {
if (i == j) {
w.set(0, i, w.get(0, i) + this.matrix.get(k, j) * this.matrix.get(k, i) * v1);
} else {
w.set(0, i, w.get(0, i) + this.matrix.get(k, j) * this.matrix.get(k, i));
}
}
//sets the final matrix
this.matrix.set(j, i, this.matrix.get(j, i) - vect.get(0, j) * w.get(0, i));
for (int k = j + 1; k < this.matrix.getRowDimension(); k++) {
if (i > j) {
this.matrix.set(k, i, this.matrix.get(k, i) - vect.get(0, j) * this.matrix.get(k, j) * w.get(0, i));
}
}
}
}
}
//code to return Q from the QR factorization
public Matrix getQ() {
int m = Math.max(matrix.getColumnDimension(), matrix.getRowDimension());
Matrix q = new Matrix(m, m);
for (int i = 0; i < Math.min(q.getRowDimension(), q.getColumnDimension()); i++) {
q.set(i, i, 1);
}
for (int k = matrix.getColumnDimension() - 1; k >= 0; k--) {
for ( int j = k; j < q.getColumnDimension(); j++) {
double w = q.get(k, j);
for (int i = k + 1; i < q.getRowDimension(); i++) {
w += matrix.get(i, k) * q.get(i, j);
}
q.set(k, j, q.get(k, j) - vect.get(0, k) * w);
for (int i = k + 1; i < q.getRowDimension(); i++) {
q.set(i, j, q.get(i, j) - vect.get(0, k) * matrix.get(i, k) * w);
}
}
}
return q.getMatrix(0, q.getRowDimension() - 1, 0, 2);
}
//returns R from the QR factorization
public Matrix getR() {
Matrix r = matrix.copy();
for (int i = 0; i < r.getRowDimension(); i++) {
for (int j = 0; j < i && j < r.getColumnDimension(); j++) {
r.set(i, j, 0);
}
}
return r.getMatrix(0, 2, 0, 2);
}
}