ViennaCL - The Vienna Computing Library: tests/src/qr_method_func.cpp Source File

ViennaCL - The Vienna Computing Library 1.7.1 Free open-source GPU-accelerated linear algebra and solver library. |

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
qr_method_func.cpp
Go to the documentation of this file.
1 /* =========================================================================
2 Copyright (c) 2010-2016, Institute for Microelectronics,
3 Institute for Analysis and Scientific Computing,
4 TU Wien.
5 Portions of this software are copyright by UChicago Argonne, LLC.
6
7 -----------------
8 ViennaCL - The Vienna Computing Library
9 -----------------
10
11 Project Head: Karl Rupp rupp@iue.tuwien.ac.at
12
13 (A list of authors and contributors can be found in the PDF manual)
14
15 License: MIT (X11), see file LICENSE in the base directory
16 ============================================================================= */
17
18
23 /*
24 *
25 * Test file for qr-method
26 *
27 */
28
29 // include necessary system headers
30 #include <iostream>
31
32 #ifndef NDEBUG
33 #define NDEBUG
34 #endif
35
36 #define VIENNACL_WITH_UBLAS
37
38 #include "viennacl/scalar.hpp"
39 #include "viennacl/vector.hpp"
40 #include "viennacl/linalg/prod.hpp"
41
42 #include <fstream>
43 #include <iomanip>
44 #include "viennacl/linalg/qr-method.hpp"
45 #include "viennacl/linalg/qr-method-common.hpp"
46 #include "viennacl/linalg/matrix_operations.hpp"
47 #include "viennacl/tools/random.hpp"
48
49 #define EPS 10.0e-3
50
51
52 namespace ublas = boost::numeric::ublas;
53 typedef float ScalarType;
54
55 void read_matrix_size(std::fstream& f, std::size_t& sz);
56
57 void read_matrix_size(std::fstream& f, std::size_t& sz)
58 {
59 if(!f.is_open())
60 {
61 throw std::invalid_argument("File is not opened");
62 }
63
64 f >> sz;
65 }
66 template <typename MatrixLayout>
67 void read_matrix_body(std::fstream& f, viennacl::matrix<ScalarType, MatrixLayout>& A)
68 {
69 if(!f.is_open())
70 {
71 throw std::invalid_argument("File is not opened");
72 }
73
74 boost::numeric::ublas::matrix<ScalarType> h_A(A.size1(), A.size2());
75
76 for(std::size_t i = 0; i < h_A.size1(); i++) {
77 for(std::size_t j = 0; j < h_A.size2(); j++) {
78 ScalarType val = 0.0;
79 f >> val;
80 h_A(i, j) = val;
81 }
82 }
83
84 viennacl::copy(h_A, A);
85 }
86
87 void matrix_print(viennacl::matrix<ScalarType>& A_orig);
88
89 void matrix_print(viennacl::matrix<ScalarType>& A_orig)
90 {
91 ublas::matrix<ScalarType> A(A_orig.size1(), A_orig.size2());
92 viennacl::copy(A_orig, A);
93 for (unsigned int i = 0; i < A.size1(); i++) {
94 for (unsigned int j = 0; j < A.size2(); j++)
95 std::cout << std::setprecision(6) << std::fixed << A(i, j) << "\t";
96 std::cout << std::endl;
97 }
98 std::cout << std::endl;
99 }
100
101 void matrix_print(ublas::matrix<ScalarType>& A);
102
103 void matrix_print(ublas::matrix<ScalarType>& A)
104 {
105 for (unsigned int i = 0; i < A.size1(); i++) {
106 for (unsigned int j = 0; j < A.size2(); j++)
107 std::cout << std::setprecision(6) << std::fixed << A(i, j) << "\t";
108 std::cout << std::endl;
109 }
110 std::cout << std::endl;
111 }
112
113 void vector_print(std::vector<ScalarType>& v );
114
115 void vector_print(std::vector<ScalarType>& v )
116 {
117 for (unsigned int i = 0; i < v.size(); i++)
118 std::cout << std::setprecision(6) << std::fixed << v[i] << ",\t";
119 std::cout << "\n";
120 }
121
122
123 template <typename MatrixType, typename VCLMatrixType>
124 bool check_for_equality(MatrixType const & ublas_A, VCLMatrixType const & vcl_A)
125 {
126 typedef typename MatrixType::value_type value_type;
127
128 ublas::matrix<value_type> vcl_A_cpu(vcl_A.size1(), vcl_A.size2());
129 viennacl::backend::finish(); //workaround for a bug in APP SDK 2.7 on Trinity APUs (with Catalyst 12.8)
130 viennacl::copy(vcl_A, vcl_A_cpu);
131
132 for (std::size_t i=0; i<ublas_A.size1(); ++i)
133 {
134 for (std::size_t j=0; j<ublas_A.size2(); ++j)
135 {
136 if (std::abs(ublas_A(i,j) - vcl_A_cpu(i,j)) > EPS * std::max(std::abs(ublas_A(i, j)), std::abs(vcl_A_cpu(i, j))))
137 {
138 std::cout << "Error at index (" << i << ", " << j << "): " << ublas_A(i,j) << " vs. " << vcl_A_cpu(i,j) << std::endl;
139 std::cout << std::endl << "TEST failed!" << std::endl;
140 return false;
141 }
142 }
143 }
144 std::cout << "PASSED!" << std::endl;
145 return true;
146 }
147
148 template <typename VectorType>
149 bool check_for_equality(VectorType const & vec_A, VectorType const & vec_B)
150 {
151
152 for (std::size_t i=0; i<vec_A.size(); ++i)
153 {
154 if (std::abs(vec_A[i] - vec_B[i]) > EPS)
155 {
156 std::cout << "Error at index (" << i << "): " << vec_A[i] << " vs " <<vec_B[i] << std::endl;
157 std::cout << std::endl << "TEST failed!" << std::endl;
158 return false;
159 }
160 }
161 std::cout << "PASSED!" << std::endl;
162 return true;
163 }
164
165 void fill_vector(std::vector<ScalarType>& v);
166
167 void fill_vector(std::vector<ScalarType>& v)
168 {
169 viennacl::tools::uniform_random_numbers<ScalarType> randomNumber;
170
171 for (unsigned int i = 0; i < v.size(); ++i)
172 v[i] = randomNumber();
173 }
174
175 /*
176 *
177 * ------------Functions to be tested---------------
178 *
179 */
180
181
182 template <typename NumericT>
183 void house_update_A_left(ublas::matrix<NumericT> & A,
184 std::vector<NumericT> D,
185 unsigned int start)
186 {
187 NumericT ss = 0;
188
189 std::size_t row_start = start + 1;
190 for(std::size_t i = 0; i < A.size2(); i++)
191 {
192 ss = 0;
193 for(std::size_t j = row_start; j < A.size1(); j++)
194 ss = ss +(D[j] * A(j, i));
195
196 for(std::size_t j = row_start; j < A.size1(); j++)
197 A(j, i) = A(j, i) - (2 * D[j] * ss);
198 }
199 }
200
201 template <typename NumericT>
202 void house_update_A_right(ublas::matrix<NumericT> & A,
203 std::vector<NumericT> D)
204 {
205 NumericT ss = 0;
206
207 for(std::size_t i = 0; i < A.size1(); i++)
208 {
209 ss = 0;
210 for(std::size_t j = 0; j < A.size2(); j++)
211 ss = ss + (D[j] * A(i, j));
212
213 NumericT sum_Av = ss;
214
215 for(std::size_t j = 0; j < A.size2(); j++)
216 A(i, j) = A(i, j) - (2 * D[j] * sum_Av);
217 }
218 }
219
220
221 template <typename NumericT>
222 void house_update_QL(ublas::matrix<NumericT> & Q,
223 std::vector<NumericT> D,
224 std::size_t A_size1)
225
226 {
227 NumericT beta = 2;
228 ublas::matrix<NumericT> ubl_P(A_size1, A_size1);
229 ublas::matrix<ScalarType> I = ublas::identity_matrix<ScalarType>(Q.size1());
230 ublas::matrix<NumericT> Q_temp(Q.size1(), Q.size2());
231
232 for(std::size_t i = 0; i < Q.size1(); i++)
233 {
234 for(std::size_t j = 0; j < Q.size2(); j++)
235 {
236 Q_temp(i, j) = Q(i, j);
237 }
238 }
239
240 ubl_P = ublas::identity_matrix<NumericT>(A_size1);
241
242 //scaled_rank_1 update
243 for(std::size_t i = 0; i < A_size1; i++)
244 {
245 for(std::size_t j = 0; j < A_size1; j++)
246 {
247 ubl_P(i, j) = I(i, j) - beta * (D[i] * D[j]);
248 }
249 }
250 Q = ublas::prod(Q_temp, ubl_P);
251 }
252
253 template <typename NumericT>
254 void givens_next(ublas::matrix<NumericT> & Q,
255 std::vector<NumericT> & tmp1,
256 std::vector<NumericT> & tmp2,
257 int l,
258 int m)
259 {
260 for(int i2 = m - 1; i2 >= l; i2--)
261 {
262 std::size_t i = static_cast<std::size_t>(i2);
263 for(std::size_t k = 0; k < Q.size1(); k++)
264 {
265 NumericT h = Q(k, i+1);
266 Q(k, i+1) = tmp2[i] * Q(k, i) + tmp1[i]*h;
267 Q(k, i) = tmp1[i] * Q(k, i) - tmp2[i]*h;
268 }
269 }
270 }
271
272
273 template <typename NumericT>
274 void copy_vec(ublas::matrix<NumericT>& A,
275 std::vector<NumericT> & V,
276 std::size_t row_start,
277 std::size_t col_start,
278 bool copy_col)
279 {
280 if(copy_col)
281 {
282 for(std::size_t i = row_start; i < A.size1(); i++)
283 {
284 V[i - row_start] = A(i, col_start);
285 }
286 }
287 else
288 {
289 for(std::size_t i = col_start; i < A.size1(); i++)
290 {
291 V[i - col_start] = A(row_start, i);
292 }
293 }
294 }
295
296 template <typename NumericT>
297 void bidiag_pack(ublas::matrix<NumericT> & A,
298 std::vector<NumericT> & D,
299 std::vector<NumericT> & S)
300
301 {
302 std::size_t size = std::min(D.size(), S.size());
303 std::size_t i = 0;
304 for(i = 0; i < size - 1; i++)
305 {
306 D[i] = A(i, i);
307 S[i + 1] = A(i, i + 1);
308 }
309 D[size - 1] = A(size - 1, size - 1);
310 }
311
312
313 template <typename MatrixLayout>
314 void test_qr_method_sym(const std::string& fn)
315 {
316 std::cout << "Reading..." << std::endl;
317 std::size_t sz;
318
319 // read file
320 std::fstream f(fn.c_str(), std::fstream::in);
321 //read size of input matrix
322 read_matrix_size(f, sz);
323
324 viennacl::matrix<ScalarType, MatrixLayout> vcl_A(sz, sz), vcl_Q(sz, sz);
325 viennacl::vector<ScalarType> vcl_D(sz), vcl_E(sz), vcl_F(sz), vcl_G(sz), vcl_H(sz);
326 std::vector<ScalarType> std_D(sz), std_E(sz), std_F(sz), std_G(sz), std_H(sz);
327 ublas::matrix<ScalarType> ubl_A(sz, sz), ubl_Q(sz, sz);
328
329
330 std::cout << "Testing matrix of size " << sz << "-by-" << sz << std::endl << std::endl;
331
332 read_matrix_body(f, vcl_A);
333 f.close();
334 viennacl::copy(vcl_A, ubl_A);
335
336 fill_vector(std_D);
337 copy(std_D, vcl_D);
338 //--------------------------------------------------------
339 std::cout << std::endl << "Testing house_update_left..." << std::endl;
340 viennacl::linalg::house_update_A_left(vcl_A, vcl_D, 0);
341 house_update_A_left(ubl_A, std_D, 0);
342
343 if(!check_for_equality(ubl_A, vcl_A))
344 exit(EXIT_FAILURE);
345 //--------------------------------------------------------
346 std::cout << std::endl << "Testing house_update_right..." << std::endl;
347 copy(ubl_A, vcl_A);
348 copy(std_D, vcl_D);
349 viennacl::linalg::house_update_A_right(vcl_A, vcl_D);
350 house_update_A_right(ubl_A, std_D);
351
352 if(!check_for_equality(ubl_A, vcl_A))
353 exit(EXIT_FAILURE);
354 //--------------------------------------------------------
355
356 std::cout << std::endl << "Testing house_update_QL..." << std::endl;
357 ubl_Q = ublas::identity_matrix<ScalarType>(ubl_Q.size1());
358 copy(ubl_Q, vcl_Q);
359 copy(ubl_A, vcl_A);
360 copy(std_D, vcl_D);
361 viennacl::linalg::house_update_QL(vcl_Q, vcl_D, vcl_A.size1());
362 house_update_QL(ubl_Q, std_D, ubl_A.size1());
363 if(!check_for_equality(ubl_Q, vcl_Q))
364 exit(EXIT_FAILURE);
365 //--------------------------------------------------------
366
367 std::cout << std::endl << "Testing givens next..." << std::endl;
368 fill_vector(std_E);
369 fill_vector(std_F);
370 copy(std_E, vcl_E);
371 copy(std_F, vcl_F);
372 copy(ubl_Q, vcl_Q);
373 copy(ubl_A, vcl_A);
374 viennacl::linalg::givens_next(vcl_Q, vcl_E, vcl_F, 2, 5);
375 givens_next(ubl_Q, std_E, std_F, 2, 5);
376 if(!check_for_equality(ubl_Q, vcl_Q))
377 exit(EXIT_FAILURE);
378 //--------------------------------------------------------
379 std::cout << std::endl << "Testing copy vec..." << std::endl;
380 viennacl::linalg::copy_vec(vcl_A, vcl_D, 0, 2, 1);
381 copy_vec(ubl_A, std_D, 0, 2, 1);
382 copy(vcl_D, std_E); //check for equality only for same vector types
383 if(!check_for_equality(std_D, std_E))
384 exit(EXIT_FAILURE);
385
386 //--------------------------------------------------------
387 std::cout << std::endl << "Testing bidiag pack..." << std::endl;
388 viennacl::linalg::bidiag_pack(vcl_A, vcl_D, vcl_F);
389 vcl_F[0] = 0; // first element in superdiagonal is irrelevant.
390 bidiag_pack(ubl_A, std_G, std_H);
391 std_H[0] = 0;
392 copy(std_G, vcl_G);
393 copy(std_H, vcl_H);
394
395 if(!check_for_equality(vcl_D, vcl_G))
396 exit(EXIT_FAILURE);
397 if(!check_for_equality(vcl_F, vcl_H))
398 exit(EXIT_FAILURE);
399 //--------------------------------------------------------
400 }
401
402 int main()
403 {
404
405 std::cout << std::endl << "Test qr_method_sym for row_major matrix" << std::endl;
406 test_qr_method_sym<viennacl::row_major>("../examples/testdata/eigen/symm5.example");
407
408 std::cout << std::endl << "Test qr_method_sym for column_major matrix" << std::endl;
409 test_qr_method_sym<viennacl::column_major>("../examples/testdata/eigen/symm5.example");
410
411
412 std::cout << std::endl <<"--------TEST SUCCESSFULLY COMPLETED----------" << std::endl;
413 }
check_for_equality
bool check_for_equality(MatrixType const &ublas_A, VCLMatrixType const &vcl_A)
Definition: qr_method_func.cpp:124
copy_vec
void copy_vec(ublas::matrix< NumericT > &A, std::vector< NumericT > &V, std::size_t row_start, std::size_t col_start, bool copy_col)
Definition: qr_method_func.cpp:274
matrix_operations.hpp
Implementations of dense matrix related operations including matrix-vector products.
viennacl::linalg::copy_vec
void copy_vec(matrix_base< SCALARTYPE > &A, vector_base< SCALARTYPE > &V, vcl_size_t row_start, vcl_size_t col_start, bool copy_col)
This function copies a row or a column from a matrix to a vector.
Definition: matrix_operations.hpp:942
prod.hpp
Generic interface for matrix-vector and matrix-matrix products. See viennacl/linalg/vector_operations...
viennacl::linalg::house_update_A_right
void house_update_A_right(matrix_base< NumericT > &A, vector_base< NumericT > &D)
This function applies a householder transformation to a matrix: A <- A * P with a householder reflect...
Definition: matrix_operations.hpp:1018
test_qr_method_sym
void test_qr_method_sym(const std::string &fn)
Definition: qr_method_func.cpp:314
viennacl::linalg::house_update_QL
void house_update_QL(matrix_base< NumericT > &Q, vector_base< NumericT > &D, vcl_size_t A_size1)
This function updates the matrix Q, which is needed for the computation of the eigenvectors.
Definition: matrix_operations.hpp:1053
house_update_QL
void house_update_QL(ublas::matrix< NumericT > &Q, std::vector< NumericT > D, std::size_t A_size1)
Definition: qr_method_func.cpp:222
viennacl::backend::finish
void finish()
Synchronizes the execution. finish() will only return after all compute kernels (CUDA, OpenCL) have completed.
Definition: memory.hpp:54
viennacl::matrix
A dense matrix class.
Definition: forwards.h:375
main
int main()
Definition: qr_method_func.cpp:402
viennacl::linalg::detail::max
T max(const T &lhs, const T &rhs)
Maximum.
Definition: util.hpp:59
ScalarType
float ScalarType
Definition: qr_method_func.cpp:53
read_matrix_size
void read_matrix_size(std::fstream &f, std::size_t &sz)
Definition: qr_method_func.cpp:57
NumericT
float NumericT
Definition: bisect.cpp:40
EPS
#define EPS
Definition: qr_method_func.cpp:49
house_update_A_right
void house_update_A_right(ublas::matrix< NumericT > &A, std::vector< NumericT > D)
Definition: qr_method_func.cpp:202
qr-method-common.hpp
Common routines used for the QR method and SVD. Experimental.
viennacl::traits::size
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:239
house_update_A_left
void house_update_A_left(ublas::matrix< NumericT > &A, std::vector< NumericT > D, unsigned int start)
Definition: qr_method_func.cpp:183
fill_vector
void fill_vector(std::vector< ScalarType > &v)
Definition: qr_method_func.cpp:167
viennacl::tools::uniform_random_numbers
Random number generator for returning uniformly distributed values in the closed interval [0...
Definition: random.hpp:44
givens_next
void givens_next(ublas::matrix< NumericT > &Q, std::vector< NumericT > &tmp1, std::vector< NumericT > &tmp2, int l, int m)
Definition: qr_method_func.cpp:254
viennacl::linalg::bidiag_pack
void bidiag_pack(matrix_base< NumericT > &A, VectorType &dh, VectorType &sh)
This function stores the diagonal and the superdiagonal of a matrix in two vectors.
Definition: matrix_operations.hpp:901
viennacl::traits::start
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:44
viennacl::linalg::house_update_A_left
void house_update_A_left(matrix_base< NumericT > &A, vector_base< NumericT > &D, vcl_size_t start)
This function applies a householder transformation to a matrix. A <- P * A with a householder reflect...
Definition: matrix_operations.hpp:981
viennacl::matrix_base< NumericT >::size2
size_type size2() const
Returns the number of columns.
Definition: matrix_def.hpp:226
viennacl::vector< ScalarType >
viennacl::matrix_base< NumericT >::size1
size_type size1() const
Returns the number of rows.
Definition: matrix_def.hpp:224
bidiag_pack
void bidiag_pack(ublas::matrix< NumericT > &A, std::vector< NumericT > &D, std::vector< NumericT > &S)
Definition: qr_method_func.cpp:297
qr-method.hpp
Implementation of the QR method for eigenvalue computations. Experimental.
prod
void prod(std::vector< std::map< IndexT, NumericT > > const &stl_A, std::vector< std::map< IndexT, NumericT > > const &stl_B, std::vector< std::map< IndexT, NumericT > > &stl_C)
Definition: sparse_prod.cpp:114
vector.hpp
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
viennacl::copy
void copy(std::vector< NumericT > &cpu_vec, circulant_matrix< NumericT, AlignmentV > &gpu_mat)
Copies a circulant matrix from the std::vector to the OpenCL device (either GPU or multi-core CPU) ...
Definition: circulant_matrix.hpp:150
random.hpp
A small collection of sequential random number generators.
read_matrix_body
void read_matrix_body(std::fstream &f, viennacl::matrix< ScalarType, MatrixLayout > &A)
Definition: qr_method_func.cpp:67
ScalarType
float ScalarType
Definition: fft_1d.cpp:42
viennacl::linalg::detail::min
T min(const T &lhs, const T &rhs)
Minimum.
Definition: util.hpp:45
matrix_print
void matrix_print(viennacl::matrix< ScalarType > &A_orig)
Definition: qr_method_func.cpp:89
scalar.hpp
Implementation of the ViennaCL scalar class.
vector_print
void vector_print(std::vector< ScalarType > &v)
Definition: qr_method_func.cpp:115
viennacl::linalg::givens_next
void givens_next(matrix_base< NumericT > &Q, vector_base< NumericT > &tmp1, vector_base< NumericT > &tmp2, int l, int m)
This function updates the matrix Q. It is part of the tql2 algorithm.
Definition: matrix_operations.hpp:1092