Open3D (C++ API)  0.16.0
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
34
35#ifndef __CUDACC__
36using std::abs;
37using std::exp;
38using std::max;
39using std::min;
40using 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