TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
qr_decompose.h
Go to the documentation of this file.
1
8
9
#ifndef NUMERICAL_METHODS_QR_DECOMPOSE_H_
10
#define NUMERICAL_METHODS_QR_DECOMPOSE_H_
11
12
#include <cmath>
13
#include <cstdlib>
14
#include <iomanip>
15
#include <iostream>
16
#include <limits>
17
#include <numeric>
18
#include <valarray>
19
#ifdef _OPENMP
20
#include <omp.h>
21
#endif
22
28
namespace
qr_algorithm
{
32
template
<
typename
T>
33
std::ostream &
operator<<
(std::ostream &out,
34
std::valarray<std::valarray<T>>
const
&v) {
35
const
int
width = 12;
36
const
char
separator =
' '
;
37
38
out.precision(4);
39
for
(
size_t
row = 0; row < v.size(); row++) {
40
for
(
size_t
col = 0; col < v[row].size(); col++)
41
out << std::right << std::setw(width) << std::setfill(separator)
42
<< v[row][col];
43
out << std::endl;
44
}
45
46
return
out;
47
}
48
52
template
<
typename
T>
53
std::ostream &
operator<<
(std::ostream &out, std::valarray<T>
const
&v) {
54
const
int
width = 10;
55
const
char
separator =
' '
;
56
57
out.precision(4);
58
for
(
size_t
row = 0; row < v.size(); row++) {
59
out << std::right << std::setw(width) << std::setfill(separator)
60
<< v[row];
61
}
62
63
return
out;
64
}
65
75
template
<
typename
T>
76
inline
double
vector_dot
(
const
std::valarray<T> &a,
const
std::valarray<T> &b) {
77
return
(a * b).sum();
78
// could also use following
79
// return std::inner_product(std::begin(a), std::end(a), std::begin(b),
80
// 0.f);
81
}
82
91
template
<
typename
T>
92
inline
double
vector_mag
(
const
std::valarray<T> &a) {
93
double
dot =
vector_dot
(a, a);
94
return
std::sqrt(dot);
95
}
96
103
template
<
typename
T>
104
std::valarray<T>
vector_proj
(
const
std::valarray<T> &a,
105
const
std::valarray<T> &b) {
106
double
num =
vector_dot
(a, b);
107
double
deno =
vector_dot
(b, b);
108
110
if
(deno <= std::numeric_limits<double>::epsilon()) {
111
std::cerr <<
"["
<< __func__ <<
"] Possible division by zero\n"
;
112
return
a;
// return vector a back
113
}
114
115
double
scalar = num / deno;
116
117
return
b * scalar;
118
}
119
145
template
<
typename
T>
146
void
qr_decompose
(
147
const
std::valarray<std::valarray<T>> &A,
148
std::valarray<std::valarray<T>> *Q,
149
std::valarray<std::valarray<T>> *R
150
) {
151
std::size_t ROWS = A.size();
// number of rows of A
152
std::size_t COLUMNS = A[0].size();
// number of columns of A
153
std::valarray<T> col_vector(ROWS);
154
std::valarray<T> col_vector2(ROWS);
155
std::valarray<T> tmp_vector(ROWS);
156
157
for
(
int
i = 0; i < COLUMNS; i++) {
158
/* for each column => R is a square matrix of NxN */
159
int
j;
160
R[0][i] = 0.;
/* make R upper triangular */
161
162
/* get corresponding Q vector */
163
#ifdef _OPENMP
164
// parallelize on threads
165
#pragma omp for
166
#endif
167
for
(j = 0; j < ROWS; j++) {
168
tmp_vector[j] = A[j][i];
/* accumulator for uk */
169
col_vector[j] = A[j][i];
170
}
171
for
(j = 0; j < i; j++) {
172
for
(
int
k = 0; k < ROWS; k++) {
173
col_vector2[k] = Q[0][k][j];
174
}
175
col_vector2 =
vector_proj
(col_vector, col_vector2);
176
tmp_vector -= col_vector2;
177
}
178
179
double
mag =
vector_mag
(tmp_vector);
180
181
#ifdef _OPENMP
182
// parallelize on threads
183
#pragma omp for
184
#endif
185
for
(j = 0; j < ROWS; j++) Q[0][j][i] = tmp_vector[j] / mag;
186
187
/* compute upper triangular values of R */
188
#ifdef _OPENMP
189
// parallelize on threads
190
#pragma omp for
191
#endif
192
for
(
int
kk = 0; kk < ROWS; kk++) {
193
col_vector[kk] = Q[0][kk][i];
194
}
195
196
#ifdef _OPENMP
197
// parallelize on threads
198
#pragma omp for
199
#endif
200
for
(
int
k = i; k < COLUMNS; k++) {
201
for
(
int
kk = 0; kk < ROWS; kk++) {
202
col_vector2[kk] = A[kk][k];
203
}
204
R[0][i][k] = (col_vector * col_vector2).sum();
205
}
206
}
207
}
208
}
// namespace qr_algorithm
209
210
#endif
// NUMERICAL_METHODS_QR_DECOMPOSE_H_
qr_algorithm
Functions to compute QR decomposition of any rectangular matrix.
qr_algorithm::vector_proj
std::valarray< T > vector_proj(const std::valarray< T > &a, const std::valarray< T > &b)
Definition
qr_decompose.h:104
qr_algorithm::qr_decompose
void qr_decompose(const std::valarray< std::valarray< T > > &A, std::valarray< std::valarray< T > > *Q, std::valarray< std::valarray< T > > *R)
Definition
qr_decompose.h:146
qr_algorithm::vector_dot
double vector_dot(const std::valarray< T > &a, const std::valarray< T > &b)
Definition
qr_decompose.h:76
qr_algorithm::vector_mag
double vector_mag(const std::valarray< T > &a)
Definition
qr_decompose.h:92
qr_algorithm::operator<<
std::ostream & operator<<(std::ostream &out, std::valarray< std::valarray< T > > const &v)
Definition
qr_decompose.h:33
numerical_methods
qr_decompose.h
Generated by
1.18.0