9void mat_fshow(
float const *A,
int n,
char const *name)
11 printf(
"%s = [\n",name);
12 for(
int i = 0;i<n;i++)
14 for(
int j = 0;j<n;j++) printf(
" %+.4e",A[i+n*j]);
20void mat_show(
double const *A,
int n,
char const *name)
22 printf(
"%s = [\n",name);
23 for(
int i = 0;i<n;i++)
25 for(
int j = 0;j<n;j++) printf(
" %+.4e",A[i+n*j]);
41 M[0] = A[0]*B[0] + A[2]*B[1];
42 M[1] = A[1]*B[0] + A[3]*B[1];
43 M[2] = A[0]*B[2] + A[2]*B[3];
44 M[3] = A[1]*B[2] + A[3]*B[3];
45 for(
int k=0;k<4;k++) A[k]=M[k];
57 M[0] = A[0]*B[0] + A[2]*B[1];
58 M[1] = A[1]*B[0] + A[3]*B[1];
59 M[2] = A[0]*B[2] + A[2]*B[3];
60 M[3] = A[1]*B[2] + A[3]*B[3];
61 for(
int k=0;k<4;k++) B[k]=M[k];
71void mat2_vfms(
double *C,
double const *A,
double const *B)
74 M[0] = A[0]*B[0] + A[2]*B[1];
75 M[1] = A[1]*B[0] + A[3]*B[1];
76 M[2] = A[0]*B[2] + A[2]*B[3];
77 M[3] = A[1]*B[2] + A[3]*B[3];
78 for(
int k=0;k<4;k++) C[k]-=M[k];
95 double inv_det = 1.0/(M[0]*M[3]-M[1]*M[2]);
96 for(
int k=0;k<4;k++) invA[k]=inv_det*M[k];
111 vA[0] = _mm256_loadu_pd(A+ 0);
112 vA[1] = _mm256_loadu_pd(A+ 4);
113 vA[2] = _mm256_loadu_pd(A+ 8);
114 vA[3] = _mm256_loadu_pd(A+12);
119 __m256d vbj = _mm256_loadu_pd(B+4*j);
123 vAB[0] = vA[0]*_mm256_permute4x64_pd(vbj,0x00);
124 vAB[1] = vA[1]*_mm256_permute4x64_pd(vbj,0x55);
125 vAB[2] = vA[2]*_mm256_permute4x64_pd(vbj,0xAA);
126 vAB[3] = vA[3]*_mm256_permute4x64_pd(vbj,0xFF);
128 __m256d vz = vAB[0] + vAB[1] + vAB[2] + vAB[3];
131 _mm256_storeu_pd(A+4*j,vz);
147 vA[0] = _mm256_loadu_pd(A+ 0);
148 vA[1] = _mm256_loadu_pd(A+ 4);
149 vA[2] = _mm256_loadu_pd(A+ 8);
150 vA[3] = _mm256_loadu_pd(A+12);
155 __m256d vbj = _mm256_loadu_pd(B+4*j);
159 vAB[0] = vA[0]*_mm256_permute4x64_pd(vbj,0x00);
160 vAB[1] = vA[1]*_mm256_permute4x64_pd(vbj,0x55);
161 vAB[2] = vA[2]*_mm256_permute4x64_pd(vbj,0xAA);
162 vAB[3] = vA[3]*_mm256_permute4x64_pd(vbj,0xFF);
164 __m256d vz = vAB[0] + vAB[1] + vAB[2] + vAB[3];
167 _mm256_storeu_pd(B+4*j,vz);
180void mat4_vfms(
double *C,
double const *A,
double const *B)
184 vA[0] = _mm256_loadu_pd(A+ 0);
185 vA[1] = _mm256_loadu_pd(A+ 4);
186 vA[2] = _mm256_loadu_pd(A+ 8);
187 vA[3] = _mm256_loadu_pd(A+12);
192 __m256d vbj = _mm256_loadu_pd(B+4*j);
196 vAB[0] = vA[0]*_mm256_permute4x64_pd(vbj,0x00);
197 vAB[1] = vA[1]*_mm256_permute4x64_pd(vbj,0x55);
198 vAB[2] = vA[2]*_mm256_permute4x64_pd(vbj,0xAA);
199 vAB[3] = vA[3]*_mm256_permute4x64_pd(vbj,0xFF);
201 __m256d vz = vAB[0] + vAB[1] + vAB[2] + vAB[3];
204 vz = _mm256_loadu_pd(C+4*j) - vz;
207 _mm256_storeu_pd(C+4*j,vz);
225 for(
int k=0;k<16;k++) M[k] = A[k];
229 double scale=-1.0/M[5*k];
230 for(
int i=0;i<4;i++) M[i+4*k] *= i==k?0:scale;
234 for(
int i=0;i<4;i++) M[i+4*j] += i==k?0:M[i+4*k]*M[k+4*j];
237 for(
int j=0;j<4;j++) M[k+4*j] *= scale;
241 for(
int k=0;k<16;k++) invA[k] = M[k];
257 __m256d col0, col1, col2, col3;
258 __m256d row0, row1, row2, row3;
262 col0 = _mm256_load_pd(A+ 0);
263 col1 = _mm256_load_pd(A+ 4);
264 col2 = _mm256_load_pd(A+ 8);
265 col3 = _mm256_load_pd(A+12);
267 tmp1 = _mm256_unpacklo_pd(col0,col1);
268 row2 = _mm256_unpacklo_pd(col2,col3);
270 row0 = _mm256_permute2f128_pd(tmp1, row2, 0x20);
271 row2 = _mm256_permute2f128_pd(row2, tmp1, 0x13);
273 tmp1 = _mm256_unpackhi_pd(col0,col1);
274 row1 = _mm256_unpackhi_pd(col2,col3);
276 row3 = _mm256_permute2f128_pd(tmp1, row1, 0x13);
277 row1 = _mm256_permute2f128_pd(row1, tmp1, 0x20);
279 tmp1 = _mm256_mul_pd(row2, row3);
280 tmp1 = _mm256_permute_pd(tmp1, 0x05);
282 col0 = _mm256_mul_pd(row1, tmp1);
283 col1 = _mm256_mul_pd(row0, tmp1);
285 tmp1 = _mm256_permute4x64_pd(tmp1,0x4E);
287 col0 = _mm256_fmsub_pd(row1,tmp1,col0);
288 col1 = _mm256_fmsub_pd(row0,tmp1,col1);
289 col1 = _mm256_permute4x64_pd(col1,0x4E);
291 tmp1 = _mm256_mul_pd(row1, row2);
292 tmp1 = _mm256_permute_pd(tmp1, 0x05);
294 col0 = _mm256_fmadd_pd(row3,tmp1,col0);
295 col3 = _mm256_mul_pd(row0, tmp1);
297 tmp1 = _mm256_permute4x64_pd(tmp1,0x4E);
299 col0 = _mm256_fnmadd_pd(row3,tmp1,col0);
300 col3 = _mm256_fmsub_pd(row0,tmp1,col3);
301 col3 = _mm256_permute4x64_pd(col3,0x4E);
303 tmp1 = _mm256_mul_pd(_mm256_permute4x64_pd(row1, 0x4E), row3);
304 tmp1 = _mm256_permute_pd(tmp1, 0x05);
305 row2 = _mm256_permute4x64_pd(row2, 0x4E);
307 col0 = _mm256_fmadd_pd(row2,tmp1,col0);
308 col2 = _mm256_mul_pd(row0, tmp1);
310 tmp1 = _mm256_permute4x64_pd(tmp1,0x4E);
312 col0 = _mm256_fnmadd_pd(row2,tmp1,col0);
313 col2 = _mm256_fmsub_pd(row0,tmp1,col2);
314 col2 = _mm256_permute4x64_pd(col2,0x4E);
316 tmp1 = _mm256_mul_pd(row0, row1);
317 tmp1 = _mm256_permute_pd(tmp1, 0x05);
319 col2 = _mm256_fmadd_pd(row3,tmp1,col2);
320 col3 = _mm256_fmsub_pd(row2,tmp1,col3);
322 tmp1 = _mm256_permute4x64_pd(tmp1,0x4E);
324 col2 = _mm256_fmsub_pd(row3,tmp1,col2);
325 col3 = _mm256_fnmadd_pd(row2,tmp1,col3);
327 tmp1 = _mm256_mul_pd(row0, row3);
328 tmp1 = _mm256_permute_pd(tmp1, 0x05);
330 col1 = _mm256_fnmadd_pd(row2,tmp1,col1);
331 col2 = _mm256_fmadd_pd(row1,tmp1,col2);
333 tmp1 = _mm256_permute4x64_pd(tmp1,0x4E);
335 col1 = _mm256_fmadd_pd(row2,tmp1,col1);
336 col2 = _mm256_fnmadd_pd(row1,tmp1,col2);
338 tmp1 = _mm256_mul_pd(row0, row2);
339 tmp1 = _mm256_permute_pd(tmp1, 0x05);
341 col1 = _mm256_fmadd_pd(row3,tmp1,col1);
342 col3 = _mm256_fnmadd_pd(row1,tmp1,col3);
344 tmp1 = _mm256_permute4x64_pd(tmp1,0x4E);
346 col1 = _mm256_fnmadd_pd(row3,tmp1,col1);
347 col3 = _mm256_fmadd_pd(row1,tmp1,col3);
349 det = _mm256_mul_pd(row0, col0);
350 det = _mm256_add_pd(_mm256_permute4x64_pd(det, 0x4E), det);
351 det = _mm256_add_pd(_mm256_permute_pd(det, 0x05), det);
352 det = _mm256_permute4x64_pd(det,0x00);
353 det = _mm256_div_pd(_mm256_set1_pd(1.0),det);
355 _mm256_store_pd(invA+ 0,_mm256_mul_pd(det, col0));
356 _mm256_store_pd(invA+ 4,_mm256_mul_pd(det, col1));
357 _mm256_store_pd(invA+ 8,_mm256_mul_pd(det, col2));
358 _mm256_store_pd(invA+12,_mm256_mul_pd(det, col3));
374 __m128 col0, col1, col2, col3;
375 __m128 row0, row1, row2, row3;
379 col0 = _mm_load_ps(A+ 0);
380 col1 = _mm_load_ps(A+ 4);
381 col2 = _mm_load_ps(A+ 8);
382 col3 = _mm_load_ps(A+12);
384 tmp1 = _mm_unpacklo_ps(col0,col1);
385 row1 = _mm_unpacklo_ps(col2,col3);
387 row0 = _mm_shuffle_ps(tmp1, row1, 0x44);
388 row1 = _mm_shuffle_ps(row1, tmp1, 0xEE);
390 tmp1 = _mm_unpackhi_ps(col0,col1);
391 row3 = _mm_unpackhi_ps(col2,col3);
393 row2 = _mm_shuffle_ps(tmp1, row3, 0x44);
394 row3 = _mm_shuffle_ps(row3, tmp1, 0xEE);
396 tmp1 = _mm_mul_ps(row2, row3);
397 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
399 col0 = _mm_mul_ps(row1, tmp1);
400 col1 = _mm_mul_ps(row0, tmp1);
402 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
404 col0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), col0);
405 col1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), col1);
406 col1 = _mm_shuffle_ps(col1, col1, 0x4E);
408 tmp1 = _mm_mul_ps(row1, row2);
409 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
411 col0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), col0);
412 col3 = _mm_mul_ps(row0, tmp1);
414 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
416 col0 = _mm_sub_ps(col0, _mm_mul_ps(row3, tmp1));
417 col3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), col3);
418 col3 = _mm_shuffle_ps(col3, col3, 0x4E);
420 tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3);
421 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
422 row2 = _mm_shuffle_ps(row2, row2, 0x4E);
424 col0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), col0);
425 col2 = _mm_mul_ps(row0, tmp1);
427 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
429 col0 = _mm_sub_ps(col0, _mm_mul_ps(row2, tmp1));
430 col2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), col2);
431 col2 = _mm_shuffle_ps(col2, col2, 0x4E);
433 tmp1 = _mm_mul_ps(row0, row1);
434 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
436 col2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), col2);
437 col3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), col3);
439 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
441 col2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), col2);
442 col3 = _mm_sub_ps(col3, _mm_mul_ps(row2, tmp1));
444 tmp1 = _mm_mul_ps(row0, row3);
445 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
447 col1 = _mm_sub_ps(col1, _mm_mul_ps(row2, tmp1));
448 col2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), col2);
450 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
452 col1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), col1);
453 col2 = _mm_sub_ps(col2, _mm_mul_ps(row1, tmp1));
455 tmp1 = _mm_mul_ps(row0, row2);
456 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
458 col1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), col1);
459 col3 = _mm_sub_ps(col3, _mm_mul_ps(row1, tmp1));
461 tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
463 col1 = _mm_sub_ps(col1, _mm_mul_ps(row3, tmp1));
464 col3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), col3);
466 det = _mm_mul_ps(row0, col0);
467 det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det);
468 det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det);
469 tmp1 = _mm_rcp_ss(det);
471 det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1)));
472 det = _mm_shuffle_ps(det, det, 0x00);
474 _mm_store_ps(A+ 0,_mm_mul_ps(det, col0));
475 _mm_store_ps(A+ 4,_mm_mul_ps(det, col1));
476 _mm_store_ps(A+ 8,_mm_mul_ps(det, col2));
477 _mm_store_ps(A+12,_mm_mul_ps(det, col3));
void mat4_inv(double *invA, const double *A)
Matrix inverse for 4x4 matrix.
Definition: matvec.h:222
void mat4_lmul(double const *A, double *B)
In-place left matrix-matrix multiplication for 4x4 matrices.
Definition: matvec.h:143
void mat2_inv(double *invA, double const *A)
Matrix inverse for 2x2 matrix.
Definition: matvec.h:87
void mat2_lmul(double const *A, double *B)
In-place left matrix-matrix multiplication for 2x2 matrices.
Definition: matvec.h:54
void mat4_vfms(double *C, double const *A, double const *B)
Fused multiply-subtract for 4x4 matrices.
Definition: matvec.h:180
void mat4_vinv(double *invA, double const *A)
Matrix inverse for 4x4 matrix.
Definition: matvec.h:255
void mat4_rmul(double *A, double const *B)
In-place right matrix-matrix multiplication for 4x4 matrices.
Definition: matvec.h:107
void mat2_vfms(double *C, double const *A, double const *B)
Fused multiply-subtract for 2x2 matrices.
Definition: matvec.h:71
void mat2_rmul(double *A, double const *B)
In-place right matrix-matrix multiplication for 2x2 matrices.
Definition: matvec.h:38
void mat4_inv2(float *A)
Matrix inverse for 4x4 matrix.
Definition: matvec.h:372