551 U(dimension), S(dimension), V(dimension);
556 std::tie(U, S, V) = impl::svd_NxN(A);
560 std::tie(U, S, V) = impl::svd_2x2(A);
568 for (
Index i = 0; i < dimension; ++i) {
571 for (
Index j = 0; j < dimension; ++j) {
580 if (S(0, 0) < S(1, 1)) {
581 std::swap(S(0, 0), S(1, 1));
582 std::swap(U(0, 0), U(0, 1));
583 std::swap(U(1, 0), U(1, 1));
584 std::swap(V(0, 0), V(0, 1));
585 std::swap(V(1, 0), V(1, 1));
591 return std::make_tuple(U, S, V);
1253 assert(dimension == 3);
1261 D = zero<T, N>(dimension);
1264 V = zero<T, N>(dimension);
1272 I = identity<T, N>(dimension);
1275 ii[3][2] = { { 1, 2 }, { 2, 0 }, { 0, 1 } };
1278 rm = zero<T, N>(dimension);
1282 trA = (1.0/3.0) *
I1(A);
1321 rhs = (J3 / 2.0) * T(std::sqrt(t1 * t1 * t1));
1324 theta = pi / 2.0 * (1.0 - (rhs < 0 ? -1.0 : 1.0));
1326 if (std::abs(rhs) <= 1.0) theta = std::acos(rhs);
1329 thetad3 = theta / 3.0;
1331 if (thetad3 > pi / 6.0) thetad3 += 2.0 * pi / 3.0;
1334 D(2,2) = 2.0 * std::cos(thetad3) * std::sqrt(-J2 / 3.0);
1338 R = Ap - D(2,2) * I;
1342 a(0) = R(0,0)*R(0,0) + R(1,0)*R(1,0) + R(2,0)*R(2,0);
1343 a(1) = R(0,1)*R(0,1) + R(1,1)*R(1,1) + R(2,1)*R(2,1);
1344 a(2) = R(0,2)*R(0,2) + R(1,2)*R(1,2) + R(2,2)*R(2,2);
1360 a(k) = std::sqrt(a(k));
1361 for (
int i(0); i < dimension; ++i)
1367 for (
int i(0); i < dimension; ++i)
1369 d0 += R(i,k) * R(i,ii[k][0]);
1370 d1 += R(i,k) * R(i,ii[k][1]);
1374 for (
int i(0); i < dimension; ++i)
1376 R(i,ii[k][0]) -= d0 * R(i,k);
1377 R(i,ii[k][1]) -= d1 * R(i,k);
1382 for (
int i(0); i < dimension; ++i)
1384 a(0) += R(i,ii[k][0]) * R(i,ii[k][0]);
1385 a(1) += R(i,ii[k][1]) * R(i,ii[k][1]);
1389 if (std::abs(a(1)) > std::abs(a(0))) p = 1;
1392 a(p) = std::sqrt(a(p));
1395 for (
int i(0); i < dimension; ++i)
1399 V(0,2) = R(1,k) * R(2,k2) - R(2,k) * R(1,k2);
1400 V(1,2) = R(2,k) * R(0,k2) - R(0,k) * R(2,k2);
1401 V(2,2) = R(0,k) * R(1,k2) - R(1,k) * R(0,k2);
1405 mag = std::sqrt(V(0,2) * V(0,2) + V(1,2) * V(1,2) + V(2,2) * V(2,2));
1413 rk(R(0,k), R(1,k), R(2,k));
1416 rk2(R(0,k2), R(1,k2), R(2,k2));
1426 rm(0,0) =
dot(rk,ak);
1427 rm(0,1) =
dot(rk,ak2);
1428 rm(1,1) =
dot(rk2,ak2);
1432 b = 0.5 * (rm(0,0) - rm(1,1));
1435 fac = (b < 0 ? -1.0 : 1.0);
1438 arg = b * b + rm(0,1) * rm(0,1);
1441 D(0,0) = rm(1,1) + b;
1443 D(0,0) = rm(1,1) + b - fac * std::sqrt(b * b + rm(0,1) * rm(0,1));
1445 D(1,1) = rm(0,0) + rm(1,1) - D(0,0);
1454 a(0) = rm(0,0) * rm(0,0) + rm(0,1) * rm(0,1);
1455 a(1) = rm(0,1) * rm(0,1) + rm(1,1) * rm(1,1);
1458 if (a(1) > a(0)) k3 = 1;
1466 V(0,0) = rm(0,k3) * rk2(0) - rm(1,k3) * rk(0);
1467 V(1,0) = rm(0,k3) * rk2(1) - rm(1,k3) * rk(1);
1468 V(2,0) = rm(0,k3) * rk2(2) - rm(1,k3) * rk(2);
1471 mag = std::sqrt(V(0,0) * V(0,0) + V(1,0) * V(1,0) + V(2,0) * V(2,0));
1477 V(0,1) = V(1,0) * V(2,2) - V(2,0) * V(1,2);
1478 V(1,1) = V(2,0) * V(0,2) - V(0,0) * V(2,2);
1479 V(2,1) = V(0,0) * V(1,2) - V(1,0) * V(0,2);
1482 mag = std::sqrt(V(0,1) * V(0,1) + V(1,1) * V(1,1) + V(2,1) * V(2,1));
1488 for (
int i(0); i < dimension; ++i)
1492 return std::make_pair(V, D);