ATLAS Offline Software
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | List of all members
ClusterMomentsCalculator::RealSymmetricMatrixSolver Struct Reference

#include <GPUClusterInfoAndMomentsCalculatorImpl.h>

Collaboration diagram for ClusterMomentsCalculator::RealSymmetricMatrixSolver:

Public Member Functions

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

Static Public Member Functions

static CUDA_HOS_DEV void cross_prod (float(&res)[3], const float a1, const float a2, const float a3, const float b1, const float b2, const float b3)
 
static CUDA_HOS_DEV void cross_prod (float(&res)[3], const float(&x)[3], const float(&y)[3])
 
static CUDA_HOS_DEV float dot_prod (const float a1, const float a2, const float a3, const float b1, const float b2, const float b3)
 
static CUDA_HOS_DEV float dot_prod (const float(&x)[3], const float(&y)[3])
 

Public Attributes

float a
 
float b
 
float c
 
float d
 
float e
 
float f
 
float shift
 
float scale
 

Static Public Attributes

static constexpr float s_typical_epsilon = 5e-4
 

Detailed Description

Definition at line 21 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

Constructor & Destructor Documentation

◆ 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 31 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

32  {
33  using namespace std;
34 
35  shift = (a_orig + b_orig + c_orig) / 3.f;
36  a = a_orig - shift;
37  b = b_orig - shift;
38  c = c_orig - shift;
39  scale = max(fabsf(a), max(fabsf(b), max(fabsf(c), max(fabsf(d_orig), max(fabsf(e_orig), fabsf(f_orig))))));
40  if (scale == 0.f)
41  {
42  scale = 1.f;
43  }
44  a /= scale;
45  b /= scale;
46  c /= scale;
47  d = d_orig / scale;
48  e = e_orig / scale;
49  f = f_orig / scale;
50  }

Member Function Documentation

◆ cross_prod() [1/2]

static CUDA_HOS_DEV void ClusterMomentsCalculator::RealSymmetricMatrixSolver::cross_prod ( float(&)  res[3],
const float  a1,
const float  a2,
const float  a3,
const float  b1,
const float  b2,
const float  b3 
)
inlinestatic

Definition at line 96 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

97  {
98  res[0] = a2 * b3 - a3 * b2;
99  res[1] = a3 * b1 - a1 * b3;
100  res[2] = a1 * b2 - a2 * b1;
101  }

◆ cross_prod() [2/2]

static CUDA_HOS_DEV void ClusterMomentsCalculator::RealSymmetricMatrixSolver::cross_prod ( float(&)  res[3],
const float(&)  x[3],
const float(&)  y[3] 
)
inlinestatic

Definition at line 103 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

104  {
105  cross_prod(res, x[0], x[1], x[2], y[0], y[1], y[2]);
106  }

◆ dot_prod() [1/2]

static CUDA_HOS_DEV float ClusterMomentsCalculator::RealSymmetricMatrixSolver::dot_prod ( const float  a1,
const float  a2,
const float  a3,
const float  b1,
const float  b2,
const float  b3 
)
inlinestatic

Definition at line 108 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

109  {
110  return a1 * b1 + a2 * b2 + a3 * b3;
111  }

◆ dot_prod() [2/2]

static CUDA_HOS_DEV float ClusterMomentsCalculator::RealSymmetricMatrixSolver::dot_prod ( const float(&)  x[3],
const float(&)  y[3] 
)
inlinestatic

Definition at line 113 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

114  {
115  return dot_prod(x[0], x[1], x[2], y[0], y[1], y[2]);
116  }

◆ extract_one()

CUDA_HOS_DEV void ClusterMomentsCalculator::RealSymmetricMatrixSolver::extract_one ( const float  eigenvalue,
float(&)  res[3],
float(&)  representative[3] 
) const
inline

Definition at line 118 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

