1*219b2ee8SDavid du Colombier /* 2*219b2ee8SDavid du Colombier * ident(m) store identity matrix in m 3*219b2ee8SDavid du Colombier * matmul(a, b) matrix multiply a*=b 4*219b2ee8SDavid du Colombier * matmulr(a, b) matrix multiply a=b*a 5*219b2ee8SDavid du Colombier * determinant(m) returns det(m) 6*219b2ee8SDavid du Colombier * adjoint(m, minv) minv=adj(m) 7*219b2ee8SDavid du Colombier * invertmat(m, minv) invert matrix m, result in minv, returns det(m) 8*219b2ee8SDavid du Colombier * if m is singular, minv=adj(m) 9*219b2ee8SDavid du Colombier */ 10*219b2ee8SDavid du Colombier #include <u.h> 11*219b2ee8SDavid du Colombier #include <libc.h> 12*219b2ee8SDavid du Colombier #include <libg.h> 13*219b2ee8SDavid du Colombier #include <geometry.h> 14*219b2ee8SDavid du Colombier void ident(Matrix m){ 15*219b2ee8SDavid du Colombier register double *s=&m[0][0]; 16*219b2ee8SDavid du Colombier *s++=1;*s++=0;*s++=0;*s++=0; 17*219b2ee8SDavid du Colombier *s++=0;*s++=1;*s++=0;*s++=0; 18*219b2ee8SDavid du Colombier *s++=0;*s++=0;*s++=1;*s++=0; 19*219b2ee8SDavid du Colombier *s++=0;*s++=0;*s++=0;*s=1; 20*219b2ee8SDavid du Colombier } 21*219b2ee8SDavid du Colombier void matmul(Matrix a, Matrix b){ 22*219b2ee8SDavid du Colombier register i, j, k; 23*219b2ee8SDavid du Colombier double sum; 24*219b2ee8SDavid du Colombier Matrix tmp; 25*219b2ee8SDavid du Colombier for(i=0;i!=4;i++) for(j=0;j!=4;j++){ 26*219b2ee8SDavid du Colombier sum=0; 27*219b2ee8SDavid du Colombier for(k=0;k!=4;k++) 28*219b2ee8SDavid du Colombier sum+=a[i][k]*b[k][j]; 29*219b2ee8SDavid du Colombier tmp[i][j]=sum; 30*219b2ee8SDavid du Colombier } 31*219b2ee8SDavid du Colombier for(i=0;i!=4;i++) for(j=0;j!=4;j++) 32*219b2ee8SDavid du Colombier a[i][j]=tmp[i][j]; 33*219b2ee8SDavid du Colombier } 34*219b2ee8SDavid du Colombier void matmulr(Matrix a, Matrix b){ 35*219b2ee8SDavid du Colombier register i, j, k; 36*219b2ee8SDavid du Colombier double sum; 37*219b2ee8SDavid du Colombier Matrix tmp; 38*219b2ee8SDavid du Colombier for(i=0;i!=4;i++) for(j=0;j!=4;j++){ 39*219b2ee8SDavid du Colombier sum=0; 40*219b2ee8SDavid du Colombier for(k=0;k!=4;k++) 41*219b2ee8SDavid du Colombier sum+=b[i][k]*a[k][j]; 42*219b2ee8SDavid du Colombier tmp[i][j]=sum; 43*219b2ee8SDavid du Colombier } 44*219b2ee8SDavid du Colombier for(i=0;i!=4;i++) for(j=0;j!=4;j++) 45*219b2ee8SDavid du Colombier a[i][j]=tmp[i][j]; 46*219b2ee8SDavid du Colombier } 47*219b2ee8SDavid du Colombier /* 48*219b2ee8SDavid du Colombier * Return det(m) 49*219b2ee8SDavid du Colombier */ 50*219b2ee8SDavid du Colombier double determinant(Matrix m){ 51*219b2ee8SDavid du Colombier return m[0][0]*(m[1][1]*(m[2][2]*m[3][3]-m[2][3]*m[3][2])+ 52*219b2ee8SDavid du Colombier m[1][2]*(m[2][3]*m[3][1]-m[2][1]*m[3][3])+ 53*219b2ee8SDavid du Colombier m[1][3]*(m[2][1]*m[3][2]-m[2][2]*m[3][1])) 54*219b2ee8SDavid du Colombier -m[0][1]*(m[1][0]*(m[2][2]*m[3][3]-m[2][3]*m[3][2])+ 55*219b2ee8SDavid du Colombier m[1][2]*(m[2][3]*m[3][0]-m[2][0]*m[3][3])+ 56*219b2ee8SDavid du Colombier m[1][3]*(m[2][0]*m[3][2]-m[2][2]*m[3][0])) 57*219b2ee8SDavid du Colombier +m[0][2]*(m[1][0]*(m[2][1]*m[3][3]-m[2][3]*m[3][1])+ 58*219b2ee8SDavid du Colombier m[1][1]*(m[2][3]*m[3][0]-m[2][0]*m[3][3])+ 59*219b2ee8SDavid du Colombier m[1][3]*(m[2][0]*m[3][1]-m[2][1]*m[3][0])) 60*219b2ee8SDavid du Colombier -m[0][3]*(m[1][0]*(m[2][1]*m[3][2]-m[2][2]*m[3][1])+ 61*219b2ee8SDavid du Colombier m[1][1]*(m[2][2]*m[3][0]-m[2][0]*m[3][2])+ 62*219b2ee8SDavid du Colombier m[1][2]*(m[2][0]*m[3][1]-m[2][1]*m[3][0])); 63*219b2ee8SDavid du Colombier } 64*219b2ee8SDavid du Colombier /* 65*219b2ee8SDavid du Colombier * Store the adjoint (matrix of cofactors) of m in madj. 66*219b2ee8SDavid du Colombier * Works fine even if m and madj are the same matrix. 67*219b2ee8SDavid du Colombier */ 68*219b2ee8SDavid du Colombier void adjoint(Matrix m, Matrix madj){ 69*219b2ee8SDavid du Colombier double m00=m[0][0], m01=m[0][1], m02=m[0][2], m03=m[0][3]; 70*219b2ee8SDavid du Colombier double m10=m[1][0], m11=m[1][1], m12=m[1][2], m13=m[1][3]; 71*219b2ee8SDavid du Colombier double m20=m[2][0], m21=m[2][1], m22=m[2][2], m23=m[2][3]; 72*219b2ee8SDavid du Colombier double m30=m[3][0], m31=m[3][1], m32=m[3][2], m33=m[3][3]; 73*219b2ee8SDavid du Colombier madj[0][0]=m11*(m22*m33-m23*m32)+m21*(m13*m32-m12*m33)+m31*(m12*m23-m13*m22); 74*219b2ee8SDavid du Colombier madj[0][1]=m01*(m23*m32-m22*m33)+m21*(m02*m33-m03*m32)+m31*(m03*m22-m02*m23); 75*219b2ee8SDavid du Colombier madj[0][2]=m01*(m12*m33-m13*m32)+m11*(m03*m32-m02*m33)+m31*(m02*m13-m03*m12); 76*219b2ee8SDavid du Colombier madj[0][3]=m01*(m13*m22-m12*m23)+m11*(m02*m23-m03*m22)+m21*(m03*m12-m02*m13); 77*219b2ee8SDavid du Colombier madj[1][0]=m10*(m23*m32-m22*m33)+m20*(m12*m33-m13*m32)+m30*(m13*m22-m12*m23); 78*219b2ee8SDavid du Colombier madj[1][1]=m00*(m22*m33-m23*m32)+m20*(m03*m32-m02*m33)+m30*(m02*m23-m03*m22); 79*219b2ee8SDavid du Colombier madj[1][2]=m00*(m13*m32-m12*m33)+m10*(m02*m33-m03*m32)+m30*(m03*m12-m02*m13); 80*219b2ee8SDavid du Colombier madj[1][3]=m00*(m12*m23-m13*m22)+m10*(m03*m22-m02*m23)+m20*(m02*m13-m03*m12); 81*219b2ee8SDavid du Colombier madj[2][0]=m10*(m21*m33-m23*m31)+m20*(m13*m31-m11*m33)+m30*(m11*m23-m13*m21); 82*219b2ee8SDavid du Colombier madj[2][1]=m00*(m23*m31-m21*m33)+m20*(m01*m33-m03*m31)+m30*(m03*m21-m01*m23); 83*219b2ee8SDavid du Colombier madj[2][2]=m00*(m11*m33-m13*m31)+m10*(m03*m31-m01*m33)+m30*(m01*m13-m03*m11); 84*219b2ee8SDavid du Colombier madj[2][3]=m00*(m13*m21-m11*m23)+m10*(m01*m23-m03*m21)+m20*(m03*m11-m01*m13); 85*219b2ee8SDavid du Colombier madj[3][0]=m10*(m22*m31-m21*m32)+m20*(m11*m32-m12*m31)+m30*(m12*m21-m11*m22); 86*219b2ee8SDavid du Colombier madj[3][1]=m00*(m21*m32-m22*m31)+m20*(m02*m31-m01*m32)+m30*(m01*m22-m02*m21); 87*219b2ee8SDavid du Colombier madj[3][2]=m00*(m12*m31-m11*m32)+m10*(m01*m32-m02*m31)+m30*(m02*m11-m01*m12); 88*219b2ee8SDavid du Colombier madj[3][3]=m00*(m11*m22-m12*m21)+m10*(m02*m21-m01*m22)+m20*(m01*m12-m02*m11); 89*219b2ee8SDavid du Colombier } 90*219b2ee8SDavid du Colombier /* 91*219b2ee8SDavid du Colombier * Store the inverse of m in minv. 92*219b2ee8SDavid du Colombier * If m is singular, minv is instead its adjoint. 93*219b2ee8SDavid du Colombier * Returns det(m). 94*219b2ee8SDavid du Colombier * Works fine even if m and minv are the same matrix. 95*219b2ee8SDavid du Colombier */ 96*219b2ee8SDavid du Colombier double invertmat(Matrix m, Matrix minv){ 97*219b2ee8SDavid du Colombier double d, dinv; 98*219b2ee8SDavid du Colombier int i, j; 99*219b2ee8SDavid du Colombier d=determinant(m); 100*219b2ee8SDavid du Colombier adjoint(m, minv); 101*219b2ee8SDavid du Colombier if(d!=0.){ 102*219b2ee8SDavid du Colombier dinv=1./d; 103*219b2ee8SDavid du Colombier for(i=0;i!=4;i++) for(j=0;j!=4;j++) minv[i][j]*=dinv; 104*219b2ee8SDavid du Colombier } 105*219b2ee8SDavid du Colombier return d; 106*219b2ee8SDavid du Colombier } 107