// File: /workspace/github_cpp_makefile_star2_O1/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 0x14e81
movq %rdi, %rbx
movq %r14, %rsi
callq 0xcb2c
movq (%rbx), %r14
xorpd %xmm0, %xmm0
leaq 0xb0(%rsp), %rdi
movapd %xmm0, 0x10(%rdi)
movapd %xmm0, (%rdi)
movq $0x0, 0x20(%rdi)
movl $0x1, %edx
movq %r14, %rsi
callq 0x1551e
leaq 0x80(%rsp), %rdi
xorpd %xmm0, %xmm0
movapd %xmm0, 0x10(%rdi)
movapd %xmm0, (%rdi)
movq $0x0, 0x20(%rdi)
movl $0x1, %edx
movq %r14, %rsi
callq 0x1551e
xorpd %xmm0, %xmm0
leaq 0x30(%rsp), %rdi
movapd %xmm0, 0x10(%rdi)
movapd %xmm0, (%rdi)
movq $0x0, 0x20(%rdi)
movl $0x1, %edx
movq %r14, %rsi
callq 0x1551e
testq %r14, %r14
jle 0x14b2f
xorl %r15d, %r15d
leaq 0x30(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x15428
movq $-0x1, (%rax)
incq %r15
cmpq %r15, %r14
jne 0x14b13
testq %r14, %r14
jle 0x14d8b
movq $0x0, (%rsp)
leaq 0x30(%rsp), %r12
movq $0x0, 0x8(%rsp)
xorl %r15d, %r15d
xorl %ebp, %ebp
xorpd %xmm0, %xmm0
movapd %xmm0, 0x10(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x15428
cmpq $0x0, (%rax)
je 0x14bd8
xorl %r13d, %r13d
movq %r12, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0x15428
cmpq $-0x1, (%rax)
jne 0x14bd0
movq %rbx, %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0xbbfc
movsd (%rax), %xmm0
andpd 0x25bb0(%rip), %xmm0    # 0x3a750
ucomisd 0x10(%rsp), %xmm0
jb 0x14bd0
movq %rbx, %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0xbbfc
movsd (%rax), %xmm0
andpd 0x25b8e(%rip), %xmm0    # 0x3a750
movapd %xmm0, 0x10(%rsp)
movq %r13, %r15
movq %rbp, 0x8(%rsp)
incq %r13
cmpq %r13, %r14
jne 0x14b73
incq %rbp
cmpq %r14, %rbp
jne 0x14b5d
movq %r12, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x15428
incq (%rax)
cmpq %r15, 0x8(%rsp)
je 0x14c39
xorl %r13d, %r13d
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
movq %r13, %rdx
callq 0xbbfc
movq %rax, %rbp
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0xbbfc
movsd (%rbp), %xmm0
movsd (%rax), %xmm1
movsd %xmm1, (%rbp)
movsd %xmm0, (%rax)
incq %r13
cmpq %r13, %r14
jne 0x14bfe
leaq 0x80(%rsp), %rdi
movq (%rsp), %rsi
xorl %edx, %edx
callq 0x15428
movq 0x8(%rsp), %rcx
movq %rcx, (%rax)
leaq 0xb0(%rsp), %rdi
movq (%rsp), %rsi
xorl %edx, %edx
callq 0x15428
movq %r15, (%rax)
movq %rbx, %rdi
movq %r15, %rsi
movq %r15, %rdx
callq 0xbbfc
movsd (%rax), %xmm0
ucomisd 0x25adc(%rip), %xmm0    # 0x3a760
jne 0x14c8c
jnp 0x14e1e
movq %rbx, %rdi
movq %r15, %rsi
movq %r15, %rdx
callq 0xbbfc
movsd 0x2584e(%rip), %xmm0    # 0x3a4f0
divsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
movq %r15, %rdx
callq 0xbbfc
movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000
movq %rcx, (%rax)
xorl %r13d, %r13d
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0xbbfc
movsd (%rax), %xmm0
mulsd 0x10(%rsp), %xmm0
movsd %xmm0, (%rax)
incq %r13
cmpq %r13, %r14
jne 0x14cca
xorl %r13d, %r13d
cmpq %r15, %r13
je 0x14d6b
movq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0xbbfc
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0xbbfc
movq $0x0, (%rax)
xorl %ebp, %ebp
movq %rbx, %rdi
movq %r15, %rsi
movq %rbp, %rdx
callq 0xbbfc
movsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0xbbfc
movsd (%rax), %xmm0
movsd 0x10(%rsp), %xmm1
mulsd 0x28(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
incq %rbp
cmpq %rbp, %r14
jne 0x14d25
incq %r13
cmpq %r14, %r13
jne 0x14cf1
movq (%rsp), %rcx
incq %rcx
movq %rcx, (%rsp)
cmpq %r14, %rcx
jne 0x14b51
cmpq $0x0, 0x40(%rsp)
je 0x14db1
leaq 0x40(%rsp), %r14
movq %r14, %rdi
callq 0x15704
xorpd %xmm0, %xmm0
movapd %xmm0, -0x10(%r14)
movq $0x0, (%r14)
cmpq $0x0, 0x90(%rsp)
je 0x14ddd
leaq 0x90(%rsp), %r14
movq %r14, %rdi
callq 0x15704
xorpd %xmm0, %xmm0
movapd %xmm0, -0x10(%r14)
movq $0x0, (%r14)
cmpq $0x0, 0xc0(%rsp)
je 0x14e09
leaq 0xc0(%rsp), %r14
movq %r14, %rdi
callq 0x15704
xorpd %xmm0, %xmm0
movapd %xmm0, -0x10(%r14)
movq $0x0, (%r14)
movq %rbx, %rax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x5170
movq %rax, %r15
leaq 0x70(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0x25cf6(%rip), %rsi     # 0x3ab32
leaq 0x25d0e(%rip), %rdx     # 0x3ab51
leaq 0x60(%rsp), %rdi
callq 0xca9c
movb $0x1, %bpl
leaq 0x60(%rsp), %rsi
movq %r15, %rdi
callq 0x5420
leaq 0x38964(%rip), %rax     # 0x4d7c8
movq %rax, (%r15)
xorl %ebp, %ebp
leaq 0x38930(%rip), %rsi     # 0x4d7a0
movq 0x39149(%rip), %rdx     # 0x4dfc0
movq %r15, %rdi
callq 0x5590
jmp 0x14ed7
movl $0x10, %edi
callq 0x5170
movq %rax, %rbx
movq (%r14), %rsi
movq 0x8(%r14), %rdx
leaq 0xd8(%rsp), %rdi
callq 0x1534c
movb $0x1, %bpl
leaq 0xd8(%rsp), %rsi
movq %rbx, %rdi
callq 0x5420
leaq 0x3890c(%rip), %rax     # 0x4d7c8
movq %rax, (%rbx)
xorl %ebp, %ebp
leaq 0x388d8(%rip), %rsi     # 0x4d7a0
movq 0x390f1(%rip), %rdx     # 0x4dfc0
movq %rbx, %rdi
callq 0x5590
movq %rax, %r14
leaq 0xe8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x14f03
movq 0xe8(%rsp), %rsi
incq %rsi
callq 0x5390
jmp 0x14f03
movq %rax, %r14
movb $0x1, %bpl
testb %bpl, %bpl
je 0x15010
movq %rbx, %rdi
callq 0x5270
jmp 0x15010
movq %rax, %r14
jmp 0x14f98
movq %rax, %r14
jmp 0x14fc4
movq %rax, %r14
jmp 0x14ff0
movq %rax, %r14
movq 0x60(%rsp), %rdi
cmpq %r12, %rdi
je 0x14f50
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x5390
jmp 0x14f50
movq %rax, %r14
movb $0x1, %bpl
testb %bpl, %bpl
je 0x14f72
movq %r15, %rdi
callq 0x5270
jmp 0x14f72
jmp 0x14f6f
jmp 0x14f6f
jmp 0x14f6f
jmp 0x14f6f
jmp 0x14f6f
jmp 0x14f6f
jmp 0x14f6f
jmp 0x14f6f
movq %rax, %r14
cmpq $0x0, 0x40(%rsp)
je 0x14f98
leaq 0x40(%rsp), %r15
movq %r15, %rdi
callq 0x15704
xorpd %xmm0, %xmm0
movapd %xmm0, -0x10(%r15)
movq $0x0, (%r15)
cmpq $0x0, 0x90(%rsp)
je 0x14fc4
leaq 0x90(%rsp), %r15
movq %r15, %rdi
callq 0x15704
xorpd %xmm0, %xmm0
movapd %xmm0, -0x10(%r15)
movq $0x0, (%r15)
cmpq $0x0, 0xc0(%rsp)
je 0x14ff0
leaq 0xc0(%rsp), %r15
movq %r15, %rdi
callq 0x15704
xorpd %xmm0, %xmm0
movapd %xmm0, -0x10(%r15)
movq $0x0, (%r15)
cmpq $0x0, 0x10(%rbx)
je 0x15010
leaq 0x10(%rbx), %rdi
callq 0xc216
xorpd %xmm0, %xmm0
movupd %xmm0, (%rbx)
movq $0x0, 0x10(%rbx)
movq %r14, %rdi
callq 0x55d0