This tutorial shows how the eigenvalues of a symmetric, tridiagonal matrix can be computed using bisection. We begin with the usual header inclusions:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
The first step is to generate a suitable input tridiagonal input matrix in the function initInputData():
template <typename NumericT>
void initInputData(std::vector<NumericT> &diagonal, std::vector<NumericT> &superdiagonal,
const unsigned int mat_size)
{
srand(278217421);
bool randomValues = false;
if(randomValues == true)
{
for (unsigned int i = 0; i < mat_size; ++i)
{
diagonal[i] =
static_cast<NumericT>(2.0 * (((double)rand()
/ (double) RAND_MAX) - 0.5));
superdiagonal[i] =
static_cast<NumericT>(2.0 * (((double)rand()
/ (double) RAND_MAX) - 0.5));
}
}
else
{
for(unsigned int i = 0; i < mat_size; ++i)
{
diagonal[i] = ((
NumericT)(i % 8)) - 4.5f;
superdiagonal[i] = ((
NumericT)(i % 5)) - 4.5f;
}
}
superdiagonal[0] = 0.0f;
}
The main program is now as follows:
{
bool bResult = false;
unsigned int mat_size = 30;
Create STL-vectors holding the diagonal, the superdiagonal, and the computed eigenvalues:
std::vector<NumericT> diagonal(mat_size);
std::vector<NumericT> superdiagonal(mat_size);
std::vector<NumericT> eigenvalues_bisect(mat_size);
Initialize the data with the helper routine defined earlier:
Run the bisection algorithm for the provided input
std::cout << "Start the bisection algorithm" << std::endl;
std::cout << std::endl << "---TUTORIAL COMPLETED---" << std::endl;
Uncomment the following code to also have the results printed:
exit(bResult == true ? EXIT_SUCCESS : EXIT_FAILURE);
}
Full Example Code
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
template <typename NumericT>
void initInputData(std::vector<NumericT> &diagonal, std::vector<NumericT> &superdiagonal,
const unsigned int mat_size)
{
srand(278217421);
bool randomValues = false;
if(randomValues == true)
{
for (unsigned int i = 0; i < mat_size; ++i)
{
diagonal[i] =
static_cast<NumericT>(2.0 * (((double)rand()
/ (double) RAND_MAX) - 0.5));
superdiagonal[i] =
static_cast<NumericT>(2.0 * (((double)rand()
/ (double) RAND_MAX) - 0.5));
}
}
else
{
for(unsigned int i = 0; i < mat_size; ++i)
{
diagonal[i] = ((
NumericT)(i % 8)) - 4.5f;
superdiagonal[i] = ((
NumericT)(i % 5)) - 4.5f;
}
}
superdiagonal[0] = 0.0f;
}
{
bool bResult = false;
unsigned int mat_size = 30;
std::vector<NumericT> diagonal(mat_size);
std::vector<NumericT> superdiagonal(mat_size);
std::vector<NumericT> eigenvalues_bisect(mat_size);
std::cout << "Start the bisection algorithm" << std::endl;
std::cout << std::endl << "---TUTORIAL COMPLETED---" << std::endl;
exit(bResult == true ? EXIT_SUCCESS : EXIT_FAILURE);
}