119  {
120  using namespace std;
121 
122  const float diag_0 = a - eigenvalue;
123  const float diag_1 = b - eigenvalue;
124  const float diag_2 = c - eigenvalue;
125 
126  float vec_1[3], vec_2[3];
127 
128  if (fabsf(diag_0) > fabsf(diag_1) && fabsf(diag_0) > fabsf(diag_2))
129  {
130  representative[0] = diag_0;
131  representative[1] = d;
132  representative[2] = f;
133 
134  vec_1[0] = d;
135  vec_1[1] = diag_1;
136  vec_1[2] = e;
137 
138  vec_2[0] = f;
139  vec_2[1] = e;
140  vec_2[2] = diag_2;
141  }
142  else if (/*(fabsf(diag_0) <= fabsf(diag_1) || fabsf(diag_0) <= fabsf(diag_2)) &&*/ fabsf(diag_1) > fabsf(diag_2))
143  {
144  representative[0] = d;
145  representative[1] = diag_1;
146  representative[2] = e;
147 
148  vec_1[0] = f;
149  vec_1[1] = e;
150  vec_1[2] = diag_2;
151 
152  vec_2[0] = diag_0;
153  vec_2[1] = d;
154  vec_2[2] = f;
155 
156  }
157  else /*if ((fabsf(diag_0) <= fabsf(diag_1) || fabsf(diag_0) <= fabsf(diag_2)) && fabsf(diag_1) <= fabsf(diag_2))*/
158  {
159  representative[0] = f;
160  representative[1] = e;
161  representative[2] = diag_2;
162 
163  vec_1[0] = diag_0;
164  vec_1[1] = d;
165  vec_1[2] = f;
166 
167  vec_2[0] = d;
168  vec_2[1] = diag_1;
169  vec_2[2] = e;
170  }
171 
172  cross_prod(res, representative, vec_1);
173  cross_prod(vec_1, representative, vec_2);
174  //Can safely override previous value...
175 
176 #ifdef __CUDA_ARCH__
177  const float norm_1 = rnorm3df(res[0], res[1], res[2]);
178  const float norm_2 = rnorm3df(vec_1[0], vec_1[1], vec_1[2]);
179 #else
180  const float norm_1 = 1.f / hypot(res[0], res[1], res[2]);
181  const float norm_2 = 1.f / hypot(vec_1[0], vec_1[1], vec_1[2]);
182 #endif
183 
184  if (norm_1 <= norm_2)
185  //Greater magnitude -> multiply by a smaller value
186  {
187  res[0] *= norm_1;
188  res[1] *= norm_1;
189  res[2] *= norm_1;
190  }
191  else
192  {
193  res[0] = vec_1[0] * norm_2;
194  res[1] = vec_1[1] * norm_2;
195  res[2] = vec_1[2] * norm_2;
196  }
197  }

◆ 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 55 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

56  {
57  using namespace std;
58 
59  const float c_0 = a * b * c + 2.f * d * f * e - a * e * e - b * f * f - c * d * d;
60  const float c_1 = a * b - d * d + a * c - f * f + b * c - e * e;
61  const float c_2 = a + b + c;
62 
63  constexpr float inv_3 = 1.f / 3.f;
64 
65  const float c_2_over_3 = c_2 * inv_3;
66 
67  const float a_over_3 = max((c_2 * c_2_over_3 - c_1) * inv_3, 0.f);
68 
69  const float half_b = 0.5f * (c_0 + c_2_over_3 * (2.f * c_2_over_3 * c_2_over_3 - c_1));
70 
71  const float q = max(a_over_3 * a_over_3 * a_over_3 - half_b * half_b, 0.f);
72 
73  const float rho = sqrtf(a_over_3);
74 
75 #ifdef __CUDA_ARCH__
76  const float theta = atan2f(1.0f, rsqrtf(q) * half_b) * inv_3;
77 #else
78  const float theta = atan2f(sqrtf(q), half_b) * inv_3;
79 #endif
80 
81 #ifdef __CUDA_ARCH__
82  float sin_theta, cos_theta;
83  sincosf(theta, &sin_theta, &cos_theta);
84 #else
85  const float sin_theta = sinf(theta);
86  const float cos_theta = cosf(theta);
87 #endif
88 
89  const float sqrt_3 = sqrtf(3.f);
90 
91  e_1 = c_2_over_3 - rho * (cos_theta + sqrt_3 * sin_theta);
92  e_2 = c_2_over_3 - rho * (cos_theta - sqrt_3 * sin_theta);
93  e_3 = c_2_over_3 + 2.f * rho * cos_theta;
94  }

◆ get_eigenvectors()

CUDA_HOS_DEV void ClusterMomentsCalculator::RealSymmetricMatrixSolver::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
inline

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 204 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

205  {
206  using namespace std;
207 
208  if (e_3 - e_1 <= epsilon)
209  {
210  res[0][0] = 1.f;
211  res[0][1] = 0.f;
212  res[0][2] = 0.f;
213 
214  res[1][0] = 0.f;
215  res[1][1] = 1.f;
216  res[1][2] = 0.f;
217 
218  res[2][0] = 0.f;
219  res[2][1] = 0.f;
220  res[2][2] = 1.f;
221  }
222  else
223  {
224  const float d_0 = e_3 - e_2;
225  const float d_1 = e_2 - e_1;
226 
227  const float d_min = min(d_0, d_1);
228 
229  int k, j;
230  float first_e, second_e;
231 
232  if (d_0 > d_1)
233  {
234  k = 2;
235  j = 0;
236 
237  first_e = e_3;
238  second_e = e_1;
239  }
240  else
241  {
242  k = 0;
243  j = 2;
244 
245  first_e = e_1;
246  second_e = e_3;
247  }
248 
249  extract_one(first_e, res[k], res[j]);
250 
251  if (d_min <= 2 * epsilon * d_1)
252  {
253 #ifdef __CUDA_ARCH__
254  const float base_norm = rnorm3df(res[j][0], res[j][1], res[j][2]);
255 #else
256  const float base_norm = 1.f / hypot(res[j][0], res[j][1], res[j][2]);
257 #endif
258  const float extra_factor = 1.f - dot_prod(res[k], res[j]);
259 
260  const float norm = base_norm / extra_factor;
261 
262  res[j][0] *= norm;
263  res[j][1] *= norm;
264  res[j][2] *= norm;
265  }
266  else
267  {
268  float extra_vector[3];
269 
270  extract_one(second_e, res[j], extra_vector);
271  }
272 
273  cross_prod(res[1], res[2], res[0]);
274 
275 #ifdef __CUDA_ARCH__
276  const float norm = rnorm3df(res[1][0], res[1][1], res[1][2]);
277 #else
278  const float norm = 1.f / hypot(res[1][0], res[1][1], res[1][2]);
279 #endif
280 
281  res[1][0] *= norm;
282  res[1][1] *= norm;
283  res[1][2] *= norm;
284  }
285  }

