// File: /workspace/github_cpp_makefile_star2_O3/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 0x146c9
movq %rdi, %rbx
movq %r14, %rsi
callq 0xc818
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 0x14cc4
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 0x14cc4
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 0x14cc4
testq %r14, %r14
jle 0x1460f
xorl %r15d, %r15d
leaq 0x30(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x14bd0
movq $-0x1, (%rax)
incq %r15
cmpq %r15, %r14
jne 0x14397
testq %r14, %r14
jle 0x1460f
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 0x14bd0
cmpq $0x0, (%rax)
je 0x1445c
xorl %r13d, %r13d
movq %r12, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0x14bd0
cmpq $-0x1, (%rax)
jne 0x14454
movq %rbx, %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0xb95c
movsd (%rax), %xmm0
andpd 0x2535c(%rip), %xmm0    # 0x39780
ucomisd 0x10(%rsp), %xmm0
jb 0x14454
movq %rbx, %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0xb95c
movsd (%rax), %xmm0
andpd 0x2533a(%rip), %xmm0    # 0x39780
movapd %xmm0, 0x10(%rsp)
movq %r13, %r15
movq %rbp, 0x8(%rsp)
incq %r13
cmpq %r13, %r14
jne 0x143f7
incq %rbp
cmpq %r14, %rbp
jne 0x143e1
movq %r12, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x14bd0
incq (%rax)
cmpq %r15, 0x8(%rsp)
je 0x144bd
xorl %r13d, %r13d
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
movq %r13, %rdx
callq 0xb95c
movq %rax, %rbp
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0xb95c
movsd (%rbp), %xmm0
movsd (%rax), %xmm1
movsd %xmm1, (%rbp)
movsd %xmm0, (%rax)
incq %r13
cmpq %r13, %r14
jne 0x14482
leaq 0x80(%rsp), %rdi
movq (%rsp), %rsi
xorl %edx, %edx
callq 0x14bd0
movq 0x8(%rsp), %rcx
movq %rcx, (%rax)
leaq 0xb0(%rsp), %rdi
movq (%rsp), %rsi
xorl %edx, %edx
callq 0x14bd0
movq %r15, (%rax)
movq %rbx, %rdi
movq %r15, %rsi
movq %r15, %rdx
callq 0xb95c
movsd (%rax), %xmm0
ucomisd 0x25288(%rip), %xmm0    # 0x39790
jne 0x14510
jnp 0x14666
movq %rbx, %rdi
movq %r15, %rsi
movq %r15, %rdx
callq 0xb95c
movsd 0x25002(%rip), %xmm0    # 0x39528
divsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
movq %r15, %rdx
callq 0xb95c
movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000
movq %rcx, (%rax)
xorl %r13d, %r13d
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0xb95c
movsd (%rax), %xmm0
mulsd 0x10(%rsp), %xmm0
movsd %xmm0, (%rax)
incq %r13
cmpq %r13, %r14
jne 0x1454e
xorl %r13d, %r13d
cmpq %r15, %r13
je 0x145ef
movq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0xb95c
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0xb95c
movq $0x0, (%rax)
xorl %ebp, %ebp
movq %rbx, %rdi
movq %r15, %rsi
movq %rbp, %rdx
callq 0xb95c
movsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0xb95c
movsd (%rax), %xmm0
movsd 0x10(%rsp), %xmm1
mulsd 0x28(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
incq %rbp
cmpq %rbp, %r14
jne 0x145a9
incq %r13
cmpq %r14, %r13
jne 0x14575
movq (%rsp), %rcx
incq %rcx
movq %rcx, (%rsp)
cmpq %r14, %rcx
jne 0x143d5
cmpq $0x0, 0x40(%rsp)
je 0x14621
leaq 0x40(%rsp), %rdi
callq 0x14ea8
cmpq $0x0, 0x90(%rsp)
je 0x14639
leaq 0x90(%rsp), %rdi
callq 0x14ea8
cmpq $0x0, 0xc0(%rsp)
je 0x14651
leaq 0xc0(%rsp), %rdi
callq 0x14ea8
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 0x254de(%rip), %rsi     # 0x39b62
leaq 0x254f6(%rip), %rdx     # 0x39b81
leaq 0x60(%rsp), %rdi
callq 0xc782
movb $0x1, %bpl
leaq 0x60(%rsp), %rsi
movq %r15, %rdi
callq 0x5420
leaq 0x3711c(%rip), %rax     # 0x4b7c8
movq %rax, (%r15)
xorl %ebp, %ebp
leaq 0x370e8(%rip), %rsi     # 0x4b7a0
movq 0x37901(%rip), %rdx     # 0x4bfc0
movq %r15, %rdi
callq 0x5590
jmp 0x1471f
movl $0x10, %edi
callq 0x5170
movq %rax, %rbx
movq (%r14), %rsi
movq 0x8(%r14), %rdx
leaq 0xd8(%rsp), %rdi
callq 0x14af4
movb $0x1, %bpl
leaq 0xd8(%rsp), %rsi
movq %rbx, %rdi
callq 0x5420
leaq 0x370c4(%rip), %rax     # 0x4b7c8
movq %rax, (%rbx)
xorl %ebp, %ebp
leaq 0x37090(%rip), %rsi     # 0x4b7a0
movq 0x378a9(%rip), %rdx     # 0x4bfc0
movq %rbx, %rdi
callq 0x5590
movq %rax, %r14
leaq 0xe8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x14743
movq 0xe8(%rsp), %rsi
incq %rsi
callq 0x5390
testb %bpl, %bpl
jne 0x14750
jmp 0x14812
movq %rax, %r14
movq %rbx, %rdi
callq 0x5270
jmp 0x14812
movq %rax, %r14
jmp 0x147c2
movq %rax, %r14
jmp 0x147da
movq %rax, %r14
jmp 0x147f2
movq %rax, %r14
movq 0x60(%rsp), %rdi
cmpq %r12, %rdi
je 0x14789
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x5390
testb %bpl, %bpl
jne 0x14793
jmp 0x147b0
movq %rax, %r14
movq %r15, %rdi
callq 0x5270
jmp 0x147b0
jmp 0x147ad
jmp 0x147ad
jmp 0x147ad
jmp 0x147ad
jmp 0x147ad
jmp 0x147ad
jmp 0x147ad
jmp 0x147ad
movq %rax, %r14
cmpq $0x0, 0x40(%rsp)
je 0x147c2
leaq 0x40(%rsp), %rdi
callq 0x14ea8
cmpq $0x0, 0x90(%rsp)
je 0x147da
leaq 0x90(%rsp), %rdi
callq 0x14ea8
cmpq $0x0, 0xc0(%rsp)
je 0x147f2
leaq 0xc0(%rsp), %rdi
callq 0x14ea8
cmpq $0x0, 0x10(%rbx)
je 0x14812
leaq 0x10(%rbx), %rdi
callq 0xbf72
xorpd %xmm0, %xmm0
movupd %xmm0, (%rbx)
movq $0x0, 0x10(%rbx)
movq %r14, %rdi
callq 0x55d0