matrixOps.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <vector>
5 
6 namespace dai {
7 namespace matrix {
15 std::vector<std::vector<float>> matMul(std::vector<std::vector<float>>& firstMatrix, std::vector<std::vector<float>>& secondMatrix) {
16  std::vector<std::vector<float>> res;
17 
18  if(firstMatrix[0].size() != secondMatrix.size()) {
19  throw std::runtime_error("Number of column of the first matrix should match with the number of rows of the second matrix ");
20  // Return an empty vector
21  return res;
22  }
23 
24  // Initializing elements of matrix mult to 0.
25  for(size_t i = 0; i < firstMatrix.size(); ++i) {
26  std::vector<float> col_vec(secondMatrix[0].size(), 0);
27  res.push_back(col_vec);
28  }
29 
30  // Multiplying matrix firstMatrix and secondMatrix and storing in array mult.
31  for(size_t i = 0; i < firstMatrix.size(); ++i) {
32  for(size_t j = 0; j < secondMatrix[0].size(); ++j) {
33  for(size_t k = 0; k < firstMatrix[0].size(); ++k) {
34  res[i][j] += firstMatrix[i][k] * secondMatrix[k][j];
35  }
36  }
37  }
38 
39  return res;
40 }
41 
42 /*
43  * Function to get cofactor of A[p][q] in temp. n is current
44  * dimension of part of A that we are calculating cofactor for.
45  */
46 static void getCofactor(std::vector<std::vector<float>>& A, std::vector<std::vector<float>>& temp, size_t p, size_t q, size_t n) {
47  size_t i = 0, j = 0;
48 
49  // Looping for each element of the matrix
50  for(size_t row = 0; row < n; ++row) {
51  for(size_t col = 0; col < n; ++col) {
52  // Copying into temporary matrix only those element
53  // which are not in given row and column
54  if(row != p && col != q) {
55  temp[i][j++] = A[row][col];
56 
57  // Row is filled, so increase row index and
58  // reset col index
59  if(j == n - 1) {
60  j = 0;
61  ++i;
62  }
63  }
64  }
65  }
66 }
67 
68 /* Recursive function for finding determinant of matrix.
69  n is current dimension of A[][]. */
70 static float determinant(std::vector<std::vector<float>>& A, size_t n) {
71  float D = 0; // Initialize result
72 
73  // Base case : if matrix contains single element
74  if(n == 1) return A[0][0];
75 
76  std::vector<std::vector<float>> temp(n, std::vector<float>(n, 0)); // To store cofactors
77  int sign = 1; // To store sign multiplier
78 
79  // Iterate for each element of first row
80  for(size_t f = 0; f < n; ++f) {
81  // Getting Cofactor of A[0][f]
82  getCofactor(A, temp, 0, f, n);
83  D += sign * A[0][f] * determinant(temp, n - 1);
84 
85  // terms are to be added with alternate sign
86  sign = -sign;
87  }
88 
89  return D;
90 }
91 
92 // Function to get adjoint of A in adj.
93 static void adjoint(std::vector<std::vector<float>>& A, std::vector<std::vector<float>>& adj) {
94  if(A.size() == 1) {
95  adj[0][0] = 1;
96  return;
97  }
98 
99  // temp is used to store the final cofactors of A
100  int sign = 1;
101  std::vector<std::vector<float>> temp(A.size(), std::vector<float>(A.size(), 0));
102 
103  for(size_t i = 0; i < A.size(); ++i) {
104  for(size_t j = 0; j < A.size(); ++j) {
105  // Get cofactor of A[i][j]
106  getCofactor(A, temp, i, j, A.size());
107 
108  // sign of adj[j][i] positive if sum of row
109  // and column indexes is even.
110  sign = ((i + j) % 2 == 0) ? 1 : -1;
111 
112  // Interchanging rows and columns to get the
113  // transpose of the cofactor matrix
114  adj[j][i] = (sign) * (determinant(temp, A.size() - 1));
115  }
116  }
117 }
118 
119 // Function to calculate and store inverse, returns false if
120 // matrix is singular
121 bool matInv(std::vector<std::vector<float>>& A, std::vector<std::vector<float>>& inverse) {
122  // Find determinant of A[][]
123  if(A[0].size() != A.size()) {
124  throw std::runtime_error("Not a Square Matrix ");
125  }
126 
127  float det = determinant(A, A.size());
128  if(det == 0) {
129  // cout << "Singular matrix, can't find its inverse";
130  return false;
131  }
132 
133  // Find adjoint
134  std::vector<std::vector<float>> adj(A.size(), std::vector<float>(A.size(), 0));
135  adjoint(A, adj);
136 
137  std::vector<float> temp;
138  // Find Inverse using formula "inverse(A) = adj(A)/det(A)"
139  for(size_t i = 0; i < A.size(); ++i) {
140  for(size_t j = 0; j < A.size(); ++j) {
141  temp.push_back(adj[i][j] / det);
142  }
143  inverse.push_back(temp);
144  temp.clear();
145  }
146 
147  return true;
148 }
149 
150 } // namespace matrix
151 } // namespace dai
dai::matrix::adjoint
static void adjoint(std::vector< std::vector< float >> &A, std::vector< std::vector< float >> &adj)
Definition: matrixOps.hpp:93
DAI_SPAN_NAMESPACE_NAME::detail::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: span.hpp:167
dai::matrix::determinant
static float determinant(std::vector< std::vector< float >> &A, size_t n)
Definition: matrixOps.hpp:70
dai
Definition: CameraExposureOffset.hpp:6
dai::matrix::matInv
bool matInv(std::vector< std::vector< float >> &A, std::vector< std::vector< float >> &inverse)
Definition: matrixOps.hpp:121
dai::matrix::matMul
std::vector< std::vector< float > > matMul(std::vector< std::vector< float >> &firstMatrix, std::vector< std::vector< float >> &secondMatrix)
Matrix multiplication between two matrixs of shape (m x n) and (n x p) of type float....
Definition: matrixOps.hpp:15
dai::matrix::getCofactor
static void getCofactor(std::vector< std::vector< float >> &A, std::vector< std::vector< float >> &temp, size_t p, size_t q, size_t n)
Definition: matrixOps.hpp:46


depthai
Author(s): Martin Peterlin
autogenerated on Sat Mar 22 2025 02:58:19