#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.
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
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.
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,...