Loading [MathJax]/extensions/TeX/AMSsymbols.js
Open3D (C++ API)  0.14.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
RobustKernelImpl.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // The MIT License (MIT)
5 //
6 // Copyright (c) 2018-2021 www.open3d.org
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 // IN THE SOFTWARE.
25 // ----------------------------------------------------------------------------
26 
27 #pragma once
28 
29 #include <cmath>
30 
31 #include "open3d/core/CUDAUtils.h"
34 
35 #ifndef __CUDACC__
36 using std::abs;
37 using std::exp;
38 using std::max;
39 using std::min;
40 using std::pow;
41 #endif
42 
44 
54 #define DISPATCH_ROBUST_KERNEL_FUNCTION(METHOD, scalar_t, scaling_parameter, \
55  shape_parameter, ...) \
56  [&] { \
57  scalar_t scale = static_cast<scalar_t>(scaling_parameter); \
58  if (METHOD == RobustKernelMethod::L2Loss) { \
59  auto GetWeightFromRobustKernel = \
60  [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
61  return 1.0; \
62  }; \
63  return __VA_ARGS__(); \
64  } else if (METHOD == RobustKernelMethod::L1Loss) { \
65  auto GetWeightFromRobustKernel = \
66  [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
67  return 1.0 / abs(residual); \
68  }; \
69  return __VA_ARGS__(); \
70  } else if (METHOD == RobustKernelMethod::HuberLoss) { \
71  auto GetWeightFromRobustKernel = \
72  [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
73  return scale / max(abs(residual), scale); \
74  }; \
75  return __VA_ARGS__(); \
76  } else if (METHOD == RobustKernelMethod::CauchyLoss) { \
77  auto GetWeightFromRobustKernel = \
78  [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
79  return 1.0 / (1.0 + Square(residual / scale)); \
80  }; \
81  return __VA_ARGS__(); \
82  } else if (METHOD == RobustKernelMethod::GMLoss) { \
83  auto GetWeightFromRobustKernel = \
84  [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
85  return scale / Square(scale + Square(residual)); \
86  }; \
87  return __VA_ARGS__(); \
88  } else if (METHOD == RobustKernelMethod::TukeyLoss) { \
89  auto GetWeightFromRobustKernel = \
90  [=] OPEN3D_HOST_DEVICE(scalar_t residual) -> scalar_t { \
91  return Square(1.0 - Square(min((scalar_t)1.0, \
92  abs(residual) / scale))); \
93  }; \
94  return __VA_ARGS__(); \
95  } else if (METHOD == RobustKernelMethod::GeneralizedLoss) { \
96  if (open3d::IsClose(shape_parameter, 2.0, 1e-3)) { \
97  auto const_val = 1.0 / Square(scale); \
98  auto GetWeightFromRobustKernel = \
99  [=] OPEN3D_HOST_DEVICE( \
100  scalar_t residual) -> scalar_t { \
101  return const_val; \
102  }; \
103  return __VA_ARGS__(); \
104  } else if (open3d::IsClose(shape_parameter, 0.0, 1e-3)) { \
105  auto GetWeightFromRobustKernel = \
106  [=] OPEN3D_HOST_DEVICE( \
107  scalar_t residual) -> scalar_t { \
108  return 2.0 / (Square(residual) + 2 * Square(scale)); \
109  }; \
110  return __VA_ARGS__(); \
111  } else if (shape_parameter < -1e7) { \
112  auto GetWeightFromRobustKernel = \
113  [=] OPEN3D_HOST_DEVICE( \
114  scalar_t residual) -> scalar_t { \
115  return exp(Square(residual / scale) / (-2.0)) / \
116  Square(scale); \
117  }; \
118  return __VA_ARGS__(); \
119  } else { \
120  auto GetWeightFromRobustKernel = \
121  [=] OPEN3D_HOST_DEVICE( \
122  scalar_t residual) -> scalar_t { \
123  return pow((Square(residual / scale) / \
124  abs(shape_parameter - 2.0) + \
125  1), \
126  ((shape_parameter / 2.0) - 1.0)) / \
127  Square(scale); \
128  }; \
129  return __VA_ARGS__(); \
130  } \
131  } else { \
132  utility::LogError("Unsupported method."); \
133  } \
134  }()
Common CUDA utilities.
RobustKernelMethod
Definition: RobustKernel.h:34