MUDA
Loading...
Searching...
No Matches
svd.inl
1#ifdef __CUDA_ARCH__
2#include <muda/ext/eigen/svd/svd_impl.h>
3
4namespace muda::eigen
5{
6namespace details
7{
8 MUDA_INLINE MUDA_DEVICE void device_svd(const Eigen::Matrix<float, 3, 3>& F,
9 Eigen::Matrix<float, 3, 3>& U,
10 Eigen::Vector3<float>& Sigma,
11 Eigen::Matrix<float, 3, 3>& V)
12 {
13 muda::details::eigen::svd3x3(F(0, 0),
14 F(0, 1),
15 F(0, 2),
16 F(1, 0),
17 F(1, 1),
18 F(1, 2),
19 F(2, 0),
20 F(2, 1),
21 F(2, 2),
22 U(0, 0),
23 U(0, 1),
24 U(0, 2),
25 U(1, 0),
26 U(1, 1),
27 U(1, 2),
28 U(2, 0),
29 U(2, 1),
30 U(2, 2),
31 Sigma(0),
32 Sigma(1),
33 Sigma(2),
34 V(0, 0),
35 V(0, 1),
36 V(0, 2),
37 V(1, 0),
38 V(1, 1),
39 V(1, 2),
40 V(2, 0),
41 V(2, 1),
42 V(2, 2));
43 }
44} // namespace details
45} // namespace muda::eigen
46#endif
47
48#include <muda/ext/eigen/eigen_dense_cxx20.h>
49namespace muda::eigen
50{
51MUDA_INLINE MUDA_GENERIC void svd(const Eigen::Matrix<float, 3, 3>& F,
52 Eigen::Matrix<float, 3, 3>& U,
53 Eigen::Vector3<float>& Sigma,
54 Eigen::Matrix<float, 3, 3>& V)
55{
56 using mat3 = Eigen::Matrix<float, 3, 3>;
57 using vec3 = Eigen::Vector3<float>;
58#ifdef __CUDA_ARCH__
59 details::device_svd(F, U, Sigma, V);
60#else
61 const Eigen::JacobiSVD<mat3, Eigen::NoQRPreconditioner> svd(
62 F, Eigen::ComputeFullU | Eigen::ComputeFullV);
63 U = svd.matrixU();
64 V = svd.matrixV();
65 Sigma = svd.singularValues();
66#endif
67 mat3 L = mat3::Identity();
68 L(2, 2) = (U * V.transpose()).determinant();
69
70 const float detU = U.determinant();
71 const float detV = V.determinant();
72
73 if(detU < 0.0 && detV > 0)
74 U = U * L;
75 if(detU > 0.0 && detV < 0.0)
76 V = V * L;
77 Sigma[2] = Sigma[2] * L(2, 2);
78}
79
80MUDA_INLINE MUDA_GENERIC void pd(const Eigen::Matrix<float, 3, 3>& F,
81 Eigen::Matrix<float, 3, 3>& R,
82 Eigen::Matrix<float, 3, 3>& S)
83{
84 Eigen::Matrix<float, 3, 3> U, V;
85 Eigen::Vector3<float> Sigma;
86 svd(F, U, Sigma, V);
87 R = U * V.transpose();
88 S = V * Sigma.asDiagonal() * V.transpose();
89}
90
91MUDA_INLINE MUDA_GENERIC void svd(const Eigen::Matrix<double, 3, 3>& F,
92 Eigen::Matrix<double, 3, 3>& U,
93 Eigen::Vector3<double>& Sigma,
94 Eigen::Matrix<double, 3, 3>& V)
95{
96 Eigen::Matrix3f fU;
97 Eigen::Vector3f fSigma;
98 Eigen::Matrix3f fV;
99 svd(F.cast<float>(), fU, fSigma, fV);
100 U = fU.cast<double>();
101 Sigma = fSigma.cast<double>();
102 V = fV.cast<double>();
103}
104
105MUDA_INLINE MUDA_GENERIC void pd(const Eigen::Matrix<double, 3, 3>& F,
106 Eigen::Matrix<double, 3, 3>& R,
107 Eigen::Matrix<double, 3, 3>& S)
108{
109 Eigen::Matrix3f fR;
110 Eigen::Matrix3f fS;
111 pd(F.cast<float>(), fR, fS);
112 R = fR.cast<double>();
113 S = fS.cast<double>();
114}
115
116} // namespace muda::eigen