#include <GPUClusterInfoAndMomentsCalculatorImpl.h>
|
CUDA_HOS_DEV | RealSymmetricMatrixSolver (const float a_orig, const float b_orig, const float c_orig, const float d_orig, const float e_orig, const float f_orig) |
|
CUDA_HOS_DEV void | get_eigenvalues (float &e_1, float &e_2, float &e_3) const |
| Calculate shifted and scaled eigenvalues of the matrix, in ascending value. More...
|
|
CUDA_HOS_DEV void | extract_one (const float eigenvalue, float(&res)[3], float(&representative)[3]) const |
|
CUDA_HOS_DEV void | get_eigenvectors (float(&res)[3][3], const float e_1, const float e_2, const float e_3, const float epsilon=s_typical_epsilon) const |
| Calculate the eigenvectors of the matrix, using the (possibly unscaled) eigenvalues e_1 , e_2 , e_3 (in ascending order of magnitude) and epsilon to guard against undefined cases. More...
|
|
CUDA_HOS_DEV void | get_solution (float(&eigenvalues)[3], float(&eigenvectors)[3][3], bool rescale_and_reshift_values=true, const float epsilon=s_typical_epsilon) |
| Get the full eigenvalues and eigenvectors for this matrix. More...
|
|
◆ RealSymmetricMatrixSolver()
CUDA_HOS_DEV ClusterMomentsCalculator::RealSymmetricMatrixSolver::RealSymmetricMatrixSolver |
( |
const float |
a_orig, |
|
|
const float |
b_orig, |
|
|
const float |
c_orig, |
|
|
const float |
d_orig, |
|
|
const float |
e_orig, |
|
|
const float |
f_orig |
|
) |
| |
|
inline |
Definition at line 455 of file GPUClusterInfoAndMomentsCalculatorImpl.h.
463 const float max_ab =
max( fabsf(
a), fabsf(
b) );
464 const float max_cd =
max( fabsf(
c), fabsf(d_orig) );
465 const float max_ef =
max( fabsf(e_orig), fabsf(f_orig) );
471 const float inv_scale = 1.0f /
scale;
475 d = d_orig * inv_scale;
476 e = e_orig * inv_scale;
477 f = f_orig * inv_scale;
◆ extract_one()
CUDA_HOS_DEV void ClusterMomentsCalculator::RealSymmetricMatrixSolver::extract_one |
( |
const float |
eigenvalue, |
|
|
float(&) |
res[3], |
|
|
float(&) |
representative[3] |
|
) |
| const |
|
inline |
Definition at line 547 of file GPUClusterInfoAndMomentsCalculatorImpl.h.
551 const float diag[3] = {
a - eigenvalue,
556 float vec_1[3], vec_2[3];
559 float max_value = -1.f;
561 for (
int i = 0;
i < 3; ++
i)
563 const float this_diag = fabsf(diag[
i]);
564 if (this_diag >= max_value)
567 max_value = this_diag;
573 representative[0] = diag[0];
574 representative[1] =
d;
575 representative[2] =
f;
585 else if (max_diag == 1)
587 representative[0] =
d;
588 representative[1] = diag[1];
589 representative[2] =
e;
602 representative[0] =
f;
603 representative[1] =
e;
604 representative[2] = diag[2];
620 const float norm_1 = rnorm3df(
res[0],
res[1],
res[2]);
621 const float norm_2 = rnorm3df(vec_1[0], vec_1[1], vec_1[2]);
623 const float norm_1 = 1.f / hypot(
res[0],
res[1],
res[2]);
624 const float norm_2 = 1.f / hypot(vec_1[0], vec_1[1], vec_1[2]);
627 if (norm_1 <= norm_2)
636 res[0] = vec_1[0] * norm_2;
637 res[1] = vec_1[1] * norm_2;
638 res[2] = vec_1[2] * norm_2;
◆ get_eigenvalues()
CUDA_HOS_DEV void ClusterMomentsCalculator::RealSymmetricMatrixSolver::get_eigenvalues |
( |
float & |
e_1, |
|
|
float & |
e_2, |
|
|
float & |
e_3 |
|
) |
| const |
|
inline |
Calculate shifted and scaled eigenvalues of the matrix, in ascending value.
To get the actual eigenvalues, you should multiply by scale
and then add shift
.
Definition at line 483 of file GPUClusterInfoAndMomentsCalculatorImpl.h.
487 const float ab =
a *
b;
488 const float corr_ab = fmaf(
a,
b, -ab);
489 const float dd =
d *
d;
490 const float corr_dd = fmaf(
d,
d, -dd);
491 const float ac =
a *
c;
492 const float corr_ac = fmaf(
a,
c, -ac);
493 const float ff =
f *
f;
494 const float corr_ff = fmaf(
f,
f, -
ff);
495 const float bc =
b *
c;
496 const float corr_bc = fmaf(
b,
c, -bc);
497 const float ee =
e *
e;
498 const float corr_ee = fmaf(
e,
e, -ee);
500 const float c_0 = fmaf(2 *
d,
f *
e,
506 const float c_1 =
sum_kahan_babushka_neumaier(ab, -dd, ac, -
ff, bc, -ee, corr_ab, -corr_dd, corr_ac, -corr_ff, corr_bc, corr_ee);
510 constexpr
float inv_3 = 1.f / 3.f;
512 const float c_2_over_3 = c_2 * inv_3;
514 const float a_over_3 =
max(fma(c_2, c_2_over_3, -c_1) * inv_3, 0.
f);
516 const float half_b = 0.5f * (fma(c_2_over_3, fma(2.
f * c_2_over_3, c_2_over_3, -c_1), c_0));
524 const float rho = sqrtf(a_over_3);
527 const float theta = atan2f(1.0
f, rsqrtf(
q) * half_b) * inv_3;
529 const float theta = atan2f(sqrtf(
q), half_b) * inv_3;
533 float sin_theta, cos_theta;
534 sincosf(
theta, &sin_theta, &cos_theta);
536 const float sin_theta = sinf(
theta);
537 const float cos_theta = cosf(
theta);
540 const float sqrt_3 = sqrtf(3.
f);
542 e_1 = fma(-
rho, fma( sqrt_3, sin_theta, cos_theta), c_2_over_3);
543 e_2 = fma(-
rho, fma(-sqrt_3, sin_theta, cos_theta), c_2_over_3);
544 e_3 = fma(
rho, 2.0
f * cos_theta, c_2_over_3);
◆ get_eigenvectors()
Calculate the eigenvectors of the matrix, using the (possibly unscaled) eigenvalues e_1
, e_2
, e_3
(in ascending order of magnitude) and epsilon
to guard against undefined cases.
Definition at line 647 of file GPUClusterInfoAndMomentsCalculatorImpl.h.
651 if (e_3 - e_1 <= epsilon)
667 const float d_0 = e_3 - e_2;
668 const float d_1 = e_2 - e_1;
670 const float d_min =
min(d_0, d_1);
671 const float d_max =
max(d_0, d_1);
674 float first_e, second_e;
694 #if USE_ORIGINAL_EIGEN
695 if (d_min <= 2 * epsilon *
d1)
698 const float base_norm = rnorm3df(
res[j][0],
res[j][1],
res[j][2]);
700 const float base_norm = 1.f / hypot(
res[j][0],
res[j][1],
res[j][2]);
704 const float norm = base_norm / extra_factor;
711 if (d_min <= 2 * epsilon * d_max)
725 const float norm = rnorm3df(
res[j][0],
res[j][1],
res[j][2]);
727 const float norm = 1.f / hypot(
res[j][0],
res[j][1],
res[j][2]);
736 float extra_vector[3];
744 const float norm = rnorm3df(
res[1][0],
res[1][1],
res[1][2]);
746 const float norm = 1.f / hypot(
res[1][0],
res[1][1],
res[1][2]);
◆ get_solution()
CUDA_HOS_DEV void ClusterMomentsCalculator::RealSymmetricMatrixSolver::get_solution |
( |
float(&) |
eigenvalues[3], |
|
|
float(&) |
eigenvectors[3][3], |
|
|
bool |
rescale_and_reshift_values = true , |
|
|
const float |
epsilon = s_typical_epsilon |
|
) |
| |
|
inline |
Get the full eigenvalues and eigenvectors for this matrix.
If rescale_and_reshift_values
is true
, the eigenvalues are scaled and shifted back to their proper value, given the original matrix.
Definition at line 759 of file GPUClusterInfoAndMomentsCalculatorImpl.h.
762 get_eigenvectors(eigenvectors, eigenvalues[0], eigenvalues[1], eigenvalues[2], epsilon);
764 if (rescale_and_reshift_values)
766 eigenvalues[0] = fmaf(eigenvalues[0],
scale,
shift);
767 eigenvalues[1] = fmaf(eigenvalues[1],
scale,
shift);
768 eigenvalues[2] = fmaf(eigenvalues[2],
scale,
shift);
float ClusterMomentsCalculator::RealSymmetricMatrixSolver::a |
float ClusterMomentsCalculator::RealSymmetricMatrixSolver::b |
float ClusterMomentsCalculator::RealSymmetricMatrixSolver::c |
float ClusterMomentsCalculator::RealSymmetricMatrixSolver::d |
float ClusterMomentsCalculator::RealSymmetricMatrixSolver::e |
float ClusterMomentsCalculator::RealSymmetricMatrixSolver::f |
◆ s_typical_epsilon
constexpr float ClusterMomentsCalculator::RealSymmetricMatrixSolver::s_typical_epsilon = std::numeric_limits<float>::epsilon() |
|
staticconstexpr |
◆ scale
float ClusterMomentsCalculator::RealSymmetricMatrixSolver::scale |
◆ shift
float ClusterMomentsCalculator::RealSymmetricMatrixSolver::shift |
The documentation for this struct was generated from the following file:
CUDA_HOS_DEV void get_eigenvectors(float(&res)[3][3], const float e_1, const float e_2, const float e_3, const float epsilon=s_typical_epsilon) const
Calculate the eigenvectors of the matrix, using the (possibly unscaled) eigenvalues e_1,...