def _determinant_euclidean_asm_col_major(col0, col1, col2): tmp0 = pyasm.Register() det = pyasm.Register() # Do some multiplications & subtractions in parallel with SIMD instructions: tmp0.xyz = pyasm.mul(col0.zxy, col1.yzx) # m0.z*m1.y, m0.x*m1.z, m0.y*m1.x tmp0.xyz = pyasm.mad( col0.yzx, col1.zxy, -tmp0.xyz ) # m0.y*m1.z - m0.z*m1.y, m0.z*m1.x - m0.x*m1.z, m0.x*m1.y - m0.y*m1.x # Now the multiplications: tmp0.xyz = pyasm.mul(tmp0.xyz, col2.xyz) # Sum it together to get the determinant: det.x = pyasm.add(tmp0.x, tmp0.y) det.x = pyasm.add(det.x, tmp0.z) return det
def _inverse_euclidean_asm_col_major(col0, col1, col2, det): ''' Performs a matrix inverse in a manner as would be done in assembly. Note that the input matrix is in column-major order, but the resulting inverted matrix will be in ROW-major order. ''' std_consts = pyasm.Register([0, 1, 0.0625, 0.5]) dst0 = pyasm.Register() dst1 = pyasm.Register() dst2 = pyasm.Register() dst3 = pyasm.Register() # 1st row, simplifying by assuimg the 4th column 0,0,0,1 # dst0.x = (m1.y*m2.z - m1.z*m2.y) # dst0.y = (m1.z*m2.x - m1.x*m2.z) # dst0.z = (m1.x*m2.y - m1.y*m2.x) # dst0.w = 0 dst0.xyz = pyasm.mul(col1.zxy, col2.yzx) dst0.xyz = pyasm.mad(col1.yzx, col2.zxy, -dst0.xyz) # 2nd row # dst1.x = (col0.z*m2.y - col0.y*m2.z) # dst1.y = (col0.x*m2.z - col0.z*m2.x) # dst1.z = (col0.y*m2.x - col0.x*m2.y) # dst1.w = 0 dst1.xyz = pyasm.mul(col0.yzx, col2.zxy) dst1.xyz = pyasm.mad(col0.zxy, col2.yzx, -dst1.xyz) # 3nd row # dst2.x = (col0.y*m1.z - col0.z*m1.y) # dst2.y = (col0.z*m1.x - col0.x*m1.z) # dst2.z = (col0.x*m1.y - col0.y*m1.x) # dst2.w = 0 dst2.xyz = pyasm.mul(col0.zxy, col1.yzx) dst2.xyz = pyasm.mad(col0.yzx, col1.zxy, -dst2.xyz) # 4th row # dst3.x = - col0.w*dst0.x - col1.w*dst1.x - col2.w*dst2.x # dst3.y = - col0.w*dst0.y - col1.w*dst1.y - col2.w*dst2.y # dst3.z = - col0.w*dst0.z - col1.w*dst1.z - col2.w*dst2.z # dst3.w = col0.x*dst0.x + col1.x*dst1.x + col2.x*dst2.x (always 1?) dst3.xyzw = pyasm.mul(col0.wwwx, dst0.xyzx) dst3.xyzw = pyasm.mad(col1.wwwx, dst1.xyzx, dst3.xyzw) dst3.xyzw = pyasm.mad(col2.wwwx, dst2.xyzx, dst3.xyzw) dst3.xyz = pyasm.mov(-dst3) # Multiply against 1/determinant (and zero out 4th column): inv_det = pyasm.rcp(det.x) inv_det.y = pyasm.mov(std_consts.x) dst0 = pyasm.mul(dst0, inv_det.xxxy) dst1 = pyasm.mul(dst1, inv_det.xxxy) dst2 = pyasm.mul(dst2, inv_det.xxxy) dst3 = pyasm.mul(dst3, inv_det.xxxx) # Note that this matrix has been transposed and is now in ROW major order! return (dst0, dst1, dst2, dst3)
def col_major_regs(m): r1 = pyasm.Register(m.T.tolist()[0]) r2 = pyasm.Register(m.T.tolist()[1]) r3 = pyasm.Register(m.T.tolist()[2]) r4 = pyasm.Register(m.T.tolist()[3]) return (r1, r2, r3, r4)