35 #define DISPATCH_ROBUST_KERNEL_FUNCTION(METHOD, scalar_t, scaling_parameter, \
36 shape_parameter, ...) \
38 scalar_t scale = static_cast<scalar_t>(scaling_parameter); \
39 if (METHOD == RobustKernelMethod::L2Loss) { \
40 auto GetWeightFromRobustKernel = \
41 [=] CLOUDVIEWER_HOST_DEVICE( \
42 scalar_t residual) -> scalar_t { return 1.0; }; \
43 return __VA_ARGS__(); \
44 } else if (METHOD == RobustKernelMethod::L1Loss) { \
45 auto GetWeightFromRobustKernel = \
46 [=] CLOUDVIEWER_HOST_DEVICE( \
47 scalar_t residual) -> scalar_t { \
48 return 1.0 / abs(residual); \
50 return __VA_ARGS__(); \
51 } else if (METHOD == RobustKernelMethod::HuberLoss) { \
52 auto GetWeightFromRobustKernel = \
53 [=] CLOUDVIEWER_HOST_DEVICE( \
54 scalar_t residual) -> scalar_t { \
55 return scale / max(abs(residual), scale); \
57 return __VA_ARGS__(); \
58 } else if (METHOD == RobustKernelMethod::CauchyLoss) { \
59 auto GetWeightFromRobustKernel = \
60 [=] CLOUDVIEWER_HOST_DEVICE( \
61 scalar_t residual) -> scalar_t { \
62 return 1.0 / (1.0 + Square(residual / scale)); \
64 return __VA_ARGS__(); \
65 } else if (METHOD == RobustKernelMethod::GMLoss) { \
66 auto GetWeightFromRobustKernel = \
67 [=] CLOUDVIEWER_HOST_DEVICE( \
68 scalar_t residual) -> scalar_t { \
69 return scale / Square(scale + Square(residual)); \
71 return __VA_ARGS__(); \
72 } else if (METHOD == RobustKernelMethod::TukeyLoss) { \
73 auto GetWeightFromRobustKernel = \
74 [=] CLOUDVIEWER_HOST_DEVICE( \
75 scalar_t residual) -> scalar_t { \
76 return Square(1.0 - Square(min((scalar_t)1.0, \
77 abs(residual) / scale))); \
79 return __VA_ARGS__(); \
80 } else if (METHOD == RobustKernelMethod::GeneralizedLoss) { \
81 if (cloudViewer::IsClose(shape_parameter, 2.0, 1e-3)) { \
82 auto const_val = 1.0 / Square(scale); \
83 auto GetWeightFromRobustKernel = \
84 [=] CLOUDVIEWER_HOST_DEVICE( \
85 scalar_t residual) -> scalar_t { \
88 return __VA_ARGS__(); \
89 } else if (cloudViewer::IsClose(shape_parameter, 0.0, 1e-3)) { \
90 auto GetWeightFromRobustKernel = \
91 [=] CLOUDVIEWER_HOST_DEVICE( \
92 scalar_t residual) -> scalar_t { \
93 return 2.0 / (Square(residual) + 2 * Square(scale)); \
95 return __VA_ARGS__(); \
96 } else if (shape_parameter < -1e7) { \
97 auto GetWeightFromRobustKernel = \
98 [=] CLOUDVIEWER_HOST_DEVICE( \
99 scalar_t residual) -> scalar_t { \
100 return exp(Square(residual / scale) / (-2.0)) / \
103 return __VA_ARGS__(); \
105 auto GetWeightFromRobustKernel = \
106 [=] CLOUDVIEWER_HOST_DEVICE( \
107 scalar_t residual) -> scalar_t { \
108 return pow((Square(residual / scale) / \
109 abs(shape_parameter - 2.0) + \
111 ((shape_parameter / 2.0) - 1.0)) / \
114 return __VA_ARGS__(); \
117 utility::LogError("Unsupported method."); \
126 #define DISPATCH_DUAL_ROBUST_KERNEL_FUNCTION(scalar_t, METHOD_1, \
127 scaling_parameter_1, METHOD_2, \
128 scaling_parameter_2, ...) \
130 scalar_t scale_1 = static_cast<scalar_t>(scaling_parameter_1); \
131 scalar_t scale_2 = static_cast<scalar_t>(scaling_parameter_2); \
132 if (METHOD_1 == RobustKernelMethod::L2Loss && \
133 METHOD_2 == RobustKernelMethod::L2Loss) { \
134 auto GetWeightFromRobustKernelFirst = \
135 [=] CLOUDVIEWER_HOST_DEVICE( \
136 scalar_t residual) -> scalar_t { return 1.0; }; \
137 auto GetWeightFromRobustKernelSecond = \
138 [=] CLOUDVIEWER_HOST_DEVICE( \
139 scalar_t residual) -> scalar_t { return 1.0; }; \
140 return __VA_ARGS__(); \
141 } else if (METHOD_1 == RobustKernelMethod::L2Loss && \
142 METHOD_2 == RobustKernelMethod::TukeyLoss) { \
143 auto GetWeightFromRobustKernelFirst = \
144 [=] CLOUDVIEWER_HOST_DEVICE( \
145 scalar_t residual) -> scalar_t { return 1.0; }; \
146 auto GetWeightFromRobustKernelSecond = \
147 [=] CLOUDVIEWER_HOST_DEVICE( \
148 scalar_t residual) -> scalar_t { \
149 return Square(1.0 - Square(min((scalar_t)1.0, \
150 abs(residual) / scale_2))); \
152 return __VA_ARGS__(); \
153 } else if (METHOD_1 == RobustKernelMethod::TukeyLoss && \
154 METHOD_2 == RobustKernelMethod::L2Loss) { \
155 auto GetWeightFromRobustKernelFirst = \
156 [=] CLOUDVIEWER_HOST_DEVICE( \
157 scalar_t residual) -> scalar_t { \
158 return Square(1.0 - Square(min((scalar_t)1.0, \
159 abs(residual) / scale_1))); \
161 auto GetWeightFromRobustKernelSecond = \
162 [=] CLOUDVIEWER_HOST_DEVICE( \
163 scalar_t residual) -> scalar_t { return 1.0; }; \
164 return __VA_ARGS__(); \
165 } else if (METHOD_1 == RobustKernelMethod::TukeyLoss && \
166 METHOD_2 == RobustKernelMethod::TukeyLoss) { \
167 auto GetWeightFromRobustKernelFirst = \
168 [=] CLOUDVIEWER_HOST_DEVICE( \
169 scalar_t residual) -> scalar_t { \
170 return Square(1.0 - Square(min((scalar_t)1.0, \
171 abs(residual) / scale_1))); \
173 auto GetWeightFromRobustKernelSecond = \
174 [=] CLOUDVIEWER_HOST_DEVICE( \
175 scalar_t residual) -> scalar_t { \
176 return Square(1.0 - Square(min((scalar_t)1.0, \
177 abs(residual) / scale_2))); \
179 return __VA_ARGS__(); \
181 utility::LogError("Unsupported method."); \
__host__ __device__ int2 abs(int2 v)