// File: /workspace/github_cpp_makefile_star2_O3/Krymancer[P]Matrix-cpp/src/Matrix.cpp
// Function: Matrix::powerIter(unsigned int, double)
tuple<Matrix, double, int> Matrix::powerIter(unsigned rowNum, double tolerance) {
    // Picks a classic X vector
    Matrix X(rowNum, 1, 1.0);
    // Initiates X vector with values 1,2,3,4
    for (unsigned i = 1; i <= rowNum; i++) {
        X(i - 1, 0) = i;
    }
    int errorCode = 0;
    double difference = 1.0;  // Initiall value greater than tolerance
    unsigned j = 0;
    unsigned location;
    // Defined to find the value between last two eigen values
    vector<double> eigen;
    double eigenvalue = 0.0;
    eigen.push_back(0.0);

    while (abs(difference) > tolerance) {  // breaks out when reached tolerance
        j++;
        // Normalize X vector with infinite norm
        for (int i = 0; i < rowNum; ++i) {
            eigenvalue = X(0, 0);
            if (abs(X(i, 0)) >= abs(eigenvalue)) {
                // Take the value of the infinite norm as your eigenvalue
                eigenvalue = X(i, 0);
                location = i;
            }
        }
        if (j >= 5e5) {
            std::cout << "Oops, that was a nasty complex number wasn't it?\n";
            std::cout << "ERROR! Returning code black, code black!";
            errorCode = -1;
            return std::make_tuple(X, 0.0, errorCode);
        }
        eigen.push_back(eigenvalue);
        difference = eigen[j] - eigen[j - 1];
        // Normalize X vector with its infinite norm
        X = X / eigenvalue;

        // Multiply The matrix with X vector
        X = (*this) * X;
    }

    // Take the X vector and what you've found is an eigenvector!
    X = X / eigenvalue;
    return std::make_tuple(X, eigenvalue, errorCode);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movsd %xmm0, -0x80(%rbp)
movl %edx, %r14d
movq %rsi, -0x88(%rbp)
movq %rdi, %rbx
leaq -0x58(%rbp), %rdi
movsd 0x39b0(%rip), %xmm0     # 0x7008
movl %edx, %esi
movl $0x1, %edx
callq 0x24fc
movq %r14, -0x38(%rbp)
testl %r14d, %r14d
je 0x36a5
movq -0x50(%rbp), %rax
movq -0x38(%rbp), %rcx
leal 0x1(%rcx), %edx
cmpl $0x3, %edx
movl $0x2, %ecx
cmovael %edx, %ecx
movl $0x1, %edx
movl %edx, %esi
xorps %xmm0, %xmm0
cvtsi2sd %rsi, %xmm0
movq (%rax), %rsi
movsd %xmm0, (%rsi)
incq %rdx
addq $0x18, %rax
cmpq %rdx, %rcx
jne 0x3688
movq %rbx, -0x78(%rbp)
xorpd %xmm0, %xmm0
leaq -0x70(%rbp), %rdi
movapd %xmm0, (%rdi)
xorl %eax, %eax
movq %rax, 0x10(%rdi)
movq %rax, -0x30(%rbp)
leaq -0xa8(%rbp), %rdx
movq %rax, (%rdx)
xorl %esi, %esi
callq 0x4a5c
movsd 0x3930(%rip), %xmm0     # 0x7008
ucomisd -0x80(%rbp), %xmm0
jbe 0x381b
movl -0x38(%rbp), %eax
shlq $0x3, %rax
leaq (%rax,%rax,2), %r13
xorl %r14d, %r14d
leaq -0xa8(%rbp), %r15
leaq -0x58(%rbp), %r12
cmpl $0x0, -0x38(%rbp)
je 0x3744
movq -0x50(%rbp), %rax
movq (%rax), %rcx
xorl %edx, %edx
movsd (%rcx), %xmm1
movsd %xmm1, -0x30(%rbp)
movq (%rax,%rdx), %rsi
movsd (%rsi), %xmm0
movapd %xmm0, %xmm2
movapd 0x38f8(%rip), %xmm3     # 0x7020
andpd %xmm3, %xmm2
andpd %xmm3, %xmm1
ucomisd %xmm1, %xmm2
jb 0x373b
movsd %xmm0, -0x30(%rbp)
addq $0x18, %rdx
cmpq %rdx, %r13
jne 0x370b
cmpq $0x7a11f, %r14          # imm = 0x7A11F
je 0x3876
movq -0x68(%rbp), %rsi
cmpq -0x60(%rbp), %rsi
je 0x376e
movsd -0x30(%rbp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, -0x68(%rbp)
jmp 0x3780
leaq -0x70(%rbp), %rdi
leaq -0x30(%rbp), %rdx
callq 0x497c
movsd -0x30(%rbp), %xmm0
leaq 0x1(%r14), %rbx
movq -0x70(%rbp), %rax
movsd (%rax,%rbx,8), %xmm1
subsd (%rax,%r14,8), %xmm1
movapd %xmm1, -0xc0(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x3134
movq -0xa8(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0xa0(%rbp), %r14
movq %r14, %rsi
callq 0x3e14
movq %r14, %rdi
callq 0x3d7a
movq %r15, %rdi
movq -0x88(%rbp), %rsi
movq %r12, %rdx
callq 0x2c3e
movq -0xa8(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
movq %r14, %rsi
callq 0x3e14
movq %r14, %rdi
callq 0x3d7a
movapd -0xc0(%rbp), %xmm0
andpd 0x3813(%rip), %xmm0     # 0x7020
ucomisd -0x80(%rbp), %xmm0
movq %rbx, %r14
ja 0x36fc
movsd -0x30(%rbp), %xmm0
leaq -0xa8(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x3134
leaq -0xa0(%rbp), %r14
movq -0x8(%r14), %rax
leaq -0x50(%rbp), %rdi
movq %rax, -0x8(%rdi)
movq %r14, %rsi
callq 0x3e14
movq %r14, %rdi
callq 0x3d7a
movq -0x78(%rbp), %rbx
movl $0x0, (%rbx)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x8(%rbx)
leaq 0x10(%rbx), %rdi
leaq -0x58(%rbp), %rsi
callq 0x2946
jmp 0x38c5
movq 0x775b(%rip), %rdi      # 0xafd8
leaq 0x384d(%rip), %rsi      # 0x70d1
movl $0x31, %edx
callq 0x2200
movq -0x78(%rbp), %rbx
movq 0x773f(%rip), %rdi      # 0xafd8
leaq 0x3863(%rip), %rsi      # 0x7103
movl $0x28, %edx
callq 0x2200
movl $0xffffffff, (%rbx)     # imm = 0xFFFFFFFF
movq $0x0, 0x8(%rbx)
leaq 0x10(%rbx), %rdi
leaq -0x58(%rbp), %rsi
callq 0x2946
movq -0x70(%rbp), %rdi
testq %rdi, %rdi
je 0x38da
movq -0x60(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
leaq -0x50(%rbp), %rdi
callq 0x3d7a
movq %rbx, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3915
jmp 0x3906
jmp 0x3915
jmp 0x3915
jmp 0x3915
jmp 0x3915
jmp 0x3906
movq %rax, %rbx
movq %r14, %rdi
callq 0x3d7a
jmp 0x3918
jmp 0x3915
movq %rax, %rbx
movq -0x70(%rbp), %rdi
testq %rdi, %rdi
je 0x392d
movq -0x60(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
leaq -0x50(%rbp), %rdi
callq 0x3d7a
movq %rbx, %rdi
callq 0x22c0