matrix.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #pragma once
  2. #include "math.h"
  3. /**
  4. * @brief 向量求模
  5. *
  6. * @param V 向量
  7. * @param n V的维度
  8. * @return float V的模值
  9. */
  10. static inline float Vector_GetNorm(const float *V, int n)
  11. {
  12. float norm = 0.0f;
  13. for (int i = 0; i < n; i++)
  14. norm += V[i] * V[i];
  15. norm = sqrtf(norm);
  16. return norm;
  17. }
  18. /**
  19. * @brief 向量 V 归一化
  20. * @param V 向量
  21. * @param n V的维度
  22. */
  23. static inline void Vector_Normalize(float *V, int n)
  24. {
  25. float norm = 0.0f;
  26. for (int i = 0; i < n; i++)
  27. norm += V[i] * V[i];
  28. norm = sqrtf(norm);
  29. if (norm > 1e-6f)
  30. {
  31. for (int i = 0; i < n; ++i)
  32. {
  33. V[i] /= norm;
  34. }
  35. }
  36. }
  37. static inline void Vector_ConstrainNorm(float *V, int n, float norm_max)
  38. {
  39. if (norm_max > 0)
  40. {
  41. float norm = Vector_GetNorm(V, n);
  42. if (norm > norm_max)
  43. {
  44. float ratio = norm_max / norm;
  45. for (int i = 0; i < n; ++i)
  46. {
  47. V[i] *= ratio;
  48. }
  49. }
  50. }
  51. }
  52. /**
  53. * @brief 向量点乘
  54. *
  55. * @param V1 向量
  56. * @param V2 向量
  57. * @param n V1 V1 的维数
  58. * @return float V1 * V2 的结果
  59. */
  60. static inline float Vector_DotProduct(const float *V1, const float *V2, int n)
  61. {
  62. float dotProduct = 0.0f;
  63. for (int i = 0; i < n; ++i)
  64. dotProduct += V1[i] * V2[i];
  65. return dotProduct;
  66. }
  67. /**
  68. * @brief 向量和实数乘
  69. *
  70. * @param V 向量
  71. * @param k 实数
  72. * @param n 向量维数
  73. */
  74. static inline void Vector_DotProductRealNum(float *V, float k, int n)
  75. {
  76. for (int i = 0; i < n; ++i)
  77. {
  78. V[i] *= k;
  79. }
  80. }
  81. /**
  82. * @brief 3 纬向量叉乘
  83. *
  84. * @param V1
  85. * @param V2
  86. * @param V V1 x V2
  87. */
  88. static inline void Vector_CrossProduct_3D(const float V1[3], const float V2[3], float *V)
  89. {
  90. V[0] = V1[1] * V2[2] - V1[2] * V2[1];
  91. V[1] = V1[2] * V2[0] - V1[0] * V2[2];
  92. V[2] = V1[0] * V2[1] - V1[1] * V2[0];
  93. }
  94. static inline void Matrix_Init(float *P, const float *datap, int m, int n)
  95. {
  96. for (int i = 0; i < m; i++)
  97. {
  98. for (int j = 0; j < n; j++)
  99. {
  100. P[i * n + j] = datap[i * n + j];
  101. }
  102. }
  103. }
  104. /**
  105. * @brief 矩阵转置
  106. *
  107. * @param M 要转置的矩阵
  108. * @param M_t 转置后的矩阵
  109. * @param m 矩阵行数
  110. * @param n 矩阵列数
  111. */
  112. static inline void Matrix_Transpose(float *M, float *M_t, int m, int n)
  113. {
  114. for (int i = 0; i < n; i++)
  115. {
  116. for (int j = 0; j < m; j++)
  117. {
  118. M_t[i * m + j] = M[j * n + i];
  119. }
  120. }
  121. }
  122. /**
  123. * @brief 矩阵乘法
  124. *
  125. * @param P 矩阵
  126. * @param Q 矩阵
  127. * @param R P * Q
  128. * @param l P的行数
  129. * @param m P的列数 M的行数
  130. * @param n M的列数
  131. */
  132. static inline void Matrix_Multiplication(const float *P, const float *Q, float *R, int l,
  133. int m, int n)
  134. {
  135. // 将 R 矩阵零化
  136. for (int i = 0; i < l; i++)
  137. {
  138. for (int j = 0; j < n; j++)
  139. {
  140. R[i * n + j] = 0.0f;
  141. }
  142. }
  143. // 计算 P * Q = R
  144. for (int i = 0; i < l; i++)
  145. {
  146. for (int j = 0; j < n; j++)
  147. {
  148. for (int k = 0; k < m; k++)
  149. {
  150. R[i * n + j] += P[i * m + k] * Q[k * n + j];
  151. }
  152. }
  153. }
  154. }
  155. /**
  156. * @brief 矩阵和实数乘
  157. *
  158. * @param P 矩阵
  159. * @param k 实数
  160. * @param m P的行数
  161. * @param n P的列数
  162. */
  163. static inline void Matrix_Multiplication_RealNum(float *P, float k, int m, int n)
  164. {
  165. for (int i = 0; i < m; i++)
  166. {
  167. for (int j = 0; j < n; j++)
  168. {
  169. P[i * n + j] *= k;
  170. }
  171. }
  172. }
  173. /**
  174. * @brief 方阵的迹
  175. *
  176. * @param P 方阵
  177. * @param m P的行列维度
  178. * @return float
  179. */
  180. static inline float Matrix_GetTrace(const float *P, int m)
  181. {
  182. float trace = 0.0f;
  183. for (int i = 0; i < m; ++i)
  184. trace += P[i * (m + 1)];
  185. return trace;
  186. }
  187. /**
  188. * @brief 矩阵按元素加
  189. *
  190. */
  191. static inline void Matrix_AdditionByElement(const float *P, const float *Q, float *R, int m,
  192. int n)
  193. {
  194. for (int i = 0; i < m; ++i)
  195. {
  196. for (int j = 0; j < n; ++j)
  197. {
  198. R[i * n + j] = P[i * n + j] + Q[i * n + j];
  199. }
  200. }
  201. }
  202. /**
  203. * @brief 矩阵按元数减
  204. *
  205. */
  206. static inline void Matrix_SubtractionByElement(const float *P, const float *Q, float *R,
  207. int m, int n)
  208. {
  209. for (int i = 0; i < m; ++i)
  210. {
  211. for (int j = 0; j < n; ++j)
  212. {
  213. R[i * n + j] = P[i * n + j] - Q[i * n + j];
  214. }
  215. }
  216. }