/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-roccv/checkouts/latest/include/core/detail/math/math.hpp Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-roccv/checkouts/latest/include/core/detail/math/math.hpp Source File#

10 min read time

Applies to Linux

rocCV: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-roccv/checkouts/latest/include/core/detail/math/math.hpp Source File
math.hpp
Go to the documentation of this file.
1 
22 #pragma once
23 
24 #include <hip/hip_runtime.h>
25 #include <cassert>
26 
28 
35 template <class T, int N>
36 class Vector {
37  public:
38  using Type = T;
39 
45  __host__ __device__ int size() const { return N; }
46 
47  const __host__ __device__ T &operator[](int i) const {
48  assert(i >= 0 && i < size());
49  return data_[i];
50  }
51 
52  __host__ __device__ T &operator[](int i) {
53  assert(i >= 0 && i < size());
54  return data_[i];
55  }
56 
57  __host__ __device__ operator const T *() const { return &data_[0]; }
58 
59  __host__ __device__ operator T *() { return &data_[0]; }
60 
61  T data_[N];
62 };
63 
64 template <class T, int N>
65 __host__ __device__ Vector<T, N> operator-(const Vector<T, N> &v) {
66  Vector<T, N> r;
67  for (int i = 0; i < N; ++i) {
68  r[i] = -v[i];
69  }
70  return r;
71 }
72 
80 template <class T, int M, int N = M>
81 class Matrix {
82  public:
83  using Type = T;
84 
90  __host__ __device__ int rows() const { return M; }
91 
97  __host__ __device__ int cols() const { return N; }
98 
105  const __host__ __device__ Vector<T, N> &operator[](int i) const {
106  assert(i >= 0 && i < rows());
107  return data_[i];
108  }
109 
116  __host__ __device__ Vector<T, N> &operator[](int i) {
117  assert(i >= 0 && i < rows());
118  return data_[i];
119  }
120 
127  const __host__ __device__ T &operator[](int2 c) const {
128  assert(c.y >= 0 && c.y < rows());
129  assert(c.x >= 0 && c.x < cols());
130  return data_[c.y][c.x];
131  }
132 
139  __host__ __device__ T &operator[](int2 c) {
140  assert(c.y >= 0 && c.y < rows());
141  assert(c.x >= 0 && c.x < cols());
142  return data_[c.y][c.x];
143  }
144 
150  __host__ __device__ void load(const T *data) {
151 #pragma unroll
152  for (int row = 0; row < M; row++) {
153 #pragma unroll
154  for (int col = 0; col < N; col++) {
155  data_[row][col] = data[row * M + col];
156  }
157  }
158  }
159 
165  __host__ __device__ void store(T *data) {
166 #pragma unroll
167  for (int row = 0; row < M; row++) {
168 #pragma unroll
169  for (int col = 0; col < N; col++) {
170  data[row * M + col] = data_[row][col];
171  }
172  }
173  }
174 
176 };
177 
178 // Determinant calculations
179 template <class T>
180 constexpr __host__ __device__ T det(const Matrix<T, 0, 0> &m) {
181  return T{1};
182 }
183 
184 template <class T>
185 constexpr __host__ __device__ T det(const Matrix<T, 1, 1> &m) {
186  return m[0][0];
187 }
188 
189 template <class T>
190 constexpr __host__ __device__ T det(const Matrix<T, 2, 2> &m) {
191  return m[0][0] * m[1][1] - m[0][1] * m[1][0];
192 }
193 
194 template <class T>
195 constexpr __host__ __device__ T det(const Matrix<T, 3, 3> &m) {
196  return m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) + m[0][1] * (m[1][2] * m[2][0] - m[1][0] * m[2][2]) +
197  m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
198 }
199 
200 // Matrix inversion
201 template <class T>
202 constexpr __host__ __device__ Matrix<T, 3, 3> inv(const Matrix<T, 3, 3> &m, const T &d) {
203  Matrix<T, 3, 3> A;
204  A[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) / d;
205  A[0][1] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]) / d;
206  A[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) / d;
207  A[1][0] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) / d;
208  A[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / d;
209  A[1][2] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) / d;
210  A[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) / d;
211  A[2][1] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) / d;
212  A[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / d;
213 
214  return A;
215 }
216 
217 template <class T>
218 constexpr __host__ __device__ void inv_inplace(Matrix<T, 3, 3> &m, const T &d) {
219  m = inv(m, d);
220 }
221 
222 template <class T, int N, class = std::enable_if_t<(N < 4)>>
223 constexpr __host__ __device__ bool inv_inplace(Matrix<T, N, N> &m) {
224  T d = det(m);
225 
226  if (d == 0) {
227  return false;
228  }
229 
230  inv_inplace(m, d);
231 
232  return true;
233 }
234 
235 template <class T>
236 __host__ __device__ void swap(T &a, T &b) {
237  T temp = a;
238  a = b;
239  b = temp;
240 }
241 
242 template <class T, int N>
243 __host__ __device__ T dot(const Vector<T, N> &a, const Vector<T, N> &b) {
244  T d = a[0] * b[0];
245 #pragma unroll
246  for (int j = 1; j < a.size(); ++j) {
247  d += a[j] * b[j];
248  }
249  return d;
250 }
251 
252 template <class F = float, class T, int N>
253 __host__ __device__ bool lu_inplace(Matrix<T, N, N> &m, Vector<int, N> &p) {
254  Vector<F, N> v;
255 
256 #pragma unroll
257  for (int i = 0; i < N; ++i) {
258  F big = 0;
259 
260 #pragma unroll
261  for (int j = 0; j < N; ++j) {
262  big = max(big, abs(m[i][j]));
263  }
264 
265  if (big == 0) {
266  return false;
267  }
268 
269  v[i] = 1.0 / big;
270  }
271 
272 #pragma unroll
273  for (int k = 0; k < N; ++k) {
274  F big = 0;
275  int imax = k;
276 
277 #pragma unroll
278  for (int i = k; i < N; ++i) {
279  F aux = v[i] * abs(m[i][k]);
280 
281  if (aux > big) {
282  big = aux;
283  imax = i;
284  }
285  }
286 
287  if (k != imax) {
288  swap(m[imax], m[k]);
289 
290  v[imax] = v[k];
291  }
292 
293  p[k] = imax;
294 
295  if (m[k][k] == 0) {
296  return false;
297  }
298 
299 #pragma unroll
300  for (int i = k + 1; i < N; ++i) {
301  T aux = m[i][k] /= m[k][k];
302 
303 #pragma unroll
304  for (int j = k + 1; j < N; ++j) {
305  m[i][j] -= aux * m[k][j];
306  }
307  }
308  }
309 
310  return true;
311 }
312 
313 template <class T, int N>
314 __host__ __device__ void solve_inplace(const Matrix<T, N, N> &lu, const Vector<int, N> &p, Vector<T, N> &b) {
315  int ii = -1;
316 
317 #pragma unroll
318  for (int i = 0; i < N; ++i) {
319  int ip = p[i];
320  T sum = b[ip];
321  b[ip] = b[i];
322 
323  if (ii >= 0) {
324  for (int j = ii; j < i; ++j) {
325  sum -= lu[i][j] * b[j];
326  }
327  } else if (sum != 0) {
328  ii = i;
329  }
330 
331  b[i] = sum;
332  }
333 
334 #pragma unroll
335  for (int i = N - 1; i >= 0; --i) {
336  T sum = b[i];
337 
338 #pragma unroll
339  for (int j = i + 1; j < N; ++j) {
340  sum -= lu[i][j] * b[j];
341  }
342 
343  b[i] = sum / lu[i][i];
344  }
345 }
346 
347 template <class T, int N>
348 __host__ __device__ bool solve_inplace(const Matrix<T, N, N> &m, Vector<T, N> &b) {
349  Vector<int, N> p;
350  Matrix<T, N, N> LU = m;
351 
352  if (!lu_inplace(LU, p)) {
353  return false;
354  }
355 
356  solve_inplace(LU, p, b);
357 
358  return true;
359 }
360 
361 }; // namespace roccv::detail::math
Defines a matrix object.
Definition: math.hpp:81
const __host__ __device__ T & operator[](int2 c) const
Returns a constant data reference from the matrix.
Definition: math.hpp:127
__host__ __device__ void store(T *data)
Stores data from the matrix into a 1D array in row-major order.
Definition: math.hpp:165
__host__ __device__ Vector< T, N > & operator[](int i)
Returns a row of a matrix as a vector reference.
Definition: math.hpp:116
const __host__ __device__ Vector< T, N > & operator[](int i) const
Returns a row of a matrix as a constant vector reference.
Definition: math.hpp:105
T Type
Definition: math.hpp:83
__host__ __device__ int cols() const
Returns the number of columns in the matrix.
Definition: math.hpp:97
__host__ __device__ void load(const T *data)
Loads a row-major array into the matrix.
Definition: math.hpp:150
__host__ __device__ int rows() const
Returns the number of rows in a matrix.
Definition: math.hpp:90
Vector< T, N > data_[M]
Definition: math.hpp:175
__host__ __device__ T & operator[](int2 c)
Returns a data reference from the matrix.
Definition: math.hpp:139
Defines a Vector object.
Definition: math.hpp:36
__host__ __device__ int size() const
Returns the size of the vector.
Definition: math.hpp:45
T data_[N]
Definition: math.hpp:61
__host__ __device__ T & operator[](int i)
Definition: math.hpp:52
T Type
Definition: math.hpp:38
const __host__ __device__ T & operator[](int i) const
Definition: math.hpp:47
Definition: math.hpp:27
__host__ __device__ void solve_inplace(const Matrix< T, N, N > &lu, const Vector< int, N > &p, Vector< T, N > &b)
Definition: math.hpp:314
constexpr __host__ __device__ Matrix< T, 3, 3 > inv(const Matrix< T, 3, 3 > &m, const T &d)
Definition: math.hpp:202
__host__ __device__ bool lu_inplace(Matrix< T, N, N > &m, Vector< int, N > &p)
Definition: math.hpp:253
__host__ __device__ void swap(T &a, T &b)
Definition: math.hpp:236
constexpr __host__ __device__ void inv_inplace(Matrix< T, 3, 3 > &m, const T &d)
Definition: math.hpp:218
__host__ __device__ T dot(const Vector< T, N > &a, const Vector< T, N > &b)
Definition: math.hpp:243
constexpr __host__ __device__ T det(const Matrix< T, 0, 0 > &m)
Definition: math.hpp:180
__host__ __device__ Vector< T, N > operator-(const Vector< T, N > &v)
Definition: math.hpp:65