13 #define ROTATE(a, i, j, k, l) \
17 a[i][j] = g - s * (h + g * tau); \
18 a[k][l] = h + s * (g - h * tau); \
22 template <
typename Scalar>
48 unsigned maxIterationCount = 50) {
53 unsigned n = matrix.
size();
65 std::vector<Scalar> bw, zw;
67 eigenValues.resize(n);
72 for (
unsigned i = 0; i < n; i++) {
73 bw[i] = eigenValues[i] = a.
m_values[i][i];
75 }
catch (
const std::bad_alloc&) {
80 for (
unsigned it = 0; it < maxIterationCount; ++it) {
84 for (
unsigned j = 0; j < n; ++j) {
85 for (
unsigned i = 0; i < j; ++i) {
91 Scalar thresh =
static_cast<Scalar
>(sqrt(sum) / (4 * n));
96 for (
unsigned p = 0; p < n; ++p) {
97 for (
unsigned q = p + 1; q < n; ++q) {
99 Scalar termp = gapq +
std::abs(eigenValues[p]);
100 Scalar termq = gapq +
std::abs(eigenValues[q]);
103 if (it > 4 && termp ==
std::abs(eigenValues[p]) &&
104 termq ==
std::abs(eigenValues[q])) {
109 Scalar h = eigenValues[q] - eigenValues[p];
116 Scalar theta = h / (2 * a.
m_values[p][q]);
117 t = 1 / (
std::abs(theta) + sqrt(1 + theta * theta));
122 Scalar c = 1 / sqrt(1 + t * t);
124 Scalar tau = s / (1 + c);
138 for (j = 0; j < p; ++j) {
141 a.
m_values[j][p] = g - s * (h + g * tau);
142 a.
m_values[j][q] = h + s * (g - h * tau);
145 for (j = p + 1; j < q; ++j) {
148 a.
m_values[p][j] = g - s * (h + g * tau);
149 a.
m_values[j][q] = h + s * (g - h * tau);
152 for (j = q + 1; j < n; ++j) {
155 a.
m_values[p][j] = g - s * (h + g * tau);
156 a.
m_values[q][j] = h + s * (g - h * tau);
160 for (j = 0; j < n; ++j) {
161 Scalar g = eigenVectors.
m_values[j][p];
162 Scalar h = eigenVectors.
m_values[j][q];
163 eigenVectors.
m_values[j][p] = g - s * (h + g * tau);
164 eigenVectors.
m_values[j][q] = h + s * (g - h * tau);
170 for (
unsigned i = 0; i < n; ++i) {
172 eigenValues[i] = bw[i];
186 bool absoluteValues =
true,
187 unsigned maxIterationCount = 50) {
192 unsigned n = matrix.
size();
193 unsigned matrixSquareSize = n * n;
202 std::vector<Scalar> b, z;
204 eigenValues.resize(n);
207 }
catch (
const std::bad_alloc&) {
211 Scalar* d = eigenValues.data();
215 for (
unsigned ip = 0; ip < n; ip++) {
224 for (
unsigned i = 1; i <= maxIterationCount; i++) {
228 for (
unsigned ip = 0; ip < n - 1; ip++) {
229 for (
unsigned iq = ip + 1; iq < n; iq++)
237 if (absoluteValues) {
239 for (
unsigned ip = 0; ip < n; ip++) d[ip] =
std::abs(d[ip]);
247 tresh = sm /
static_cast<Scalar
>(
248 5 * matrixSquareSize);
252 for (
unsigned ip = 0; ip < n - 1; ip++) {
253 for (
unsigned iq = ip + 1; iq < n; iq++) {
258 static_cast<float>(
std::abs(d[ip]) + g) ==
259 static_cast<float>(
std::abs(d[ip])) &&
260 static_cast<float>(
std::abs(d[iq]) + g) ==
261 static_cast<float>(
std::abs(d[iq]))) {
264 Scalar h = d[iq] - d[ip];
266 if (
static_cast<float>(
std::abs(h) + g) ==
275 t = 1 / (
std::abs(theta) + sqrt(1 + theta * theta));
276 if (theta < 0) t = -t;
279 Scalar c = 1 / sqrt(t * t + 1);
281 Scalar tau = s / (1 + c);
291 for (
unsigned j = 0; j + 1 <= ip; j++)
296 for (
unsigned j = ip + 1; j + 1 <= iq; j++)
301 for (
unsigned j = iq + 1; j < n; j++)
306 for (
unsigned j = 0; j < n; j++)
315 for (
unsigned ip = 0; ip < n; ip++) {
335 if (!eigenVectors.
isValid() || eigenVectors.
size() < 2 ||
336 eigenVectors.
size() != eigenValues.size()) {
341 unsigned n = eigenVectors.
size();
342 for (
unsigned i = 0; i < n - 1; i++) {
343 unsigned maxValIndex = i;
344 for (
unsigned j = i + 1; j < n; j++)
345 if (eigenValues[j] > eigenValues[maxValIndex]) maxValIndex = j;
347 if (maxValIndex != i) {
348 std::swap(eigenValues[i], eigenValues[maxValIndex]);
349 for (
unsigned j = 0; j < n; ++j)
351 eigenVectors.
m_values[j][maxValIndex]);
366 Scalar eigenVector[]) {
367 if (eigenVector && index < eigenVectors.
size()) {
368 for (
unsigned i = 0; i < eigenVectors.
size(); ++i) {
369 eigenVector[i] = eigenVectors.
m_values[i][index];
387 Scalar& maxEigenValue,
388 Scalar maxEigenVector[]) {
389 if (!eigenVectors.
isValid() || eigenVectors.
size() < 2 ||
390 eigenVectors.
size() != eigenValues.size()) {
395 unsigned maxIndex = 0;
396 for (
unsigned i = 1; i < eigenVectors.
size(); ++i)
397 if (eigenValues[i] > eigenValues[maxIndex]) maxIndex = i;
399 maxEigenValue = eigenValues[maxIndex];
412 Scalar& minEigenValue,
413 Scalar minEigenVector[]) {
414 if (!eigenVectors.
isValid() || eigenVectors.
size() < 2 ||
415 eigenVectors.
size() != eigenValues.size()) {
420 unsigned minIndex = 0;
421 for (
unsigned i = 1; i < eigenVectors.
size(); ++i)
422 if (eigenValues[i] < eigenValues[minIndex]) minIndex = i;
424 minEigenValue = eigenValues[minIndex];
#define ROTATE(a, i, j, k, l)
Jacobi eigen vectors/values decomposition.
static bool GetEigenVector(const SquareMatrix &eigenVectors, unsigned index, Scalar eigenVector[])
Returns the given eigenvector.
std::vector< Scalar > EigenValues
static bool ComputeEigenValuesAndVectors2(const SquareMatrix &matrix, SquareMatrix &eigenVectors, EigenValues &eigenValues, unsigned maxIterationCount=50)
Computes the eigenvalues and eigenvectors of a given square matrix.
cloudViewer::SquareMatrixTpl< Scalar > SquareMatrix
static bool GetMinEigenValueAndVector(const SquareMatrix &eigenVectors, const EigenValues &eigenValues, Scalar &minEigenValue, Scalar minEigenVector[])
Returns the smallest eigenvalue and its associated eigenvector.
static bool ComputeEigenValuesAndVectors(const SquareMatrix &matrix, SquareMatrix &eigenVectors, EigenValues &eigenValues, bool absoluteValues=true, unsigned maxIterationCount=50)
Computes eigen vectors (and values) with the Jacobian method.
static bool SortEigenValuesAndVectors(SquareMatrix &eigenVectors, EigenValues &eigenValues)
static bool GetMaxEigenValueAndVector(const SquareMatrix &eigenVectors, const EigenValues &eigenValues, Scalar &maxEigenValue, Scalar maxEigenVector[])
Returns the biggest eigenvalue and its associated eigenvector.
void toIdentity()
Sets matrix to identity.
Scalar ** m_values
The matrix rows.
bool isValid() const
Returns matrix validity.
unsigned size() const
Returns matrix size.
__host__ __device__ int2 abs(int2 v)
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.