8 for (
Size i = 0; i < 3; ++i) {
12 svd.
S[i] = 1._f / svd.
S[i];
22 Vector(result(0, 0), result(1, 1), result(2, 2)),
Vector(result(0, 1), result(0, 2), result(1, 2)));
27 INLINE static double hypot2(
double x,
double y) {
29 return sqrt(x * x + y * y);
34 static void tred2(
double V[
N][
N],
double d[
N],
double e[
N]) {
39 for (
int j = 0; j <
N; j++) {
43 for (
int i =
N - 1; i > 0; i--) {
47 for (
int k = 0; k < i; k++) {
48 scale = scale + fabs(d[k]);
52 for (
int j = 0; j < i; j++) {
59 for (
int k = 0; k < i; k++) {
72 for (
int j = 0; j < i; j++) {
77 for (
int j = 0; j < i; j++) {
80 g = e[j] + V[j][j] * f;
81 for (
int k = j + 1; k <= i - 1; k++) {
89 for (
int j = 0; j < i; j++) {
93 double hh = f / (h + h);
94 for (
int j = 0; j < i; j++) {
97 for (
int j = 0; j < i; j++) {
100 for (
int k = j; k <= i - 1; k++) {
101 V[k][j] -= (f * e[k] + g * d[k]);
111 for (
int i = 0; i <
N - 1; i++) {
112 V[
N - 1][i] = V[i][i];
116 for (
int k = 0; k <= i; k++) {
117 d[k] = V[k][i + 1] / h;
119 for (
int j = 0; j <= i; j++) {
121 for (
int k = 0; k <= i; k++) {
122 g += V[k][i + 1] * V[k][j];
124 for (
int k = 0; k <= i; k++) {
129 for (
int k = 0; k <= i; k++) {
133 for (
int j = 0; j <
N; j++) {
137 V[
N - 1][
N - 1] = 1.0;
142 static void tql2(
double V[
N][
N],
double d[
N],
double e[
N]) {
147 for (
int i = 1; i <
N; i++) {
154 double eps =
pow(2.0, -52.0);
155 for (
int l = 0; l <
N; l++) {
157 tst1 =
max(tst1, fabs(d[l]) + fabs(e[l]));
160 if (fabs(e[m]) <= eps * tst1) {
174 double p = (d[l + 1] - g) / (2.0 * e[l]);
176 double r = hypot2(p, 1.0);
180 d[l] = e[l] / (p + r);
181 d[l + 1] = e[l] * (p + r);
182 double dl1 = d[l + 1];
184 for (
int i = l + 2; i <
N; i++) {
195 double el1 = e[l + 1];
198 for (
int i = m - 1; i >= l; i--) {
208 p = c * d[i] - s * g;
210 d[i + 1] = h + s * (c * g + s * d[i]);
213 for (
int k = 0; k <
N; k++) {
215 V[k][i + 1] = s * V[k][i] + c * h;
216 V[k][i] = c * V[k][i] - s * h;
219 p = -s * s2 * c3 * el1 * e[l] / dl1;
222 }
while (fabs(e[l]) > eps * tst1);
228 for (
int i = 0; i <
N - 1; i++) {
231 for (
int j = i + 1; j <
N; j++) {
240 for (
int j = 0; j <
N; j++) {
252 if (scale < 1.e-20_f) {
261 for (
int i = 0; i <
N; i++) {
262 for (
int j = 0; j <
N; j++) {
269 Vector(V[0][1], V[1][1], V[2][1]),
270 Vector(V[0][2], V[1][2], V[2][2])),
271 Vector(d[0], d[1], d[2]) };
274 INLINE static double SIGN(
double a,
double b) {
275 return b >= 0.0 ? fabs(a) : -fabs(a);
278 INLINE static double PYTHAG(
double a,
double b) {
279 double at = fabs(a), bt = fabs(b), ct, result;
284 result = at *
sqrt(1.0 + ct * ct);
285 }
else if (bt > 0.0) {
288 result = bt *
sqrt(1.0 + ct * ct);
296 int dsvd(
float (&a)[3][3],
float* w,
float (&v)[3][3]) {
297 const int m = 3, n = 3;
298 int flag, i, its, j, jj, k, l, nm;
299 double c, f, h, s, x, y, z;
300 double anorm = 0.0, g = 0.0, scale = 0.0;
305 rv1 = (
double*)malloc((
unsigned int)n *
sizeof(double));
308 for (i = 0; i < n; i++) {
314 for (k = i; k < m; k++)
315 scale += fabs((
double)a[k][i]);
317 for (k = i; k < m; k++) {
318 a[k][i] = (float)((
double)a[k][i] / scale);
319 s += ((double)a[k][i] * (
double)a[k][i]);
323 g = -SIGN(
sqrt(s), f);
325 a[i][i] = (float)(f - g);
327 for (j = l; j < n; j++) {
328 for (s = 0.0, k = i; k < m; k++)
329 s += ((
double)a[k][i] * (double)a[k][j]);
331 for (k = i; k < m; k++)
332 a[k][j] += (
float)(f * (double)a[k][i]);
335 for (k = i; k < m; k++)
336 a[k][i] = (
float)((double)a[k][i] * scale);
339 w[i] = (float)(scale * g);
343 if (i < m && i != n - 1) {
344 for (k = l; k < n; k++)
345 scale += fabs((
double)a[i][k]);
347 for (k = l; k < n; k++) {
348 a[i][k] = (float)((
double)a[i][k] / scale);
349 s += ((double)a[i][k] * (
double)a[i][k]);
353 g = -SIGN(
sqrt(s), f);
355 a[i][l] = (float)(f - g);
356 for (k = l; k < n; k++)
357 rv1[k] = (
double)a[i][k] / h;
359 for (j = l; j < m; j++) {
360 for (s = 0.0, k = l; k < n; k++)
361 s += ((
double)a[j][k] * (double)a[i][k]);
362 for (k = l; k < n; k++)
363 a[j][k] += (
float)(s * rv1[k]);
366 for (k = l; k < n; k++)
367 a[i][k] = (
float)((double)a[i][k] * scale);
370 anorm =
max(anorm, (fabs((
double)w[i]) + fabs(rv1[i])));
374 for (i = n - 1; i >= 0; i--) {
377 for (j = l; j < n; j++)
378 v[j][i] = (
float)(((double)a[i][j] / (
double)a[i][l]) / g);
380 for (j = l; j < n; j++) {
381 for (s = 0.0, k = l; k < n; k++)
382 s += ((
double)a[i][k] * (double)v[k][j]);
383 for (k = l; k < n; k++)
384 v[k][j] += (
float)(s * (double)v[k][i]);
387 for (j = l; j < n; j++)
388 v[i][j] = v[j][i] = 0.0;
396 for (i = n - 1; i >= 0; i--) {
400 for (j = l; j < n; j++)
405 for (j = l; j < n; j++) {
406 for (s = 0.0, k = l; k < m; k++)
407 s += ((
double)a[k][i] * (double)a[k][j]);
408 f = (s / (double)a[i][i]) * g;
409 for (k = i; k < m; k++)
410 a[k][j] += (
float)(f * (double)a[k][i]);
413 for (j = i; j < m; j++)
414 a[j][i] = (
float)((double)a[j][i] * g);
416 for (j = i; j < m; j++)
423 for (k = n - 1; k >= 0; k--) {
424 for (its = 0; its < 30; its++) {
426 for (l = k; l >= 0; l--) {
428 if (fabs(rv1[l]) + anorm == anorm) {
432 if (fabs((
double)w[nm]) + anorm == anorm)
438 for (i = l; i <= k; i++) {
440 if (fabs(f) + anorm != anorm) {
447 for (j = 0; j < m; j++) {
448 y = (double)a[j][nm];
450 a[j][nm] = (float)(y * c + z * s);
451 a[j][i] = (float)(z * c - y * s);
460 for (j = 0; j < n; j++)
461 v[j][k] = (-v[j][k]);
465 SPH_ASSERT(its < 30,
"No convergence after 30,000! iterations ");
474 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
476 f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
480 for (j = l; j <= nm; j++) {
494 for (jj = 0; jj < n; jj++) {
495 x = (double)v[jj][j];
496 z = (double)v[jj][i];
497 v[jj][j] = (float)(x * c + z * s);
498 v[jj][i] = (float)(z * c - x * s);
507 f = (c * g) + (s * y);
508 x = (c * y) - (s * g);
509 for (jj = 0; jj < m; jj++) {
510 y = (double)a[jj][j];
511 z = (double)a[jj][i];
512 a[jj][j] = (float)(y * c + z * s);
513 a[jj][i] = (float)(z * c - y * s);
534 { float(diag[0]), float(off[0]), float(off[1]) },
535 { float(off[0]), float(diag[1]), float(off[2]) },
536 { float(off[1]), float(off[2]), float(diag[2]) },
542 result.
S =
Vector(S[0], S[1], S[2]);
544 Vector(U[1][0], U[1][1], U[1][2]),
545 Vector(U[2][0], U[2][1], U[2][2]));
547 Vector(V[1][0], V[1][1], V[1][2]),
548 Vector(V[2][0], V[2][1], V[2][2]));
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
INLINE Float maxElement(const T &value)
Returns maximum element, simply the value iself by default.
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
constexpr INLINE T max(const T &f1, const T &f2)
INLINE T sqrt(const T f)
Return a squared root of a value.
constexpr INLINE Float pow(const Float v)
Power for floats.
INLINE auto abs(const T &f)
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
Eigen eigenDecomposition(const SymmetricTensor &t)
Computes eigenvectors and corresponding eigenvalues of symmetric matrix.
int dsvd(float(&a)[3][3], float *w, float(&v)[3][3])
Svd singularValueDecomposition(const SymmetricTensor &t)
Computes the singular value decomposition of symmetric matrix.
Basic algebra for symmetric 2nd order tensors.
BasicVector< Float > Vector
static AffineMatrix identity()
static AffineMatrix scale(const Vector &scaling)
INLINE AffineMatrix transpose() const
Returns the transposed matrix.
Symmetric tensor of 2nd order.
INLINE const Vector & offDiagonal() const
Returns the off-diagonal elements of the tensor.
SymmetricTensor pseudoInverse(const Float eps) const
SymmetricTensor()=default
INLINE const Vector & diagonal() const
Returns the diagonal part of the tensor.