ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
RobustKernelImpl.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 #include <cmath>
11 
15 
16 #ifndef __CUDACC__
17 using std::abs;
18 using std::exp;
19 using std::max;
20 using std::min;
21 using 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  [=] 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); \
49  }; \
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); \
56  }; \
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)); \
63  }; \
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)); \
70  }; \
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))); \
78  }; \
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 { \
86  return const_val; \
87  }; \
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)); \
94  }; \
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)) / \
101  Square(scale); \
102  }; \
103  return __VA_ARGS__(); \
104  } else { \
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) + \
110  1), \
111  ((shape_parameter / 2.0) - 1.0)) / \
112  Square(scale); \
113  }; \
114  return __VA_ARGS__(); \
115  } \
116  } else { \
117  utility::LogError("Unsupported method."); \
118  } \
119  }()
120 
126 #define DISPATCH_DUAL_ROBUST_KERNEL_FUNCTION(scalar_t, METHOD_1, \
127  scaling_parameter_1, METHOD_2, \
128  scaling_parameter_2, ...) \
129  [&] { \
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))); \
151  }; \
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))); \
160  }; \
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))); \
172  }; \
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))); \
178  }; \
179  return __VA_ARGS__(); \
180  } else { \
181  utility::LogError("Unsupported method."); \
182  } \
183  }()
Common CUDA utilities.
int min(int a, int b)
Definition: cutil_math.h:53
__host__ __device__ int2 abs(int2 v)
Definition: cutil_math.h:1267
int max(int a, int b)
Definition: cutil_math.h:48