Heidelberg Educational Numerics Library Version 0.27 (from 15 March 2021)
qrhousholder.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2/*
3 * File: qrhousholder
4 * Author: Ahmad Fadl <abohmaid@windowslive.com>
5 *
6 * Created on August 25, 2020
7 */
8
9#ifndef HDNUM_QRHOUSHOLDER_HH
10#define HDNUM_QRHOUSHOLDER_HH
11#include <cmath>
12#include <cstdlib>
13#include <fstream>
14#include <iomanip>
15#include <iostream>
16#include <sstream>
17#include <string>
18
19#include "densematrix.hh"
20#include "vector.hh"
24namespace hdnum {
25template <class REAL>
26DenseMatrix<REAL> creat_I_matrix(size_t n) {
27 DenseMatrix<REAL> res(n, n, 0);
28 for (size_t i = 0; i < n; i++) {
29 res(i, i) = 1;
30 }
31 return res;
32}
33
36template <typename REAL>
37size_t sgn(REAL val) {
38 return (REAL(0) < val) - (val < REAL(0));
39}
49template <class REAL>
51 auto m = A.rowsize();
52 auto n = A.colsize();
53 for (size_t j = 0; j < n; j++) {
54 REAL s = 0;
55 for (size_t i = j; i < m; i++) {
56 s = s + pow(A(i, j), 2);
57 }
58 s = sqrt(s);
59 v[j] = (-1.0) * sgn(A(j, j)) * s;
60 REAL fak = sqrt(s * (s + std::abs(A(j, j))));
61 A(j, j) = A(j, j) - v[j];
62 for (size_t k = j; k < m; k++) {
63 A(k, j) = A(k, j) / fak;
64 }
65 for (size_t i = j + 1; i < n; i++) {
66 s = 0;
67 for (size_t k = j; k < m; k++) {
68 s = s + (A(k, j) * A(k, i));
69 }
70 for (size_t k = j; k < m; k++) {
71 A(k, i) = A(k, i) - (A(k, j) * s);
72 }
73 }
74 // normalize the vi vectors again
75 for (size_t i = m; i >= 0; i--) {
76 A(i, j) = A(i, j) * fak;
77 if (i == j) {
78 break;
79 }
80 }
81 }
82}
93template <class REAL>
96 bool show_Hi = false) {
97 auto m = A.rowsize();
98 auto n = A.colsize();
99 auto I = creat_I_matrix<REAL>(std::max(m, n));
100
101 DenseMatrix<REAL> Q(m, m, 0);
102 for (size_t j = 0; j < n; j++) {
103 REAL s = 0;
104 for (size_t i = j; i < m; i++) {
105 s = s + pow(A(i, j), 2);
106 }
107 s = sqrt(s);
108 v[j] = (-1.0) * sgn(A(j, j)) * s;
109 REAL fak = sqrt(s * (s + std::abs(A(j, j))));
110 A(j, j) = A(j, j) - v[j];
111 for (size_t k = j; k < m; k++) {
112 A(k, j) = A(k, j) / fak;
113 }
114 for (size_t i = j + 1; i < n; i++) {
115 s = 0;
116 for (size_t k = j; k < m; k++) {
117 s = s + (A(k, j) * A(k, i));
118 }
119 for (size_t k = j; k < m; k++) {
120 A(k, i) = A(k, i) - (A(k, j) * s);
121 }
122 }
123 // normalize the vi vectors again
124 for (size_t i = m; i >= 0; i--) {
125 A(i, j) = A(i, j) * fak;
126 if (i == j) {
127 break;
128 }
129 }
130 }
131 // create qi and multiply them
132 if (m >= n) {
133 for (size_t j = 0; j < n; j++) {
134 DenseMatrix<REAL> TempQ(m, m, 0.0);
135 DenseMatrix<REAL> v1(m, 1, 0.0);
136 DenseMatrix<REAL> v1t(1, m, 0.0);
138 for (size_t i = 0; i < m; i++) {
139 if (i < j) {
140 v1(i, 0) = 0;
141
142 v__i[i] = 0;
143 continue;
144 }
145 v1(i, 0) = A(i, j);
146
147 v__i[i] = A(i, j);
148 }
149 v1t = v1.transpose();
150
151 TempQ = (v1 * v1t);
152
153 TempQ *= (-2.0);
154
155 TempQ /= v__i.two_norm_2();
156
157 TempQ += I;
158 if (show_Hi) {
159 std::cout << "H[" << j + 1 << "]" << TempQ;
160 }
161 if (j == 0) {
162 Q = TempQ;
163 }
164 if (j > 0) {
165 Q = Q * TempQ;
166 }
167 }
168 }
169 if (n > m) {
170 for (size_t j = 0; j < m; j++) {
171 DenseMatrix<REAL> TempQ(m, m, 0.0);
172 DenseMatrix<REAL> v1(m, 1, 0.0);
173 DenseMatrix<REAL> v1t(1, m, 0.0);
175 for (size_t i = 0; i < m; i++) {
176 if (i < j) {
177 v1(i, 0) = 0;
178
179 v__i[i] = 0;
180 continue;
181 }
182 v1(i, 0) = A(i, j);
183
184 v__i[i] = A(i, j);
185 }
186 v1t = v1.transpose();
187
188 TempQ = (v1 * v1t);
189
190 TempQ *= (-2.0);
191
192 TempQ /= v__i.two_norm_2();
193
194 TempQ += I;
195 if (show_Hi) {
196 std::cout << "H[" << j + 1 << "]" << TempQ;
197 }
198 if (j == 0) {
199 Q = TempQ;
200 }
201 if (j > 0) {
202 Q = Q * TempQ;
203 }
204 }
205 }
206 return Q;
207}
208} // namespace hdnum
209#endif
Class with mathematical matrix operations.
Definition densematrix.hh:33
size_t rowsize() const
get number of rows of the matrix
Definition densematrix.hh:136
size_t colsize() const
get number of columns of the matrix
Definition densematrix.hh:153
DenseMatrix transpose() const
Transposition.
Definition densematrix.hh:350
size_t sgn(REAL val)
Function that return the sign of a number.
Definition qrhousholder.hh:37
DenseMatrix< REAL > qrhousholderexplizitQ(DenseMatrix< REAL > &A, hdnum::Vector< REAL > &v, bool show_Hi=false)
Funktion that calculate the QR decoposition in place and return Q the elements of A will be replaced ...
Definition qrhousholder.hh:94
void qrhousholder(DenseMatrix< REAL > &A, hdnum::Vector< REAL > &v)
Funktion that calculate the QR decoposition in place the elements of A will be replaced with the elem...
Definition qrhousholder.hh:50