Open3D (C++ API)  0.17.0
RobustKernelImpl.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2023 www.open3d.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 #include <cmath>
11 
12 #include "open3d/core/CUDAUtils.h"
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  [=] 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  }()
Common CUDA utilities.
RobustKernelMethod
Definition: RobustKernel.h:15