ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Matrix.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
10 
11 namespace cloudViewer {
12 namespace core {
13 namespace linalg {
14 namespace kernel {
15 
16 // ---- Matmul ----
17 template <typename scalar_t>
19  const scalar_t& m00,
20  const scalar_t& m01,
21  const scalar_t& m02,
22  const scalar_t& m10,
23  const scalar_t& m11,
24  const scalar_t& m12,
25  const scalar_t& m20,
26  const scalar_t& m21,
27  const scalar_t& m22,
28  const scalar_t& v0,
29  const scalar_t& v1,
30  const scalar_t& v2,
31  scalar_t& o0,
32  scalar_t& o1,
33  scalar_t& o2) {
34  o0 = m00 * v0 + m01 * v1 + m02 * v2;
35  o1 = m10 * v0 + m11 * v1 + m12 * v2;
36  o2 = m20 * v0 + m21 * v1 + m22 * v2;
37 }
38 
39 template <typename scalar_t>
41  const scalar_t* A_3x3, const scalar_t* B_3x1, scalar_t* C_3x1) {
42  C_3x1[0] = A_3x3[0] * B_3x1[0] + A_3x3[1] * B_3x1[1] + A_3x3[2] * B_3x1[2];
43  C_3x1[1] = A_3x3[3] * B_3x1[0] + A_3x3[4] * B_3x1[1] + A_3x3[5] * B_3x1[2];
44  C_3x1[2] = A_3x3[6] * B_3x1[0] + A_3x3[7] * B_3x1[1] + A_3x3[8] * B_3x1[2];
45 }
46 
47 template <typename scalar_t>
49  const scalar_t* A_3x3, const scalar_t* B_3x3, scalar_t* C_3x3) {
50  matmul3x3_3x1(A_3x3[0], A_3x3[1], A_3x3[2], A_3x3[3], A_3x3[4], A_3x3[5],
51  A_3x3[6], A_3x3[7], A_3x3[8], B_3x3[0], B_3x3[3], B_3x3[6],
52  C_3x3[0], C_3x3[3], C_3x3[6]);
53  matmul3x3_3x1(A_3x3[0], A_3x3[1], A_3x3[2], A_3x3[3], A_3x3[4], A_3x3[5],
54  A_3x3[6], A_3x3[7], A_3x3[8], B_3x3[1], B_3x3[4], B_3x3[7],
55  C_3x3[1], C_3x3[4], C_3x3[7]);
56  matmul3x3_3x1(A_3x3[0], A_3x3[1], A_3x3[2], A_3x3[3], A_3x3[4], A_3x3[5],
57  A_3x3[6], A_3x3[7], A_3x3[8], B_3x3[2], B_3x3[5], B_3x3[8],
58  C_3x3[2], C_3x3[5], C_3x3[8]);
59 }
60 
61 template <typename scalar_t>
63  const scalar_t* A_3x1_input,
64  const scalar_t* B_3x1_input,
65  scalar_t* C_3x1_output) {
66  C_3x1_output[0] =
67  A_3x1_input[1] * B_3x1_input[2] - A_3x1_input[2] * B_3x1_input[1];
68  C_3x1_output[1] =
69  A_3x1_input[2] * B_3x1_input[0] - A_3x1_input[0] * B_3x1_input[2];
70  C_3x1_output[2] =
71  A_3x1_input[0] * B_3x1_input[1] - A_3x1_input[1] * B_3x1_input[0];
72 }
73 
74 template <typename scalar_t>
76 cross_mag_3x1(const scalar_t* A_3x1_input, const scalar_t* B_3x1_input) {
77  scalar_t temp_0 =
78  A_3x1_input[1] * B_3x1_input[2] - A_3x1_input[2] * B_3x1_input[1];
79  scalar_t temp_1 =
80  A_3x1_input[2] * B_3x1_input[0] - A_3x1_input[0] * B_3x1_input[2];
81  scalar_t temp_2 =
82  A_3x1_input[0] * B_3x1_input[1] - A_3x1_input[1] * B_3x1_input[0];
83  return sqrt(temp_0 * temp_0 + temp_1 * temp_1 + temp_2 * temp_2);
84 }
85 
86 template <typename scalar_t>
88 dot_3x1(const scalar_t* A_3x1_input, const scalar_t* B_3x1_input) {
89  return A_3x1_input[0] * B_3x1_input[0] + A_3x1_input[1] * B_3x1_input[1] +
90  A_3x1_input[2] * B_3x1_input[2];
91 }
92 
93 // ---- Determinant ----
94 template <typename scalar_t>
96 det2x2(const scalar_t* A_2x2) {
97  return A_2x2[0] * A_2x2[3] - A_2x2[1] * A_2x2[2];
98 }
99 
100 template <typename scalar_t>
102 det3x3(const scalar_t* A_3x3) {
103  return A_3x3[0] * (A_3x3[4] * A_3x3[8] - A_3x3[5] * A_3x3[7]) -
104  A_3x3[3] * (A_3x3[1] * A_3x3[8] - A_3x3[2] * A_3x3[7]) +
105  A_3x3[6] * (A_3x3[1] * A_3x3[5] - A_3x3[2] * A_3x3[4]);
106 }
107 
108 template <typename scalar_t>
110  const scalar_t* A_2x2, scalar_t* output_2x2) {
111  scalar_t det = det3x3(A_2x2);
112  if (det < 1e-12) {
113  return false;
114  } else {
115  scalar_t invdet = 1.0 / det;
116  output_2x2[0] = A_2x2[3] * det;
117  output_2x2[1] = -A_2x2[1] * det;
118  output_2x2[2] = -A_2x2[2] * det;
119  output_2x2[3] = A_2x2[0] * det;
120  }
121  return true;
122 }
123 
124 // ---- Matrix Inverse ----
125 template <typename scalar_t>
127  const scalar_t* A_3x3, scalar_t* output_3x3) {
128  scalar_t det = det3x3(A_3x3);
129  if (det < 1e-12) {
130  return false;
131  } else {
132  scalar_t invdet = 1.0 / det;
133  output_3x3[0] = (A_3x3[4] * A_3x3[8] - A_3x3[7] * A_3x3[5]) * invdet;
134  output_3x3[1] = (A_3x3[2] * A_3x3[7] - A_3x3[1] * A_3x3[8]) * invdet;
135  output_3x3[2] = (A_3x3[1] * A_3x3[5] - A_3x3[2] * A_3x3[4]) * invdet;
136  output_3x3[3] = (A_3x3[5] * A_3x3[6] - A_3x3[3] * A_3x3[8]) * invdet;
137  output_3x3[4] = (A_3x3[0] * A_3x3[8] - A_3x3[2] * A_3x3[6]) * invdet;
138  output_3x3[5] = (A_3x3[3] * A_3x3[2] - A_3x3[0] * A_3x3[5]) * invdet;
139  output_3x3[6] = (A_3x3[3] * A_3x3[7] - A_3x3[6] * A_3x3[4]) * invdet;
140  output_3x3[7] = (A_3x3[6] * A_3x3[1] - A_3x3[0] * A_3x3[7]) * invdet;
141  output_3x3[8] = (A_3x3[0] * A_3x3[4] - A_3x3[3] * A_3x3[1]) * invdet;
142  }
143  return true;
144 }
145 
146 // ---- Matrix Transpose ----
147 template <typename scalar_t>
149  scalar_t* A_2x2) {
150  scalar_t temp_01 = A_2x2[1];
151  A_2x2[1] = A_2x2[2];
152  A_2x2[2] = temp_01;
153 }
154 
155 template <typename scalar_t>
157  const scalar_t* A_2x2, scalar_t* output_2x2) {
158  output_2x2[0] = A_2x2[0];
159  output_2x2[1] = A_2x2[2];
160  output_2x2[2] = A_2x2[1];
161  output_2x2[3] = A_2x2[3];
162 }
163 
164 template <typename scalar_t>
166  scalar_t* A_3x3) {
167  scalar_t temp_01 = A_3x3[1];
168  scalar_t temp_02 = A_3x3[2];
169  scalar_t temp_12 = A_3x3[5];
170  A_3x3[1] = A_3x3[3];
171  A_3x3[2] = A_3x3[6];
172  A_3x3[5] = A_3x3[7];
173  A_3x3[3] = temp_01;
174  A_3x3[6] = temp_02;
175  A_3x3[7] = temp_12;
176 }
177 
178 template <typename scalar_t>
180  const scalar_t* A_3x3, scalar_t* output_3x3) {
181  output_3x3[0] = A_3x3[0];
182  output_3x3[1] = A_3x3[3];
183  output_3x3[2] = A_3x3[6];
184 
185  output_3x3[3] = A_3x3[1];
186  output_3x3[4] = A_3x3[4];
187  output_3x3[5] = A_3x3[7];
188 
189  output_3x3[6] = A_3x3[2];
190  output_3x3[7] = A_3x3[5];
191  output_3x3[8] = A_3x3[8];
192 }
193 
194 template <typename scalar_t>
196  scalar_t* A_4x4) {
197  scalar_t temp_01 = A_4x4[1];
198  scalar_t temp_02 = A_4x4[2];
199  scalar_t temp_03 = A_4x4[3];
200  scalar_t temp_12 = A_4x4[6];
201  scalar_t temp_13 = A_4x4[7];
202  scalar_t temp_23 = A_4x4[11];
203  A_4x4[1] = A_4x4[4];
204  A_4x4[2] = A_4x4[8];
205  A_4x4[3] = A_4x4[12];
206  A_4x4[6] = A_4x4[9];
207  A_4x4[7] = A_4x4[13];
208  A_4x4[11] = A_4x4[14];
209  A_4x4[4] = temp_01;
210  A_4x4[8] = temp_02;
211  A_4x4[12] = temp_03;
212  A_4x4[9] = temp_12;
213  A_4x4[13] = temp_13;
214  A_4x4[14] = temp_23;
215 }
216 
217 template <typename scalar_t>
219  const scalar_t* A_4x4, scalar_t* output_4x4) {
220  output_4x4[0] = A_4x4[0];
221  output_4x4[1] = A_4x4[4];
222  output_4x4[2] = A_4x4[8];
223  output_4x4[3] = A_4x4[12];
224 
225  output_4x4[4] = A_4x4[1];
226  output_4x4[5] = A_4x4[5];
227  output_4x4[6] = A_4x4[9];
228  output_4x4[7] = A_4x4[13];
229 
230  output_4x4[8] = A_4x4[2];
231  output_4x4[9] = A_4x4[6];
232  output_4x4[10] = A_4x4[10];
233  output_4x4[11] = A_4x4[14];
234 
235  output_4x4[12] = A_4x4[3];
236  output_4x4[13] = A_4x4[7];
237  output_4x4[14] = A_4x4[11];
238  output_4x4[15] = A_4x4[15];
239 }
240 
241 } // namespace kernel
242 } // namespace linalg
243 } // namespace core
244 } // namespace cloudViewer
Common CUDA utilities.
#define CLOUDVIEWER_FORCE_INLINE
Definition: CUDAUtils.h:43
#define CLOUDVIEWER_HOST_DEVICE
Definition: CUDAUtils.h:44
#define CLOUDVIEWER_DEVICE
Definition: CUDAUtils.h:45
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE scalar_t det3x3(const scalar_t *A_3x3)
Definition: Matrix.h:102
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE void transpose3x3(const scalar_t *A_3x3, scalar_t *output_3x3)
Definition: Matrix.h:179
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE void transpose2x2(const scalar_t *A_2x2, scalar_t *output_2x2)
Definition: Matrix.h:156
static CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE void matmul3x3_3x1(const scalar_t &m00, const scalar_t &m01, const scalar_t &m02, const scalar_t &m10, const scalar_t &m11, const scalar_t &m12, const scalar_t &m20, const scalar_t &m21, const scalar_t &m22, const scalar_t &v0, const scalar_t &v1, const scalar_t &v2, scalar_t &o0, scalar_t &o1, scalar_t &o2)
Definition: Matrix.h:18
CLOUDVIEWER_HOST_DEVICE CLOUDVIEWER_FORCE_INLINE void cross_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input, scalar_t *C_3x1_output)
Definition: Matrix.h:62
CLOUDVIEWER_HOST_DEVICE CLOUDVIEWER_FORCE_INLINE scalar_t cross_mag_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input)
Definition: Matrix.h:76
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE void transpose3x3_(scalar_t *A_3x3)
Definition: Matrix.h:165
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE void transpose4x4(const scalar_t *A_4x4, scalar_t *output_4x4)
Definition: Matrix.h:218
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE void transpose4x4_(scalar_t *A_4x4)
Definition: Matrix.h:195
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE scalar_t det2x2(const scalar_t *A_2x2)
Definition: Matrix.h:96
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE void matmul3x3_3x3(const scalar_t *A_3x3, const scalar_t *B_3x3, scalar_t *C_3x3)
Definition: Matrix.h:48
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE bool inverse3x3(const scalar_t *A_3x3, scalar_t *output_3x3)
Definition: Matrix.h:126
CLOUDVIEWER_HOST_DEVICE CLOUDVIEWER_FORCE_INLINE scalar_t dot_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input)
Definition: Matrix.h:88
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE bool inverse2x2(const scalar_t *A_2x2, scalar_t *output_2x2)
Definition: Matrix.h:109
CLOUDVIEWER_DEVICE CLOUDVIEWER_FORCE_INLINE void transpose2x2_(scalar_t *A_2x2)
Definition: Matrix.h:148
Generic file read and write utility for python interface.