// File: hitc8494[P]Matrix/matrix.cpp
// Function: Matrix::inv()
Matrix Matrix::inv(){
  if( _m == _n ){
    //*****Create a matching identity matrix to mirror our row operations.
    Matrix identity( _m, _n );
    for( uint i = 0; i < _m; i++ ) 
      identity._data[i][i] = 1;
    
    Matrix result = *this;
    //*****For each leading 1...
    for( uint i = 0; i < _m; i++ ){
      //*****Put a leading nonzero in the current row.
      if( result._data[i][i] == 0 ){
	for( uint j = i+1; j < _m; j++ ){
	  if( result._data[j][i] != 0 ){
	    identity.SWITCHRows( i+1, j+1 );
	    result.SWITCHRows( i+1, j+1 );
	    break;
	  }
	}
      }
      if( result._data[i][i] == 0 ){ //All 0s in the column. No inverse possible.
	_error = 1;
	return *this;
      }
      //*****Multiply current row by 1/value to give it a leading 1.
      double value = result._data[i][i];
      result.MULTIPLYRow( 1/value, i+1 );
      identity.MULTIPLYRow( 1/value, i+1 );
      //*****Clean the column so the leading 1 is the only number in the column.
      Matrix res( result, i );
      Matrix ide( identity, i );
      for( uint j = 0; j < _m; j++ ){
	if( i != j ){
	  double coeff = result._data[j][i];
	  result.ADDToRow( (res*-coeff), j+1 );
	  identity.ADDToRow( (ide*-coeff), j+1 );
	}
      }
    }
    return identity;
  }
  else {
    _error = 1;
    return *this;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movq %rdi, -0x1f0(%rbp)
movq %rdi, %rax
movq %rax, -0x1e8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rcx
movq %rcx, -0x1e0(%rbp)
movl 0x18(%rcx), %eax
cmpl 0x1c(%rcx), %eax
jne 0x4e81
movq -0x1e0(%rbp), %rax
movl 0x18(%rax), %esi
movl 0x1c(%rax), %edx
leaq -0x50(%rbp), %rdi
callq 0x2990
movl $0x0, -0x54(%rbp)
movq -0x1e0(%rbp), %rcx
movl -0x54(%rbp), %eax
cmpl 0x18(%rcx), %eax
jae 0x4a29
leaq -0x50(%rbp), %rdi
movl -0x54(%rbp), %eax
movl %eax, %esi
callq 0x5ba0
movq %rax, %rdi
movl -0x54(%rbp), %eax
movl %eax, %esi
callq 0x6360
movsd 0xa5ee(%rip), %xmm0     # 0xf008
movsd %xmm0, (%rax)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x49e8
movq -0x1e0(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0x2be0
jmp 0x4a3e
movl $0x0, -0xa8(%rbp)
movq -0x1e0(%rbp), %rcx
movl -0xa8(%rbp), %eax
cmpl 0x18(%rcx), %eax
jae 0x4e37
leaq -0x98(%rbp), %rdi
movl -0xa8(%rbp), %eax
movl %eax, %esi
callq 0x5ba0
movq %rax, %rdi
movl -0xa8(%rbp), %eax
movl %eax, %esi
callq 0x6360
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x4b74
jp 0x4b74
movl -0xa8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
movq -0x1e0(%rbp), %rcx
movl -0xac(%rbp), %eax
cmpl 0x18(%rcx), %eax
jae 0x4b72
leaq -0x98(%rbp), %rdi
movl -0xac(%rbp), %eax
movl %eax, %esi
callq 0x5ba0
movq %rax, %rdi
movl -0xa8(%rbp), %eax
movl %eax, %esi
callq 0x6360
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x4af3
jp 0x4af3
jmp 0x4b5c
movl -0xa8(%rbp), %esi
incl %esi
movl -0xac(%rbp), %edx
incl %edx
leaq -0x50(%rbp), %rdi
callq 0x3600
jmp 0x4b0e
movl -0xa8(%rbp), %esi
incl %esi
movl -0xac(%rbp), %edx
incl %edx
leaq -0x98(%rbp), %rdi
callq 0x3600
jmp 0x4b2c
jmp 0x4b72
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4e76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4e6a
jmp 0x4b5e
movl -0xac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
jmp 0x4aa8
jmp 0x4b74
leaq -0x98(%rbp), %rdi
movl -0xa8(%rbp), %eax
movl %eax, %esi
callq 0x5ba0
movq %rax, %rdi
movl -0xa8(%rbp), %eax
movl %eax, %esi
callq 0x6360
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x4bcf
jp 0x4bcf
movq -0x1e0(%rbp), %rsi
movq -0x1f0(%rbp), %rdi
movb $0x1, 0x31(%rsi)
callq 0x2be0
jmp 0x4bc0
movl $0x1, -0xb0(%rbp)
jmp 0x4e53
movl -0xa8(%rbp), %eax
movl %eax, %esi
leaq -0x98(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x5ba0
movq %rax, %rdi
movl -0xa8(%rbp), %eax
movl %eax, %esi
callq 0x6360
movq -0x1f8(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0xb8(%rbp)
movsd -0xb8(%rbp), %xmm1
movsd 0xa3eb(%rip), %xmm0     # 0xf008
movsd %xmm0, -0x200(%rbp)
divsd %xmm1, %xmm0
movl -0xa8(%rbp), %esi
incl %esi
callq 0x37c0
movsd -0x200(%rbp), %xmm0
movsd -0xb8(%rbp), %xmm1
divsd %xmm1, %xmm0
movl -0xa8(%rbp), %esi
incl %esi
leaq -0x50(%rbp), %rdi
callq 0x37c0
movq -0x1f8(%rbp), %rsi
movl -0xa8(%rbp), %edx
leaq -0xf8(%rbp), %rdi
callq 0x2b30
jmp 0x4c76
movl -0xa8(%rbp), %edx
leaq -0x138(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2b30
jmp 0x4c8e
movl $0x0, -0x13c(%rbp)
movq -0x1e0(%rbp), %rcx
movl -0x13c(%rbp), %eax
cmpl 0x18(%rcx), %eax
jae 0x4dfd
movl -0xa8(%rbp), %eax
cmpl -0x13c(%rbp), %eax
je 0x4de7
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0x98(%rbp), %rdi
callq 0x5ba0
movq %rax, %rdi
movl -0xa8(%rbp), %eax
movl %eax, %esi
callq 0x6360
movsd (%rax), %xmm0
movsd %xmm0, -0x148(%rbp)
movaps 0xa319(%rip), %xmm1     # 0xf010
movsd -0x148(%rbp), %xmm0
pxor %xmm1, %xmm0
movlpd %xmm0, -0x190(%rbp)
leaq -0x188(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
leaq -0x190(%rbp), %rdx
callq 0x32a0
jmp 0x4d27
movl -0x13c(%rbp), %edx
incl %edx
leaq -0x98(%rbp), %rdi
leaq -0x188(%rbp), %rsi
movq %rsi, -0x208(%rbp)
callq 0x3410
movq -0x208(%rbp), %rdi
callq 0x2c30
movaps 0xa2b4(%rip), %xmm1     # 0xf010
movsd -0x148(%rbp), %xmm0
pxor %xmm1, %xmm0
movlpd %xmm0, -0x1d8(%rbp)
leaq -0x1d0(%rbp), %rdi
leaq -0x138(%rbp), %rsi
leaq -0x1d8(%rbp), %rdx
callq 0x32a0
jmp 0x4d8c
movl -0x13c(%rbp), %edx
addl $0x1, %edx
leaq -0x50(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x3410
leaq -0x1d0(%rbp), %rdi
callq 0x2c30
jmp 0x4de7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4e29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x2c30
jmp 0x4e29
jmp 0x4de9
movl -0x13c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x13c(%rbp)
jmp 0x4c98
leaq -0x138(%rbp), %rdi
callq 0x2c30
leaq -0xf8(%rbp), %rdi
callq 0x2c30
movl -0xa8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa8(%rbp)
jmp 0x4a48
leaq -0xf8(%rbp), %rdi
callq 0x2c30
jmp 0x4e6a
movq -0x1f0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2be0
jmp 0x4e49
movl $0x1, -0xb0(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x2c30
leaq -0x50(%rbp), %rdi
callq 0x2c30
jmp 0x4e98
leaq -0x98(%rbp), %rdi
callq 0x2c30
leaq -0x50(%rbp), %rdi
callq 0x2c30
jmp 0x4ea8
movq -0x1e0(%rbp), %rsi
movq -0x1f0(%rbp), %rdi
movb $0x1, 0x31(%rsi)
callq 0x2be0
movq -0x1e8(%rbp), %rax
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
movq -0xa0(%rbp), %rdi
callq 0x22a0
nopw %cs:(%rax,%rax)