ViennaCL - The Vienna Computing Library  1.6.1
Free open-source GPU-accelerated linear algebra and solver library.
bisect.cpp
Go to the documentation of this file.
1 /* =========================================================================
2  Copyright (c) 2010-2014, 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 
22 #ifndef NDEBUG
23  #define NDEBUG
24 #endif
25 
26 // includes, system
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 
31 
32 // includes, project
33 
34 #include "viennacl/scalar.hpp"
35 #include "viennacl/vector.hpp"
36 #include "viennacl/matrix.hpp"
37 
39 #include "viennacl/linalg/tql2.hpp"
40 
41 #define EPS 10.0e-4
42 
43 
51 template<typename NumericT>
52 void initInputData(std::vector<NumericT> &diagonal, std::vector<NumericT> &superdiagonal, std::size_t mat_size)
53 {
54 
55  srand(278217421);
56  bool randomValues = false;
57 
58 
59  if (randomValues == true)
60  {
61  // Initialize diagonal and superdiagonal elements with random values
62  for (std::size_t i = 0; i < mat_size; ++i)
63  {
64  diagonal[i] = static_cast<NumericT>(2.0 * (((double)rand()
65  / (double) RAND_MAX) - 0.5));
66  superdiagonal[i] = static_cast<NumericT>(2.0 * (((double)rand()
67  / (double) RAND_MAX) - 0.5));
68  }
69  }
70  else
71  {
72  // Initialize diagonal and superdiagonal elements with modulo values
73  // This will cause in many multiple eigenvalues.
74  for (std::size_t i = 0; i < mat_size; ++i)
75  {
76  diagonal[i] = ((NumericT)(i % 8)) - 4.5f;
77  superdiagonal[i] = ((NumericT)(i % 5)) - 4.5f;
78  }
79  }
80  // the first element of s is used as padding on the device (thus the
81  // whole vector is copied to the device but the kernels are launched
82  // with (s+1) as start address
83  superdiagonal[0] = 0.0f;
84 }
85 
86 
90 template<typename NumericT>
91 bool runTest(std::size_t mat_size)
92 {
93  bool bResult = false;
94 
95  std::vector<NumericT> diagonal(mat_size);
96  std::vector<NumericT> superdiagonal(mat_size);
97  std::vector<NumericT> eigenvalues_bisect(mat_size);
98 
99  // -------------Initialize data-------------------
100  // Fill the diagonal and superdiagonal elements of the vector
101  initInputData(diagonal, superdiagonal, mat_size);
102 
103 
104  // -------Start the bisection algorithm------------
105  std::cout << "Start the bisection algorithm" << std::endl;
106  std::cout << "Matrix size: " << mat_size << std::endl;
107  bResult = viennacl::linalg::bisect(diagonal, superdiagonal, eigenvalues_bisect);
108  // Exit if an error occured during the execution of the algorithm
109  if (bResult == false)
110  return false;
111 
112 
113  // ---------------Check the results---------------
114  // The results of the bisection algorithm will be checked with the tql2 algorithm
115  // Initialize Data for tql2 algorithm
117  std::vector<NumericT> diagonal_tql(mat_size);
118  std::vector<NumericT> superdiagonal_tql(mat_size);
119  diagonal_tql = diagonal;
120  superdiagonal_tql = superdiagonal;
121 
122  // Start the tql2 algorithm
123  std::cout << "Start the tql2 algorithm..." << std::endl;
124  viennacl::linalg::tql2(Q, diagonal_tql, superdiagonal_tql);
125 
126  // Ensure that eigenvalues from tql2 algorithm are sorted in ascending order
127  std::sort(diagonal_tql.begin(), diagonal_tql.end());
128 
129 
130  // Compare the results from the bisection algorithm with the results
131  // from the tql2 algorithm.
132  std::cout << "Start comparison..." << std::endl;
133  for (std::size_t i = 0; i < mat_size; i++)
134  {
135  if (std::abs(eigenvalues_bisect[i] - diagonal_tql[i]) > EPS)
136  {
137  std::cout << std::setprecision(8) << eigenvalues_bisect[i] << " != " << diagonal_tql[i] << "\n";
138  return false;
139  }
140  }
141 
142 /*
143  // ------------Print the results---------------
144  std::cout << "mat_size = " << mat_size << std::endl;
145  for (unsigned int i = 0; i < mat_size; ++i)
146  {
147  std::cout << "Eigenvalue " << i << ": \tbisect: " << std::setprecision(8) << eigenvalues_bisect[i] << "\ttql2: " << diagonal_tql[i] << std::endl;
148  }
149 */
150 
151 
152  return bResult;
153 
154 }
155 
156 
158 // Program main
160 int main()
161 {
162  bool test_result = false;
163 
164  // run test for large matrix
165  test_result = runTest<float>(520);
166  if(test_result == true)
167  {
168  std::cout << "First Test Succeeded!" << std::endl << std::endl;
169  }
170  else
171  {
172  std::cout << "---TEST FAILED---" << std::endl;
173  exit(EXIT_FAILURE);
174  }
175 
176  // run test for small matrix
177  test_result = runTest<float>(230);
178  if(test_result == true)
179  {
180  std::cout << std::endl << "---TEST SUCCESSFULLY COMPLETED---" << std::endl;
181  exit(EXIT_SUCCESS);
182  }
183  else
184  {
185  std::cout << "---TEST FAILED---" << std::endl;
186  exit(EXIT_FAILURE);
187  }
188 }
#define EPS
Definition: bisect.cpp:41
void initInputData(std::vector< NumericT > &diagonal, std::vector< NumericT > &superdiagonal, std::size_t mat_size)
initInputData Initialize the diagonal and superdiagonal elements of the matrix
Definition: bisect.cpp:52
Implementation of the dense matrix class.
int main()
Definition: bisect.cpp:160
void tql2(matrix_base< SCALARTYPE, F > &Q, VectorType &d, VectorType &e)
Definition: tql2.hpp:42
Implementation of the tql2-algorithm for eigenvalue computations.
A dense matrix class.
Definition: forwards.h:374
Represents a vector consisting of 1 at a given index and zeros otherwise. To be used as an initialize...
Definition: matrix_def.hpp:69
Implementation of an bisection algorithm for eigenvalues.
std::vector< typename viennacl::result_of::cpu_value_type< typename VectorT::value_type >::type > bisect(VectorT const &alphas, VectorT const &betas)
Implementation of the bisect-algorithm for the calculation of the eigenvalues of a tridiagonal matrix...
Definition: bisect.hpp:75
bool runTest(std::size_t mat_size)
Run a simple test.
Definition: bisect.cpp:91
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
Implementation of the ViennaCL scalar class.