Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1. //usr/bin/cc -Wall -Wextra -Wpedantic matrix.c -o matrix && ./matrix; exit
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. #define EPSILON 1E-6
  8.  
  9. #define OK 0
  10. #define NO_INVERSE 1
  11.  
  12. typedef float matrix3[9];
  13. typedef float matrix4[16];
  14.  
  15. #define PRINT_MATRIX(matrix, size) { \
  16. uint8_t __i = 0; \
  17. while (__i < size * size) { \
  18. printf("%f ", matrix[__i]); \
  19. if (++__i % size == 0) printf("\n"); \
  20. } \
  21. }
  22.  
  23. // a b c
  24. // det(d e f) = a * (ei - hf) - b * (di - gf) + c * (dh - ge)
  25. // g h i
  26. float determinant3(matrix3 matrix) {
  27. return matrix[0] * (matrix[4] * matrix[8] - matrix[7] * matrix[5])
  28. - matrix[1] * (matrix[3] * matrix[8] - matrix[6] * matrix[5])
  29. + matrix[2] * (matrix[3] * matrix[7] - matrix[6] * matrix[4])
  30. ;
  31. }
  32.  
  33. /*
  34. * To compute an inverse:
  35. * 1. First check the determinant is not zero
  36. * 2. Compute the cofactor matrix
  37. * 3. Transpose the cofactor matrix to get the adjugate matrix
  38. * 4. Divide the adjugate matrix by the determinant
  39. */
  40. uint8_t inverse3(matrix3 matrix) {
  41. // Compute determinant to check if matrix is invertible
  42. float det = determinant3(matrix);
  43. if (abs(det) < EPSILON) return NO_INVERSE;
  44. // Compute adjugate matrix (transpose of the cofactors)
  45. matrix3 adjugate = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  46. adjugate[0] = (matrix[4] * matrix[8] - matrix[7] * matrix[5]);
  47. adjugate[3] = -(matrix[3] * matrix[8] - matrix[6] * matrix[5]);
  48. adjugate[6] = (matrix[3] * matrix[7] - matrix[6] * matrix[4]);
  49. adjugate[1] = -(matrix[1] * matrix[8] - matrix[7] * matrix[2]);
  50. adjugate[4] = (matrix[0] * matrix[8] - matrix[6] * matrix[2]);
  51. adjugate[7] = -(matrix[0] * matrix[7] - matrix[6] * matrix[1]);
  52. adjugate[2] = (matrix[1] * matrix[5] - matrix[4] * matrix[2]);
  53. adjugate[5] = -(matrix[0] * matrix[5] - matrix[3] * matrix[2]);
  54. adjugate[8] = (matrix[0] * matrix[4] - matrix[3] * matrix[1]);
  55. // Divide the cofactor matrix by the dererminant
  56. float idet = 1 / det;
  57. matrix[0] = adjugate[0] * idet;
  58. matrix[1] = adjugate[1] * idet;
  59. matrix[2] = adjugate[2] * idet;
  60. matrix[3] = adjugate[3] * idet;
  61. matrix[4] = adjugate[4] * idet;
  62. matrix[5] = adjugate[5] * idet;
  63. matrix[6] = adjugate[6] * idet;
  64. matrix[7] = adjugate[7] * idet;
  65. matrix[8] = adjugate[8] * idet;
  66.  
  67. return OK;
  68. }
  69.  
  70. void multiplication3(matrix3 lhs, matrix3 rhs) {
  71. matrix3 result = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  72. result[0] = lhs[0] * rhs[0] + lhs[1] * rhs[3] + lhs[2] * rhs[6];
  73. result[1] = lhs[0] * rhs[1] + lhs[1] * rhs[4] + lhs[2] * rhs[7];
  74. result[2] = lhs[0] * rhs[2] + lhs[1] * rhs[5] + lhs[2] * rhs[8];
  75. result[3] = lhs[3] * rhs[0] + lhs[4] * rhs[3] + lhs[5] * rhs[6];
  76. result[4] = lhs[3] * rhs[1] + lhs[4] * rhs[4] + lhs[5] * rhs[7];
  77. result[5] = lhs[3] * rhs[2] + lhs[4] * rhs[5] + lhs[5] * rhs[8];
  78. result[6] = lhs[6] * rhs[0] + lhs[7] * rhs[3] + lhs[8] * rhs[6];
  79. result[7] = lhs[6] * rhs[1] + lhs[7] * rhs[4] + lhs[8] * rhs[7];
  80. result[8] = lhs[6] * rhs[2] + lhs[7] * rhs[5] + lhs[8] * rhs[8];
  81. memcpy(&lhs[0], &result[0], sizeof(matrix3));
  82. }
  83.  
  84. /*
  85. * a b c d
  86. * e f g h
  87. * det(i j k l) = a * (f * (kp - ol) - g * (jp - nl) + h * (jo - nk))
  88. * m n o p - b * (e * (kp - ol) - g * (ip - ml) + h * (io - mk))
  89. * + c * (e * (jp - nl) - f * (ip - ml) + h * (in - mj))
  90. * - d * (e * (jo - nk) - f * (io - mk) + g * (in - mj))
  91. */
  92. float determinant4(matrix4 m) {
  93. return
  94. m[0] * (m[5] * (m[10] * m[15] - m[14] * m[11]) - m[6] * (m[9] * m[15] - m[13] * m[11]) + m[7] * (m[9] * m[14] - m[13] * m[10]))
  95. - m[1] * (m[4] * (m[10] * m[15] - m[14] * m[11]) - m[6] * (m[8] * m[15] - m[12] * m[11]) + m[7] * (m[8] * m[14] - m[12] * m[10]))
  96. + m[2] * (m[4] * ( m[9] * m[15] - m[13] * m[11]) - m[5] * (m[8] * m[15] - m[12] * m[11]) + m[7] * (m[8] * m[13] - m[12] * m[9]))
  97. - m[3] * (m[4] * ( m[9] * m[14] - m[13] * m[10]) - m[5] * (m[8] * m[14] - m[12] * m[10]) + m[6] * (m[8] * m[13] - m[12] * m[9]))
  98. ;
  99. }
  100.  
  101. uint8_t inverse4(matrix4 m) {
  102. // Compute determinant to check if matrix is invertible
  103. float det = determinant4(m);
  104. if (abs(det) < EPSILON) return NO_INVERSE;
  105. // Compute adjugate matrix (transpose of the cofactors)
  106. // a b c d A11 A12 A13 A14
  107. // cofactor(e f g h) = (A21 A22 A23 A24)
  108. // i j k l A31 A32 A33 A34
  109. // m n o p A41 A42 A43 A44
  110. //
  111. // A11 = a * (f * (k * p - o * l) - g * (j * p - n * l) + h * (j * o - n * k))
  112. // A12 = -b * (e * (k * p - o * l) - g * (i * p - m * l) + h * (i * o - m * k))
  113. // A13 = c * (e * (j * p - n * l) - f * (i * p - m * l) + h * (i * n - m * j))
  114. // A14 = -d * (e * (j * o - n * k) - f * (i * o - m * k) + g * (i * n - m * j))
  115. // A21 = e * (b * (k * p - o * l) - c * (j * p - n * l) + d * (j * o - n * k))
  116. // A22 = -f * (a * (k * p - o * l) - c * (i * p - m * l) + d * (i * o - m * k))
  117. // A23 = g * (a * (j * p - n * l) - b * (i * p - m * l) + d * (i * n - m * j))
  118. // A24 = -h * (a * (j * o - n * k) - b * (i * o - m * k) + c * (i * n - m * j))
  119. // A31 = i * (b * (g * p - o * h) - c * (f * p - n * h) + d * (f * o - n * g))
  120. // A32 = -j * (a * (g * p - o * h) - c * (e * p - m * h) + d * (e * o - m * g))
  121. // A33 = k * (a * (f * p - n * h) - b * (e * p - m * h) + d * (e * n - m * f))
  122. // A34 = -l * (a * (f * o - n * g) - b * (e * o - m * g) + c * (e * n - m * f))
  123. // A41 = m * (b * (g * l - k * h) - c * (f * l - j * h) + d * (f * k - j * g))
  124. // A42 = -n * (a * (g * l - k * h) - c * (e * l - i * h) + d * (e * k - i * g))
  125. // A43 = o * (a * (f * l - j * h) - b * (e * l - i * h) + d * (e * j - i * f))
  126. // A44 = -p * (a * (f * k - g * j) - b * (e * k - i * g) + c * (e * j - i * f))
  127. matrix4 adjugate = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  128. adjugate[0] = (m[5] * (m[10] * m[15] - m[14] * m[11]) - m[6] * (m[9] * m[15] - m[13] * m[11]) + m[7] * (m[9] * m[14] - m[13] * m[10]));
  129. adjugate[4] = -(m[4] * (m[10] * m[15] - m[14] * m[11]) - m[6] * (m[8] * m[15] - m[12] * m[11]) + m[7] * (m[8] * m[14] - m[12] * m[10]));
  130. adjugate[8] = (m[4] * ( m[9] * m[15] - m[13] * m[11]) - m[5] * (m[8] * m[15] - m[12] * m[11]) + m[7] * (m[8] * m[13] - m[12] * m[9]));
  131. adjugate[12] = -(m[4] * ( m[9] * m[14] - m[13] * m[10]) - m[5] * (m[8] * m[14] - m[12] * m[10]) + m[6] * (m[8] * m[13] - m[12] * m[9]));
  132. adjugate[1] = -(m[1] * (m[10] * m[15] - m[14] * m[11]) - m[2] * (m[9] * m[15] - m[13] * m[11]) + m[3] * (m[9] * m[14] - m[13] * m[10]));
  133. adjugate[5] = (m[0] * (m[10] * m[15] - m[14] * m[11]) - m[2] * (m[8] * m[15] - m[12] * m[11]) + m[3] * (m[8] * m[14] - m[12] * m[10]));
  134. adjugate[9] = -(m[0] * ( m[9] * m[15] - m[13] * m[11]) - m[1] * (m[8] * m[15] - m[12] * m[11]) + m[3] * (m[8] * m[13] - m[12] * m[9]));
  135. adjugate[13] = (m[0] * ( m[9] * m[14] - m[13] * m[10]) - m[1] * (m[8] * m[14] - m[12] * m[10]) + m[2] * (m[8] * m[13] - m[12] * m[9]));
  136. adjugate[2] = (m[1] * ( m[6] * m[15] - m[14] * m[7]) - m[2] * (m[5] * m[15] - m[13] * m[7]) + m[3] * (m[5] * m[14] - m[13] * m[6]));
  137. adjugate[6] = -(m[0] * ( m[6] * m[15] - m[14] * m[7]) - m[2] * (m[4] * m[15] - m[12] * m[7]) + m[3] * (m[4] * m[14] - m[12] * m[6]));
  138. adjugate[10] = (m[0] * ( m[5] * m[15] - m[13] * m[7]) - m[1] * (m[4] * m[15] - m[12] * m[7]) + m[3] * (m[4] * m[13] - m[12] * m[5]));
  139. adjugate[14] = -(m[0] * ( m[5] * m[14] - m[13] * m[6]) - m[1] * (m[4] * m[14] - m[12] * m[6]) + m[2] * (m[4] * m[13] - m[12] * m[5]));
  140. adjugate[3] = -(m[1] * ( m[6] * m[11] - m[10] * m[7]) - m[2] * (m[5] * m[11] - m[9] * m[7]) + m[3] * (m[5] * m[10] - m[9] * m[6]));
  141. adjugate[7] = (m[0] * ( m[6] * m[11] - m[10] * m[7]) - m[2] * (m[4] * m[11] - m[8] * m[7]) + m[3] * (m[4] * m[10] - m[8] * m[6]));
  142. adjugate[11] = -(m[0] * ( m[5] * m[11] - m[9] * m[7]) - m[1] * (m[4] * m[11] - m[8] * m[7]) + m[3] * (m[4] * m[9] - m[8] * m[5]));
  143. adjugate[15] = (m[0] * ( m[5] * m[10] - m[6] * m[9]) - m[1] * (m[4] * m[10] - m[8] * m[6]) + m[2] * (m[4] * m[9] - m[8] * m[5]));
  144. // Divide the cofactor matrix by the dererminant
  145. float idet = 1 / det;
  146. m[0] = adjugate[0] * idet;
  147. m[1] = adjugate[1] * idet;
  148. m[2] = adjugate[2] * idet;
  149. m[3] = adjugate[3] * idet;
  150. m[4] = adjugate[4] * idet;
  151. m[5] = adjugate[5] * idet;
  152. m[6] = adjugate[6] * idet;
  153. m[7] = adjugate[7] * idet;
  154. m[8] = adjugate[8] * idet;
  155. m[9] = adjugate[9] * idet;
  156. m[10] = adjugate[10] * idet;
  157. m[11] = adjugate[11] * idet;
  158. m[12] = adjugate[12] * idet;
  159. m[13] = adjugate[13] * idet;
  160. m[14] = adjugate[14] * idet;
  161. m[15] = adjugate[15] * idet;
  162.  
  163. return OK;
  164. }
  165.  
  166. void multiplication4(matrix4 lhs, matrix4 rhs) {
  167. matrix4 result = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  168. result[0] = lhs[0] * rhs[0] + lhs[1] * rhs[4] + lhs[2] * rhs[8] + lhs[3] * rhs[12];
  169. result[1] = lhs[0] * rhs[1] + lhs[1] * rhs[5] + lhs[2] * rhs[9] + lhs[3] * rhs[13];
  170. result[2] = lhs[0] * rhs[2] + lhs[1] * rhs[6] + lhs[2] * rhs[10] + lhs[3] * rhs[14];
  171. result[3] = lhs[0] * rhs[3] + lhs[1] * rhs[7] + lhs[2] * rhs[11] + lhs[3] * rhs[15];
  172. result[4] = lhs[4] * rhs[0] + lhs[5] * rhs[4] + lhs[6] * rhs[8] + lhs[7] * rhs[12];
  173. result[5] = lhs[4] * rhs[1] + lhs[5] * rhs[5] + lhs[6] * rhs[9] + lhs[7] * rhs[13];
  174. result[6] = lhs[4] * rhs[2] + lhs[5] * rhs[6] + lhs[6] * rhs[10] + lhs[7] * rhs[14];
  175. result[7] = lhs[4] * rhs[3] + lhs[5] * rhs[7] + lhs[6] * rhs[11] + lhs[7] * rhs[15];
  176. result[8] = lhs[8] * rhs[0] + lhs[9] * rhs[4] + lhs[10] * rhs[8] + lhs[11] * rhs[12];
  177. result[9] = lhs[8] * rhs[1] + lhs[9] * rhs[5] + lhs[10] * rhs[9] + lhs[11] * rhs[13];
  178. result[10] = lhs[8] * rhs[2] + lhs[9] * rhs[6] + lhs[10] * rhs[10] + lhs[11] * rhs[14];
  179. result[11] = lhs[8] * rhs[3] + lhs[9] * rhs[7] + lhs[10] * rhs[11] + lhs[11] * rhs[15];
  180. result[12] = lhs[12] * rhs[0] + lhs[13] * rhs[4] + lhs[14] * rhs[8] + lhs[15] * rhs[12];
  181. result[13] = lhs[12] * rhs[1] + lhs[13] * rhs[5] + lhs[14] * rhs[9] + lhs[15] * rhs[13];
  182. result[14] = lhs[12] * rhs[2] + lhs[13] * rhs[6] + lhs[14] * rhs[10] + lhs[15] * rhs[14];
  183. result[15] = lhs[12] * rhs[3] + lhs[13] * rhs[7] + lhs[14] * rhs[11] + lhs[15] * rhs[15];
  184. memcpy(&lhs[0], &result[0], sizeof(matrix4));
  185. }
  186.  
  187.  
  188. int main(/*int argc, char **argv*/) {
  189. matrix4 matrix = { 1, 2, 3, 4, 5, 6, 7, 2, 2, 10, 11, 12, 13, 14, 2, 15 };
  190. matrix4 matrixInverse;
  191. memcpy(&matrixInverse[0], &matrix[0], sizeof(matrix4));
  192.  
  193. if (inverse4(matrixInverse)) {
  194. fprintf(stderr, "cannot invert matrix\n");
  195. } else {
  196. multiplication4(matrixInverse, matrix);
  197. PRINT_MATRIX(matrixInverse, 4);
  198. }
  199.  
  200. return 0;
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement