// File: /workspace/github_cpp_makefile_star2_O1/DavidLBruce[P]sim3dof/Matrix/build/../../Matrix/src/Matrix.cpp
// Function: Matrix::Det()
double Matrix::Det()
{
  if (rows != cols)
  {
    throw(DIMERR());
  }

  double cofactor;
  int    col(0);
  bool   done(false);
  int    maxZeroRow(0);
  double minor(0.0);
  int    prevZeroCnt(0);
  double result(0.0);
  int    row(0);
  double sign(0.0);
  int    zeroCnt(0);

  //
  // Handle trivial cases.
  //
  if (rows == 1)
  {
    result = *pData;
    done = true;
  }

  if (!done)
  {
    if (rows == 2)
    {
      result = (*this)[0][0] * (*this)[1][1] - (*this)[0][1] * (*this)[1][0];
      done = true;
    }
  }

  if (!done)
  {
    //
    // Find the row with the most zero elements.
    //
    for (row = 0; row < rows; ++row)
    {
      zeroCnt = 0.0;
      for (col = 0; col < cols; ++col)
      {
        if (WithinTolerance((*this)[row][col],  0.0))
        {
          ++zeroCnt;
        }
      }
      if (zeroCnt == cols)
      {
        result = 0.0;
        done = true;
        break;  // exit loop for (row = 0; row < rows; ++row)
      }
      else if (zeroCnt > prevZeroCnt)
      {
        maxZeroRow = row;
        prevZeroCnt = zeroCnt;
      }
    }
    
    row = maxZeroRow;

  } // end if (!done)

  //
  // Sum the products of the selected row elements and their cofactors.
  //
  if (!done)
  {  
    for (col = 0; col < cols; ++col)
    {
      if (!WithinTolerance(pData[row*cols+col], 0.0))
      { 
        //
        // Odd powers of -1 are negative 1, even powers are positive 1.
        //
        sign = (row + col) % 2 == 0 ? 1.0 : -1.0;

        minor = Minor(row, col);
    
        cofactor = sign * pData[row*cols+col] * minor;
    
        result += cofactor;
      }
    }
  }  // end if (!done)

  return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl 0x8(%rdi), %eax
cmpl (%rdi), %eax
jne 0x14e72
movq %rdi, %rbx
cmpl $0x1, %eax
jne 0x14c7f
movq 0x10(%rbx), %rcx
movsd (%rcx), %xmm0
movsd %xmm0, -0x30(%rbp)
movb $0x1, %cl
jmp 0x14c8a
xorpd %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
xorl %ecx, %ecx
cmpl $0x2, %eax
setne %al
orb %cl, %al
jne 0x14cfd
movq %rbx, %rdi
xorl %esi, %esi
callq 0x13b48
movsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
movq %rbx, %rdi
movl $0x1, %esi
callq 0x13b48
movsd -0x30(%rbp), %xmm0
mulsd 0x8(%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x13b48
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movq %rbx, %rdi
movl $0x1, %esi
callq 0x13b48
movsd -0x38(%rbp), %xmm1
mulsd (%rax), %xmm1
movsd -0x30(%rbp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movb $0x1, %cl
xorl %edx, %edx
testb %cl, %cl
jne 0x14d95
cmpl $0x0, 0x8(%rbx)
jle 0x14d95
movl %ecx, -0x40(%rbp)
xorl %r14d, %r14d
xorl %r13d, %r13d
xorl %edx, %edx
movl (%rbx), %eax
movl $0x0, %r12d
testl %eax, %eax
jle 0x14d6c
movl %edx, -0x38(%rbp)
xorl %r15d, %r15d
xorl %r12d, %r12d
movq %rbx, %rdi
movl %r14d, %esi
callq 0x13b48
movapd 0x185c(%rip), %xmm1     # 0x165a0
movsd (%rax,%r15,8), %xmm0
andpd %xmm1, %xmm0
movsd 0x385a(%rip), %xmm1     # 0x185b0
ucomisd %xmm0, %xmm1
sbbl $-0x1, %r12d
incq %r15
movslq (%rbx), %rax
cmpq %rax, %r15
jl 0x14d31
movl -0x38(%rbp), %edx
cmpl %eax, %r12d
je 0x14d8a
cmpl %r13d, %r12d
cmovgl %r14d, %edx
cmovgl %r12d, %r13d
incl %r14d
cmpl 0x8(%rbx), %r14d
jl 0x14d1c
movl -0x40(%rbp), %ecx
jmp 0x14d95
xorpd %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
movb $0x1, %cl
testb %cl, %cl
jne 0x14e5e
movl (%rbx), %eax
testl %eax, %eax
jle 0x14e5e
xorps %xmm0, %xmm0
cvtsi2sd %edx, %xmm0
movsd %xmm0, -0x38(%rbp)
movl %edx, %ecx
movq %rcx, -0x40(%rbp)
xorl %r12d, %r12d
movapd 0x17dc(%rip), %xmm1     # 0x165a0
movsd 0x37e4(%rip), %xmm2     # 0x185b0
movslq %edx, %r13
movq 0x10(%rbx), %rcx
imull %edx, %eax
cltq
addq %r12, %rax
movsd (%rcx,%rax,8), %xmm0
andpd %xmm1, %xmm0
ucomisd %xmm0, %xmm2
jae 0x14e50
movl %edx, %r14d
movq -0x40(%rbp), %rax
leal (%rax,%r12), %r15d
xorps %xmm1, %xmm1
cvtsi2sd %r12d, %xmm1
movq %rbx, %rdi
movsd -0x38(%rbp), %xmm0
callq 0x14e9c
movslq (%rbx), %rax
imulq %r13, %rax
addq %r12, %rax
movq 0x10(%rbx), %rcx
movsd (%rcx,%rax,8), %xmm1
testb $0x1, %r15b
je 0x14e2b
xorpd 0x11e5(%rip), %xmm1     # 0x16010
mulsd %xmm1, %xmm0
movsd -0x30(%rbp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, -0x30(%rbp)
movl %r14d, %edx
movapd 0x1758(%rip), %xmm1     # 0x165a0
movsd 0x3760(%rip), %xmm2     # 0x185b0
movl (%rbx), %eax
incq %r12
cmpl %eax, %r12d
jl 0x14dcf
movsd -0x30(%rbp), %xmm0
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x8, %edi
callq 0x30b0
leaq 0x8ec5(%rip), %rcx      # 0x1dd48
movq %rcx, (%rax)
leaq 0x8e63(%rip), %rsi      # 0x1dcf0
movq 0x914c(%rip), %rdx      # 0x1dfe0
movq %rax, %rdi
callq 0x32b0