Open3D (C++ API)  0.19.0
Loading...
Searching...
No Matches
RobustKernelImpl.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2024 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7
8#pragma once
9
10#include <cmath>
11
15
16#ifndef __CUDACC__
17using std::abs;
18using std::exp;
19using std::max;
20using std::min;
21using std::pow;
22#endif
23
25
35#define DISPATCH_ROBUST_KERNEL_FUNCTION(METHOD, scalar_t, scaling_parameter, \
36 shape_parameter, ...) \
37 [&] { \
38 scalar_t scale = static_cast<scalar_t>(scaling_parameter); \
39 if (METHOD == RobustKernelMethod::L2Loss) { \
40 auto GetWeightFromRobustKernel = \
41 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
42 return 1.0; \
43 }; \
44 return __VA_ARGS__(); \
45 } else if (METHOD == RobustKernelMethod::L1Loss) { \
46 auto GetWeightFromRobustKernel = \
47 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
48 return 1.0 / abs(residual); \
49 }; \
50 return __VA_ARGS__(); \
51 } else if (METHOD == RobustKernelMethod::HuberLoss) { \
52 auto GetWeightFromRobustKernel = \
53 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
54 return scale / max(abs(residual), scale); \
55 }; \
56 return __VA_ARGS__(); \
57 } else if (METHOD == RobustKernelMethod::CauchyLoss) { \
58 auto GetWeightFromRobustKernel = \
59 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
60 return 1.0 / (1.0 + Square(residual / scale)); \
61 }; \
62 return __VA_ARGS__(); \
63 } else if (METHOD == RobustKernelMethod::GMLoss) { \
64 auto GetWeightFromRobustKernel = \
65 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
66 return scale / Square(scale + Square(residual)); \
67 }; \
68 return __VA_ARGS__(); \
69 } else if (METHOD == RobustKernelMethod::TukeyLoss) { \
70 auto GetWeightFromRobustKernel = \
71 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
72 return Square(1.0 - Square(min((scalar_t)1.0, \
73 abs(residual) / scale))); \
74 }; \
75 return __VA_ARGS__(); \
76 } else if (METHOD == RobustKernelMethod::GeneralizedLoss) { \
77 if (open3d::IsClose(shape_parameter, 2.0, 1e-3)) { \
78 auto const_val = 1.0 / Square(scale); \
79 auto GetWeightFromRobustKernel = \
80 [=] OPEN3D_HOST_DEVICE( \
81 scalar_t residual) -> scalar_t { \
82 return const_val; \
83 }; \
84 return __VA_ARGS__(); \
85 } else if (open3d::IsClose(shape_parameter, 0.0, 1e-3)) { \
86 auto GetWeightFromRobustKernel = \
87 [=] OPEN3D_HOST_DEVICE( \
88 scalar_t residual) -> scalar_t { \
89 return 2.0 / (Square(residual) + 2 * Square(scale)); \
90 }; \
91 return __VA_ARGS__(); \
92 } else if (shape_parameter < -1e7) { \
93 auto GetWeightFromRobustKernel = \
94 [=] OPEN3D_HOST_DEVICE( \
95 scalar_t residual) -> scalar_t { \
96 return exp(Square(residual / scale) / (-2.0)) / \
97 Square(scale); \
98 }; \
99 return __VA_ARGS__(); \
100 } else { \
101 auto GetWeightFromRobustKernel = \
102 [=] OPEN3D_HOST_DEVICE( \
103 scalar_t residual) -> scalar_t { \
104 return pow((Square(residual / scale) / \
105 abs(shape_parameter - 2.0) + \
106 1), \
107 ((shape_parameter / 2.0) - 1.0)) / \
108 Square(scale); \
109 }; \
110 return __VA_ARGS__(); \
111 } \
112 } else { \
113 utility::LogError("Unsupported method."); \
114 } \
115 }()
116
122#define DISPATCH_DUAL_ROBUST_KERNEL_FUNCTION(scalar_t, METHOD_1, \
123 scaling_parameter_1, METHOD_2, \
124 scaling_parameter_2, ...) \
125 [&] { \
126 scalar_t scale_1 = static_cast<scalar_t>(scaling_parameter_1); \
127 scalar_t scale_2 = static_cast<scalar_t>(scaling_parameter_2); \
128 if (METHOD_1 == RobustKernelMethod::L2Loss && \
129 METHOD_2 == RobustKernelMethod::L2Loss) { \
130 auto GetWeightFromRobustKernelFirst = \
131 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
132 return 1.0; \
133 }; \
134 auto GetWeightFromRobustKernelSecond = \
135 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
136 return 1.0; \
137 }; \
138 return __VA_ARGS__(); \
139 } else if (METHOD_1 == RobustKernelMethod::L2Loss && \
140 METHOD_2 == RobustKernelMethod::TukeyLoss) { \
141 auto GetWeightFromRobustKernelFirst = \
142 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
143 return 1.0; \
144 }; \
145 auto GetWeightFromRobustKernelSecond = \
146 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
147 return Square(1.0 - Square(min((scalar_t)1.0, \
148 abs(residual) / scale_2))); \
149 }; \
150 return __VA_ARGS__(); \
151 } else if (METHOD_1 == RobustKernelMethod::TukeyLoss && \
152 METHOD_2 == RobustKernelMethod::L2Loss) { \
153 auto GetWeightFromRobustKernelFirst = \
154 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
155 return Square(1.0 - Square(min((scalar_t)1.0, \
156 abs(residual) / scale_1))); \
157 }; \
158 auto GetWeightFromRobustKernelSecond = \
159 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
160 return 1.0; \
161 }; \
162 return __VA_ARGS__(); \
163 } else if (METHOD_1 == RobustKernelMethod::TukeyLoss && \
164 METHOD_2 == RobustKernelMethod::TukeyLoss) { \
165 auto GetWeightFromRobustKernelFirst = \
166 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
167 return Square(1.0 - Square(min((scalar_t)1.0, \
168 abs(residual) / scale_1))); \
169 }; \
170 auto GetWeightFromRobustKernelSecond = \
171 [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
172 return Square(1.0 - Square(min((scalar_t)1.0, \
173 abs(residual) / scale_2))); \
174 }; \
175 return __VA_ARGS__(); \
176 } else { \
177 utility::LogError("Unsupported method."); \
178 } \
179 }()
Common CUDA utilities.
RobustKernelMethod
Definition RobustKernel.h:15