◆ 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 291 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

292  {
293  get_eigenvalues(eigenvalues[0], eigenvalues[1], eigenvalues[2]);
294  get_eigenvectors(eigenvectors, eigenvalues[0], eigenvalues[1], eigenvalues[2], epsilon);
295 
296  if (rescale_and_reshift_values)
297  {
298  eigenvalues[0] = eigenvalues[0] * scale + shift;
299  eigenvalues[1] = eigenvalues[1] * scale + shift;
300  eigenvalues[2] = eigenvalues[2] * scale + shift;
301  }
302  }

Member Data Documentation

◆ a

float ClusterMomentsCalculator::RealSymmetricMatrixSolver::a

Definition at line 24 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

◆ b

float ClusterMomentsCalculator::RealSymmetricMatrixSolver::b

Definition at line 24 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

◆ c

float ClusterMomentsCalculator::RealSymmetricMatrixSolver::c

Definition at line 24 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

◆ d

float ClusterMomentsCalculator::RealSymmetricMatrixSolver::d

Definition at line 24 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

◆ e

float ClusterMomentsCalculator::RealSymmetricMatrixSolver::e

Definition at line 24 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

◆ f

float ClusterMomentsCalculator::RealSymmetricMatrixSolver::f

Definition at line 24 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

◆ s_typical_epsilon

constexpr float ClusterMomentsCalculator::RealSymmetricMatrixSolver::s_typical_epsilon = 5e-4
staticconstexpr

Definition at line 199 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

◆ scale

float ClusterMomentsCalculator::RealSymmetricMatrixSolver::scale

Definition at line 24 of file GPUClusterInfoAndMomentsCalculatorImpl.h.

◆ shift

float ClusterMomentsCalculator::RealSymmetricMatrixSolver::shift

Definition at line 24 of file GPUClusterInfoAndMomentsCalculatorImpl.h.


The documentation for this struct was generated from the following file:
PlotCalibFromCool.norm
norm
Definition: PlotCalibFromCool.py:100
max
#define max(a, b)
Definition: cfImp.cxx:41
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:71
ClusterMomentsCalculator::RealSymmetricMatrixSolver::a
float a
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:24
ClusterMomentsCalculator::RealSymmetricMatrixSolver::dot_prod
static CUDA_HOS_DEV float dot_prod(const float a1, const float a2, const float a3, const float b1, const float b2, const float b3)
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:108
x
#define x
ClusterMomentsCalculator::RealSymmetricMatrixSolver::extract_one
CUDA_HOS_DEV void extract_one(const float eigenvalue, float(&res)[3], float(&representative)[3]) const
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:118
ClusterMomentsCalculator::RealSymmetricMatrixSolver::e
float e
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:24
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
min
#define min(a, b)
Definition: cfImp.cxx:40
ClusterMomentsCalculator::RealSymmetricMatrixSolver::f
float f
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:24
ClusterMomentsCalculator::RealSymmetricMatrixSolver::b
float b
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:24
y
#define y
ClusterMomentsCalculator::RealSymmetricMatrixSolver::get_eigenvectors
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,...
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:204
ClusterMomentsCalculator::RealSymmetricMatrixSolver::get_eigenvalues
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.
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:55
ClusterMomentsCalculator::RealSymmetricMatrixSolver::shift
float shift
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:24
ClusterMomentsCalculator::RealSymmetricMatrixSolver::scale
float scale
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:24
extractSporadic.q
list q
Definition: extractSporadic.py:98
ClusterMomentsCalculator::RealSymmetricMatrixSolver::c
float c
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:24
ClusterMomentsCalculator::RealSymmetricMatrixSolver::cross_prod
static CUDA_HOS_DEV void cross_prod(float(&res)[3], const float a1, const float a2, const float a3, const float b1, const float b2, const float b3)
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:96
ClusterMomentsCalculator::RealSymmetricMatrixSolver::d
float d
Definition: GPUClusterInfoAndMomentsCalculatorImpl.h:24
fitman.rho
rho
Definition: fitman.py:532
fitman.k
k
Definition: fitman.py:528