// File: /workspace/github_cpp_makefile_star2_O2/chiku[P]cmatrix/src/impl/matrix/invert.cpp
// Function: cmatrix::Matrix<double>::invert()
Matrix<Type> Matrix<Type>::invert()
{
    if (!isSquare()) {
        throw Exception::InversionNotPossible(ExceptionBody::NonSquareMatrix(size));
    }

    Matrix<Type> result = (*this);
    long int n = result.rows();
    long int pivot_column = 0, pivot_row = 0;

    Matrix<long int> column_indices(n, 1);
    Matrix<long int> row_indices(n, 1);
    Matrix<long int> pivots(n, 1);

    for (long int i = 0; i < n; i++) {
        pivots(i, 0) = -1;
    }

    for (long int i = 0; i < n; i++) {
        Type big = 0;
        for (long int j = 0; j < n; j++) {
            if (pivots(j, 0) != 0) {
                for (long int k = 0; k < n; k++) {
                    if ((pivots(k, 0) == -1) && (fabs(result(j, k)) >= big)) {
                        big = fabs(result(j, k));
                        pivot_row = j;
                        pivot_column = k;
                    }
                }
            }
        }
        pivots(pivot_column, 0) += 1;

        /* We now have the pivot element, so we interchange rows, if needed, to put the pivot
        element on the diagonal. The columns are not physically interchanged, only relabeled:
        column_indices[i], the column of the ith pivot element, is the ith column that is reduced,
        while row_indices[i] is the row in which that pivot element was originally located.
        If row_indices[i] != column_indices[i] there is an implied column interchange.
        With this form of book keeping, inverse matrix will be scrambled by columns. */
        if (pivot_row != pivot_column) {
            for (long int j = 0; j < n; j++)
                std::swap(result(pivot_row, j), result(pivot_column, j));
        }

        row_indices(i, 0) = pivot_row;       // We are now ready to divide the pivot row by the
        column_indices(i, 0) = pivot_column; // pivot element, located at pivot_row and pivot_column.
        if (result(pivot_column, pivot_column) == 0.0) {
            throw Exception::InversionNotPossible(ExceptionBody::SingularMatrix());
        }
        Type pivot_inverse = 1.0 / result(pivot_column, pivot_column);
        result(pivot_column, pivot_column) = 1.0;

        for (long int j = 0; j < n; j++) {
            result(pivot_column, j) *= pivot_inverse;
        }

        for (long int j = 0; j < n; j++) { // Next, we reduce the rows...
            if (j != pivot_column) {       //  except for the pivot one
                Type dum = result(j, pivot_column);
                result(j, pivot_column) = 0.0;
                for (long int k = 0; k < n; k++)
                    result(j, k) -= result(pivot_column, k) * dum;
            }
        }
    }
    /* This is the end of the main loop over columns of the reduction. It only remains to unscramble
    the solution in view of the column interchanges. We do this by interchanging pairs of
    columns in the reverse order that the permutation was built up. */
    for (long int i = 0; i < 0; i++) {
        if (row_indices(i, 0) != column_indices(i, 0)) {
            for (long int j = 0; j < n; j++) {
                std::swap(result(j, row_indices(i, 0)), result(i, column_indices(i, 0)));
            }
        }
    }

    return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %rsi, %r14
movq (%rsi), %rax
cmpq 0x8(%rsi), %rax
jne 0x126e3
movq %rdi, %rbx
movq %r14, %rsi
callq 0xb95a
movq (%rbx), %r14
leaq 0x90(%rsp), %rdi
pushq $0x1
popq %rdx
movq %r14, %rsi
callq 0x12afe
leaq 0x68(%rsp), %rdi
pushq $0x1
popq %rdx
movq %r14, %rsi
callq 0x12afe
leaq 0x40(%rsp), %rdi
pushq $0x1
popq %rdx
movq %r14, %rsi
callq 0x12afe
xorl %r15d, %r15d
testq %r14, %r14
movl $0x0, %eax
cmovgq %r14, %rax
movq %rax, 0x8(%rsp)
leaq 0x40(%rsp), %r12
cmpq %r15, 0x8(%rsp)
je 0x123fc
movq %r12, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x12b12
orq $-0x1, (%rax)
incq %r15
jmp 0x123df
xorl %ebp, %ebp
leaq 0x40(%rsp), %r15
movq $0x0, 0x10(%rsp)
xorl %eax, %eax
movq %rax, 0x18(%rsp)
cmpq 0x8(%rsp), %rax
je 0x12668
xorpd %xmm0, %xmm0
movapd %xmm0, 0x20(%rsp)
xorl %r13d, %r13d
cmpq %r14, %r13
je 0x124b9
movq %r15, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0x12b12
cmpq $0x0, (%rax)
je 0x124b1
xorl %r12d, %r12d
cmpq %r12, %r14
je 0x124b1
movq %r15, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x12b12
cmpq $-0x1, (%rax)
jne 0x124ac
movq %rbx, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0xaad2
movsd (%rax), %xmm0
andpd 0x202c4(%rip), %xmm0    # 0x32740
ucomisd 0x20(%rsp), %xmm0
jb 0x124ac
movq %rbx, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0xaad2
movsd (%rax), %xmm0
andpd 0x202a2(%rip), %xmm0    # 0x32740
movapd %xmm0, 0x20(%rsp)
movq %r12, %rbp
movq %r13, 0x10(%rsp)
incq %r12
jmp 0x1244a
incq %r13
jmp 0x1242b
movq %r15, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x12b12
incq (%rax)
cmpq %rbp, 0x10(%rsp)
jne 0x12622
leaq 0x68(%rsp), %rdi
movq 0x18(%rsp), %rsi
xorl %edx, %edx
callq 0x12b12
movq 0x10(%rsp), %rcx
movq %rcx, (%rax)
leaq 0x90(%rsp), %rdi
movq 0x18(%rsp), %rsi
xorl %edx, %edx
callq 0x12b12
movq %rbp, (%rax)
movq %rbx, %rdi
movq %rbp, %rsi
movq %rbp, %rdx
callq 0xaad2
movsd (%rax), %xmm0
ucomisd 0x20232(%rip), %xmm0    # 0x32750
jne 0x12526
jnp 0x1269e
movq %rbx, %rdi
movq %rbp, %rsi
movq %rbp, %rdx
callq 0xaad2
movsd 0x1ffa4(%rip), %xmm0    # 0x324e0
divsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq %rbx, %rdi
movq %rbp, %rsi
movq %rbp, %rdx
callq 0xaad2
movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000
movq %rcx, (%rax)
xorl %r12d, %r12d
cmpq %r12, 0x8(%rsp)
je 0x1258c
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq 0xaad2
movsd (%rax), %xmm0
mulsd 0x20(%rsp), %xmm0
movsd %xmm0, (%rax)
incq %r12
jmp 0x12564
xorl %r13d, %r13d
cmpq 0x8(%rsp), %r13
je 0x12615
cmpq %rbp, %r13
jne 0x125a0
incq %r13
jmp 0x1258f
movq %rbx, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0xaad2
movsd (%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0xaad2
andq $0x0, (%rax)
xorl %r12d, %r12d
cmpq %r12, %r14
je 0x1259b
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq 0xaad2
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0xaad2
movsd (%rax), %xmm0
movsd 0x20(%rsp), %xmm1
mulsd 0x38(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
incq %r12
jmp 0x125cd
movq 0x18(%rsp), %rax
incq %rax
jmp 0x1240e
xorl %r12d, %r12d
cmpq %r12, %r14
je 0x124d4
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
movq %r12, %rdx
callq 0xaad2
movq %rax, %r13
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq 0xaad2
movsd (%r13), %xmm0
movsd (%rax), %xmm1
movsd %xmm1, (%r13)
movsd %xmm0, (%rax)
incq %r12
jmp 0x12625
leaq 0x40(%rsp), %rdi
callq 0x12bf0
leaq 0x68(%rsp), %rdi
callq 0x12bf0
leaq 0x90(%rsp), %rdi
callq 0x12bf0
movq %rbx, %rax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x51b0
movq %rax, %r15
leaq 0xb8(%rsp), %rdi
callq 0x12bce
movb $0x1, %bpl
leaq 0xb8(%rsp), %rsi
movq %r15, %rdi
callq 0x12ae8
xorl %ebp, %ebp
leaq 0x360be(%rip), %rsi     # 0x48790
movq 0x368df(%rip), %rdx     # 0x48fb8
movq %r15, %rdi
callq 0x55e0
jmp 0x1272d
pushq $0x10
popq %rdi
callq 0x51b0
movq %rax, %rbx
movq (%r14), %rsi
movq 0x8(%r14), %rdx
leaq 0xd8(%rsp), %rdi
callq 0x12a48
movb $0x1, %bpl
leaq 0xd8(%rsp), %rsi
movq %rbx, %rdi
callq 0x12ae8
xorl %ebp, %ebp
leaq 0x36072(%rip), %rsi     # 0x48790
movq 0x36893(%rip), %rdx     # 0x48fb8
movq %rbx, %rdi
callq 0x55e0
movq %rax, %r14
leaq 0xd8(%rsp), %rdi
callq 0x5180
testb %bpl, %bpl
jne 0x12747
jmp 0x127c0
movq %rax, %r14
movq %rbx, %rdi
callq 0x5290
jmp 0x127c0
movq %rax, %r14
jmp 0x127a1
movq %rax, %r14
jmp 0x127ab
movq %rax, %r14
jmp 0x127b8
movq %rax, %r14
leaq 0xb8(%rsp), %rdi
callq 0x5180
testb %bpl, %bpl
jne 0x1277a
jmp 0x12797
movq %rax, %r14
movq %r15, %rdi
callq 0x5290
jmp 0x12797
jmp 0x12794
jmp 0x12794
jmp 0x12794
jmp 0x12794
jmp 0x12794
jmp 0x12794
jmp 0x12794
jmp 0x12794
movq %rax, %r14
leaq 0x40(%rsp), %rdi
callq 0x12bf0
leaq 0x68(%rsp), %rdi
callq 0x12bf0
leaq 0x90(%rsp), %rdi
callq 0x12bf0
movq %rbx, %rdi
callq 0xac4e
movq %r14, %rdi
callq 0x5620