// File: Luthaf[P]zeopp/./Eigen/src/QR/ColPivHouseholderQR.h
// Function: Eigen::ColPivHouseholderQR<Eigen::Matrix<double, 3, 3, 0, 3, 3>>::compute(Eigen::Matrix<double, 3, 3, 0, 3, 3> const&)
ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
  check_template_parameters();
  
  using std::abs;
  Index rows = matrix.rows();
  Index cols = matrix.cols();
  Index size = matrix.diagonalSize();
  
  // the column permutation is stored as int indices, so just to be sure:
  eigen_assert(cols<=NumTraits<int>::highest());

  m_qr = matrix;
  m_hCoeffs.resize(size);

  m_temp.resize(cols);

  m_colsTranspositions.resize(matrix.cols());
  Index number_of_transpositions = 0;

  m_colSqNorms.resize(cols);
  for(Index k = 0; k < cols; ++k)
    m_colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();

  RealScalar threshold_helper = m_colSqNorms.maxCoeff() * numext::abs2(NumTraits<Scalar>::epsilon()) / RealScalar(rows);

  m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
  m_maxpivot = RealScalar(0);

  for(Index k = 0; k < size; ++k)
  {
    // first, we look up in our table m_colSqNorms which column has the biggest squared norm
    Index biggest_col_index;
    RealScalar biggest_col_sq_norm = m_colSqNorms.tail(cols-k).maxCoeff(&biggest_col_index);
    biggest_col_index += k;

    // since our table m_colSqNorms accumulates imprecision at every step, we must now recompute
    // the actual squared norm of the selected column.
    // Note that not doing so does result in solve() sometimes returning inf/nan values
    // when running the unit test with 1000 repetitions.
    biggest_col_sq_norm = m_qr.col(biggest_col_index).tail(rows-k).squaredNorm();

    // we store that back into our table: it can't hurt to correct our table.
    m_colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm;

    // Track the number of meaningful pivots but do not stop the decomposition to make
    // sure that the initial matrix is properly reproduced. See bug 941.
    if(m_nonzero_pivots==size && biggest_col_sq_norm < threshold_helper * RealScalar(rows-k))
      m_nonzero_pivots = k;

    // apply the transposition to the columns
    m_colsTranspositions.coeffRef(k) = biggest_col_index;
    if(k != biggest_col_index) {
      m_qr.col(k).swap(m_qr.col(biggest_col_index));
      std::swap(m_colSqNorms.coeffRef(k), m_colSqNorms.coeffRef(biggest_col_index));
      ++number_of_transpositions;
    }

    // generate the householder vector, store it below the diagonal
    RealScalar beta;
    m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);

    // apply the householder transformation to the diagonal coefficient
    m_qr.coeffRef(k,k) = beta;

    // remember the maximum absolute value of diagonal coefficients
    if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta);

    // apply the householder transformation
    m_qr.bottomRightCorner(rows-k, cols-k-1)
        .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));

    // update our table of squared norms of the columns
    m_colSqNorms.tail(cols-k-1) -= m_qr.row(k).tail(cols-k-1).cwiseAbs2();
  }

  m_colsPermutation.setIdentity(PermIndexType(cols));
  for(PermIndexType k = 0; k < size/*m_nonzero_pivots*/; ++k)
    m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k)));

  m_det_pq = (number_of_transpositions%2) ? -1 : 1;
  m_isInitialized = true;

  return *this;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x370, %rsp            # imm = 0x370
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x320(%rbp)
callq 0x176d30
movq -0x10(%rbp), %rdi
callq 0x175dc0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rdi
callq 0x175df0
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x176d40
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x318(%rbp)
callq 0x176d80
movl %eax, %ecx
movq -0x318(%rbp), %rax
movslq %ecx, %rcx
cmpq %rcx, %rax
jg 0x17625d
jmp 0x17627c
leaq 0x89c24(%rip), %rdi     # 0x1ffe88
leaq 0x89c3d(%rip), %rsi     # 0x1ffea8
movl $0x1b7, %edx            # imm = 0x1B7
leaq 0x89c56(%rip), %rcx     # 0x1ffecd
callq 0x5320
movq -0x320(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x176d90
movq -0x320(%rbp), %rdi
addq $0x48, %rdi
movq -0x28(%rbp), %rsi
callq 0x176dc0
movq -0x320(%rbp), %rdi
addq $0x88, %rdi
movq -0x20(%rbp), %rsi
callq 0x176e40
movq -0x320(%rbp), %rax
addq $0x70, %rax
movq %rax, -0x328(%rbp)
movq -0x10(%rbp), %rdi
callq 0x175df0
movq -0x328(%rbp), %rdi
movq %rax, %rsi
callq 0x176ec0
movq -0x320(%rbp), %rdi
movq $0x0, -0x30(%rbp)
addq $0xa0, %rdi
movq -0x20(%rbp), %rsi
callq 0x176e40
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x20(%rbp), %rax
jge 0x176368
movq -0x320(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq -0x58(%rbp), %rdi
callq 0x176f40
leaq -0x58(%rbp), %rdi
callq 0x176f90
movq -0x320(%rbp), %rdi
movsd %xmm0, -0x330(%rbp)
addq $0xa0, %rdi
movq -0x38(%rbp), %rsi
callq 0x176fd0
movsd -0x330(%rbp), %xmm0
movsd %xmm0, (%rax)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x176308
movq -0x320(%rbp), %rdi
addq $0xa0, %rdi
callq 0x177000
movsd %xmm0, -0x338(%rbp)
callq 0x177050
movsd %xmm0, -0x68(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x177030
movq -0x320(%rbp), %rax
movaps %xmm0, %xmm1
movsd -0x338(%rbp), %xmm0
mulsd %xmm1, %xmm0
cvtsi2sdq -0x18(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movq -0x28(%rbp), %rcx
movq %rcx, 0xd0(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, 0xc8(%rax)
movq $0x0, -0x70(%rbp)
movq -0x70(%rbp), %rax
cmpq -0x28(%rbp), %rax
jge 0x1767ba
movq -0x320(%rbp), %rsi
addq $0xa0, %rsi
movq -0x20(%rbp), %rdx
subq -0x70(%rbp), %rdx
leaq -0xa8(%rbp), %rdi
callq 0x177060
leaq -0xa8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x1770c0
movq -0x320(%rbp), %rsi
movsd %xmm0, -0x80(%rbp)
movq -0x70(%rbp), %rax
addq -0x78(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdx
leaq -0x108(%rbp), %rdi
callq 0x176f40
movq -0x18(%rbp), %rdx
subq -0x70(%rbp), %rdx
leaq -0xe8(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x177100
leaq -0xe8(%rbp), %rdi
callq 0x177160
movq -0x320(%rbp), %rdi
movsd %xmm0, -0x80(%rbp)
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x340(%rbp)
addq $0xa0, %rdi
movq -0x78(%rbp), %rsi
callq 0x176fd0
movsd -0x340(%rbp), %xmm0
movq %rax, %rcx
movq -0x320(%rbp), %rax
movsd %xmm0, (%rcx)
movq 0xd0(%rax), %rax
cmpq -0x28(%rbp), %rax
jne 0x1764e7
movsd -0x80(%rbp), %xmm1
movsd -0x60(%rbp), %xmm0
movq -0x18(%rbp), %rax
subq -0x70(%rbp), %rax
cvtsi2sd %rax, %xmm2
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1764e7
movq -0x320(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, 0xd0(%rax)
movq -0x320(%rbp), %rdi
movq -0x78(%rbp), %rax
movq %rax, -0x348(%rbp)
addq $0x70, %rdi
movq -0x70(%rbp), %rsi
callq 0x1771a0
movq -0x348(%rbp), %rcx
movq %rcx, (%rax)
movq -0x70(%rbp), %rax
cmpq -0x78(%rbp), %rax
je 0x1765b1
movq -0x320(%rbp), %rsi
movq -0x70(%rbp), %rdx
leaq -0x128(%rbp), %rdi
callq 0x176f40
movq -0x320(%rbp), %rsi
movq -0x78(%rbp), %rdx
leaq -0x148(%rbp), %rdi
callq 0x176f40
leaq -0x128(%rbp), %rdi
leaq -0x148(%rbp), %rsi
xorl %edx, %edx
callq 0x1771d0
movq -0x320(%rbp), %rdi
addq $0xa0, %rdi
movq -0x70(%rbp), %rsi
callq 0x176fd0
movq -0x320(%rbp), %rdi
movq %rax, -0x350(%rbp)
addq $0xa0, %rdi
movq -0x78(%rbp), %rsi
callq 0x176fd0
movq -0x350(%rbp), %rdi
movq %rax, %rsi
callq 0x72500
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movq -0x320(%rbp), %rsi
movq -0x70(%rbp), %rdx
leaq -0x1b0(%rbp), %rdi
callq 0x176f40
movq -0x18(%rbp), %rdx
subq -0x70(%rbp), %rdx
leaq -0x190(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x177100
movq -0x320(%rbp), %rdi
addq $0x48, %rdi
movq -0x70(%rbp), %rsi
callq 0x175b50
movq %rax, %rsi
leaq -0x190(%rbp), %rdi
leaq -0x150(%rbp), %rdx
callq 0x177220
movq -0x320(%rbp), %rdi
movsd -0x150(%rbp), %xmm0
movsd %xmm0, -0x358(%rbp)
movq -0x70(%rbp), %rsi
movq -0x70(%rbp), %rdx
callq 0x175d50
movsd -0x358(%rbp), %xmm0
movsd %xmm0, (%rax)
movsd -0x150(%rbp), %xmm0
callq 0x162b0
movq -0x320(%rbp), %rax
ucomisd 0xc8(%rax), %xmm0
jbe 0x176677
movsd -0x150(%rbp), %xmm0
callq 0x162b0
movq -0x320(%rbp), %rax
movsd %xmm0, 0xc8(%rax)
movq -0x320(%rbp), %rsi
movq -0x18(%rbp), %rdx
subq -0x70(%rbp), %rdx
movq -0x20(%rbp), %rcx
subq -0x70(%rbp), %rcx
subq $0x1, %rcx
leaq -0x1d8(%rbp), %rdi
callq 0x177290
movq -0x320(%rbp), %rsi
movq -0x70(%rbp), %rdx
leaq -0x238(%rbp), %rdi
callq 0x176f40
movq -0x18(%rbp), %rdx
subq -0x70(%rbp), %rdx
subq $0x1, %rdx
leaq -0x218(%rbp), %rdi
leaq -0x238(%rbp), %rsi
callq 0x177100
movq -0x320(%rbp), %rdi
addq $0x48, %rdi
movq -0x70(%rbp), %rsi
callq 0x175b50
movq -0x320(%rbp), %rdi
movq %rax, -0x360(%rbp)
addq $0x88, %rdi
movq -0x70(%rbp), %rsi
addq $0x1, %rsi
callq 0x176fd0
movq -0x360(%rbp), %rdx
movq %rax, %rcx
leaq -0x1d8(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0x177310
movq -0x320(%rbp), %rsi
movq -0x70(%rbp), %rdx
leaq -0x2e0(%rbp), %rdi
callq 0x177520
movq -0x20(%rbp), %rdx
subq -0x70(%rbp), %rdx
subq $0x1, %rdx
leaq -0x2c0(%rbp), %rdi
leaq -0x2e0(%rbp), %rsi
callq 0x177570
leaq -0x280(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x1775d0
movq -0x320(%rbp), %rsi
addq $0xa0, %rsi
movq -0x20(%rbp), %rdx
subq -0x70(%rbp), %rdx
subq $0x1, %rdx
leaq -0x308(%rbp), %rdi
callq 0x177060
leaq -0x308(%rbp), %rdi
leaq -0x280(%rbp), %rsi
callq 0x177620
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0x1763d9
movq -0x320(%rbp), %rdi
addq $0x60, %rdi
movq -0x20(%rbp), %rax
movl %eax, %esi
callq 0x177680
movl $0x0, -0x30c(%rbp)
movslq -0x30c(%rbp), %rax
cmpq -0x28(%rbp), %rax
jge 0x176840
movq -0x320(%rbp), %rdi
movq %rdi, %rax
addq $0x60, %rax
movq %rax, -0x370(%rbp)
movl -0x30c(%rbp), %eax
movl %eax, -0x364(%rbp)
addq $0x70, %rdi
movslq -0x30c(%rbp), %rsi
callq 0x177790
movq -0x370(%rbp), %rdi
movl -0x364(%rbp), %esi
movq (%rax), %rax
movl %eax, %edx
callq 0x1776b0
movl -0x30c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30c(%rbp)
jmp 0x1767da
movq -0x30(%rbp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
movq -0x320(%rbp), %rax
movq %rdx, %rsi
movl $0x1, %ecx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
cmpq $0x0, %rsi
cmovnel %edx, %ecx
movslq %ecx, %rcx
movq %rcx, 0xd8(%rax)
movb $0x1, 0xb8(%rax)
addq $0x370, %rsp            # imm = 0x370
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)