tqrfunc.cpp - numeric - C++ library with numerical algorithms | |
git clone git://src.adamsgaard.dk/numeric | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
tqrfunc.cpp (2033B) | |
--- | |
1 #include <iostream> | |
2 #include <armadillo> | |
3 #include "header.h" | |
4 #include "qrfunc.h" | |
5 | |
6 // QR decomposition constructor | |
7 QR::QR(arma::mat &A) | |
8 : n(A.n_cols), | |
9 A(A), | |
10 Q(A) | |
11 { | |
12 // Initialize output structures | |
13 R = arma::zeros<arma::mat> (n,n); | |
14 | |
15 // Perform QR decomposition straight away | |
16 decomp(); | |
17 } | |
18 | |
19 // Class deconstructor (equivalent to compiler destructor) | |
20 QR::~QR() { }; | |
21 | |
22 // Return system size | |
23 Lengthtype QR::size() | |
24 { | |
25 return n; | |
26 } | |
27 | |
28 // QR decomposition function of Armadillo matrix. | |
29 // Returns right matrix R, and modifies A into Q. | |
30 // Uses Gram-Schmidt orthogonalization | |
31 void QR::decomp() | |
32 { | |
33 Floattype r, s; | |
34 Lengthtype j; | |
35 for (Lengthtype i=0; i<n; ++i) { | |
36 r = dot(Q.col(i), Q.col(i)); | |
37 R(i,i) = sqrt(r); | |
38 Q.col(i) /= sqrt(r); // Normalization | |
39 for (j=i+1; j<n; ++j) { | |
40 s = dot(Q.col(i), Q.col(j)); | |
41 Q.col(j) -= s*Q.col(i); // Orthogonalization | |
42 R(i,j) = s; | |
43 } | |
44 } | |
45 } | |
46 | |
47 // Solve the square system of linear equations with back | |
48 // substitution. T is an upper triangular matrix. | |
49 arma::vec QR::backsub(arma::vec &b) | |
50 { | |
51 Floattype tmpsum; | |
52 arma::vec x = Q.t() * b; | |
53 for (Lengthtype i=n-1; i>=0; --i) { | |
54 tmpsum = 0.0f; | |
55 for (Lengthtype k=i+1; k<n; ++k) | |
56 tmpsum += R(i,k) * x(k); | |
57 | |
58 x(i) = 1.0f/R(i,i) * (x(i) - tmpsum); | |
59 } | |
60 return x; | |
61 } | |
62 | |
63 // Calculate the (absolute value of the) determinant of | |
64 // matrix A given the Q and R components. | |
65 // det(A) = det(Q) * det(R), |det(Q) = 1| | |
66 // => |det(A)| = |det(R)| | |
67 Floattype QR::det() | |
68 { | |
69 Floattype determinant = 1.0f; | |
70 for (Lengthtype i=0; i<n; ++i) | |
71 determinant *= R(i,i); | |
72 return fabs(determinant); | |
73 } | |
74 | |
75 // Calculate the inverse of matrix A given the Q and R | |
76 // components. | |
77 arma::mat QR::inverse() | |
78 { | |
79 arma::mat inv = arma::zeros<arma::mat> (n, n); | |
80 // In vector z, all elements are equal to 0, except z(i) = 1 | |
81 arma::vec z = arma::zeros<arma::mat> (n); | |
82 | |
83 for (Lengthtype i=0; i<n; ++i) { | |
84 z(i) = 1.0f; // Element i changed to 1 | |
85 inv.col(i) = backsub(z); | |
86 z(i) = 0.0f; // Element i changed back to 0 | |
87 } | |
88 | |
89 return inv; | |
90 } |