ViennaCL - The Vienna Computing Library: examples/tutorial/qr.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.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
25 // Activate ublas support in ViennaCL
26 #define VIENNACL_WITH_UBLAS
27
28 //
29 // Include necessary system headers
30 //
31 #include <iostream>
32
33 //
34 // ViennaCL includes
35 //
36 #include "viennacl/matrix.hpp"
37 #include "viennacl/linalg/prod.hpp"
38 #include "viennacl/linalg/qr.hpp"
39
40 //
41 // Boost includes
42 //
43 #include <boost/numeric/ublas/vector.hpp>
44 #include <boost/numeric/ublas/matrix.hpp>
45 #include <boost/numeric/ublas/io.hpp>
46
47
51 template<typename MatrixType>
52 double check(MatrixType const & qr, MatrixType const & ref)
53 {
54 bool do_break = false;
55 double max_error = 0;
56 for (std::size_t i=0; i<ref.size1(); ++i)
57 {
58 for (std::size_t j=0; j<ref.size2(); ++j)
59 {
60 if (qr(i,j) != 0.0 && ref(i,j) != 0.0)
61 {
62 double rel_err = fabs(qr(i,j) - ref(i,j)) / fabs(ref(i,j) );
63
64 if (rel_err > max_error)
65 max_error = rel_err;
66 }
67
68
69 /* Uncomment the following if you also want to check for NaNs.
70 if (qr(i,j) != qr(i,j))
71 {
72 std::cout << "!!!" << std::endl;
73 std::cout << "!!! NaN detected at i=" << i << " and j=" << j << std::endl;
74 std::cout << "!!!" << std::endl;
75 do_break = true;
76 break;
77 }*/
78 }
79 if (do_break)
80 break;
81 }
82 return max_error;
83 }
84
89 int main (int, const char **)
90 {
91 typedef double ScalarType; //feel free to change this to 'double' if supported by your hardware
92 typedef boost::numeric::ublas::matrix<ScalarType> MatrixType;
93 typedef viennacl::matrix<ScalarType, viennacl::column_major> VCLMatrixType;
94
95 std::size_t rows = 113; // number of rows in the matrix
96 std::size_t cols = 54; // number of columns
97
101 MatrixType ublas_A(rows, cols);
102 MatrixType Q(rows, rows);
103 MatrixType R(rows, cols);
104
105 // Some random data with a bit of extra weight on the diagonal
106 for (std::size_t i=0; i<rows; ++i)
107 {
108 for (std::size_t j=0; j<cols; ++j)
109 {
110 ublas_A(i,j) = ScalarType(-1.0) + ScalarType((i+1)*(j+1))
111 + ScalarType( (rand() % 1000) - 500.0) / ScalarType(1000.0);
112
113 if (i == j)
114 ublas_A(i,j) += ScalarType(10.0);
115
116 R(i,j) = 0.0;
117 }
118
119 for (std::size_t j=0; j<rows; ++j)
120 Q(i,j) = ScalarType(0.0);
121 }
122
123 // keep initial input matrix for comparison
124 MatrixType ublas_A_backup(ublas_A);
125
126
130 VCLMatrixType vcl_A(ublas_A.size1(), ublas_A.size2());
131
132 viennacl::copy(ublas_A, vcl_A);
133
140 std::cout << "--- Boost.uBLAS ---" << std::endl;
141 std::vector<ScalarType> ublas_betas = viennacl::linalg::inplace_qr(ublas_A); //computes the QR factorization
142
146 viennacl::linalg::recoverQ(ublas_A, ublas_betas, Q, R);
147 MatrixType ublas_QR = prod(Q, R);
148 double ublas_error = check(ublas_QR, ublas_A_backup);
149 std::cout << "Maximum relative error (ublas): " << ublas_error << std::endl;
150
155 std::cout << "--- Hybrid (default) ---" << std::endl;
156 viennacl::copy(ublas_A_backup, vcl_A);
157 std::vector<ScalarType> hybrid_betas = viennacl::linalg::inplace_qr(vcl_A);
158
162 viennacl::copy(vcl_A, ublas_A);
163 Q.clear(); R.clear();
164 viennacl::linalg::recoverQ(ublas_A, hybrid_betas, Q, R);
165 double hybrid_error = check(ublas_QR, ublas_A_backup);
166 std::cout << "Maximum relative error (hybrid): " << hybrid_error << std::endl;
167
168
172 std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl;
173
174 return EXIT_SUCCESS;
175 }
176
viennacl::linalg::inplace_qr
std::vector< T > inplace_qr(viennacl::matrix< T, F, ALIGNMENT > &A, vcl_size_t block_size=16)
Overload of inplace-QR factorization of a ViennaCL matrix A.
Definition: qr.hpp:647
prod.hpp
Generic interface for matrix-vector and matrix-matrix products. See viennacl/linalg/vector_operations...
matrix.hpp
Implementation of the dense matrix class.
main
int main(int argc, const char *argv[])
Definition: qr.cpp:53
viennacl::matrix
A dense matrix class.
Definition: forwards.h:375
hybrid_betas
std::cout<< "--- ViennaCL (hybrid implementation) ---"<< std::endl;std::vector< ScalarType > hybrid_betas
Definition: least-squares.cpp:134
viennacl::linalg::recoverQ
void recoverQ(MatrixType const &A, VectorType const &betas, MatrixType &Q, MatrixType &R)
Definition: qr.hpp:564
qr.hpp
Provides a QR factorization using a block-based approach.
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
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
ScalarType
float ScalarType
Definition: fft_1d.cpp:42
check
void check(T const &t, U const &u, EpsilonT eps)
Definition: libviennacl_blas1.cpp:66