// File: /workspace/github_cpp_makefile_star2_O1/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, -0x88(%rbp)
movl %edx, %r14d
movq %rsi, -0xb0(%rbp)
movq %rdi, %rbx
leaq -0x78(%rbp), %rdi
movsd 0x39af(%rip), %xmm0     # 0x7008
movl %edx, %esi
movl $0x1, %edx
callq 0x24fc
movq %r14, -0x58(%rbp)
testl %r14d, %r14d
je 0x36a6
movq -0x70(%rbp), %rax
movq -0x58(%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 0x3689
xorpd %xmm0, %xmm0
movapd %xmm0, -0x50(%rbp)
xorl %eax, %eax
movq %rax, -0x40(%rbp)
movq %rax, -0x30(%rbp)
movq %rax, -0xa8(%rbp)
movq -0x48(%rbp), %rsi
testq %rsi, %rsi
movq %rbx, -0x80(%rbp)
je 0x36de
movq $0x0, (%rsi)
addq $0x8, %rsi
movq %rsi, -0x48(%rbp)
jmp 0x36ee
leaq -0x50(%rbp), %rdi
leaq -0xa8(%rbp), %rdx
callq 0x4a16
movsd 0x3912(%rip), %xmm0     # 0x7008
ucomisd -0x88(%rbp), %xmm0
jbe 0x383e
movl -0x58(%rbp), %eax
shlq $0x3, %rax
leaq (%rax,%rax,2), %r13
xorl %ebx, %ebx
leaq -0xa8(%rbp), %r15
leaq -0x78(%rbp), %r12
cmpl $0x0, -0x58(%rbp)
je 0x3764
movq -0x70(%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 0x38d8(%rip), %xmm3     # 0x7020
andpd %xmm3, %xmm2
andpd %xmm3, %xmm1
ucomisd %xmm1, %xmm2
jb 0x375b
movsd %xmm0, -0x30(%rbp)
addq $0x18, %rdx
cmpq %rdx, %r13
jne 0x372b
cmpq $0x7a11f, %rbx          # imm = 0x7A11F
je 0x3899
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x378e
movsd -0x30(%rbp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, -0x48(%rbp)
jmp 0x379b
leaq -0x50(%rbp), %rdi
leaq -0x30(%rbp), %rdx
callq 0x4936
leaq 0x1(%rbx), %r14
movq -0x50(%rbp), %rax
movsd (%rax,%r14,8), %xmm0
subsd (%rax,%rbx,8), %xmm0
movapd %xmm0, -0xc0(%rbp)
movsd -0x30(%rbp), %xmm0
movq %r15, %rdi
movq %r12, %rsi
callq 0x3134
movq -0xa8(%rbp), %rax
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0xa0(%rbp), %rbx
movq %rbx, %rsi
callq 0x3e2e
movq %rbx, %rdi
callq 0x3d9a
movq %r15, %rdi
movq -0xb0(%rbp), %rsi
movq %r12, %rdx
callq 0x2c3e
movq -0xa8(%rbp), %rax
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
movq %rbx, %rsi
callq 0x3e2e
movq %rbx, %rdi
callq 0x3d9a
movapd -0xc0(%rbp), %xmm0
andpd 0x37f3(%rip), %xmm0     # 0x7020
ucomisd -0x88(%rbp), %xmm0
movq %r14, %rbx
ja 0x371c
movsd -0x30(%rbp), %xmm0
leaq -0xa8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3134
leaq -0xa0(%rbp), %r14
movq -0x8(%r14), %rax
leaq -0x70(%rbp), %rdi
movq %rax, -0x8(%rdi)
movq %r14, %rsi
callq 0x3e2e
movq -0x80(%rbp), %rbx
movq %r14, %rdi
callq 0x3d9a
movl $0x0, (%rbx)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x8(%rbx)
leaq 0x10(%rbx), %rdi
leaq -0x78(%rbp), %rsi
callq 0x2946
jmp 0x38e8
movq 0x7738(%rip), %rdi      # 0xafd8
leaq 0x382a(%rip), %rsi      # 0x70d1
movl $0x31, %edx
callq 0x2200
movq -0x80(%rbp), %rbx
movq 0x771c(%rip), %rdi      # 0xafd8
leaq 0x3840(%rip), %rsi      # 0x7103
movl $0x28, %edx
callq 0x2200
movl $0xffffffff, (%rbx)     # imm = 0xFFFFFFFF
movq $0x0, 0x8(%rbx)
leaq 0x10(%rbx), %rdi
leaq -0x78(%rbp), %rsi
callq 0x2946
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x38fd
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
leaq -0x70(%rbp), %rdi
callq 0x3d9a
movq %rbx, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x393e
jmp 0x393e
movq %rax, %rbx
movq %r14, %rdi
jmp 0x3935
jmp 0x393e
jmp 0x393e
jmp 0x393e
jmp 0x392f
movq %rbx, %rdi
movq %rax, %rbx
callq 0x3d9a
jmp 0x3941
jmp 0x393e
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3956
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
leaq -0x70(%rbp), %rdi
callq 0x3d9a
movq %rbx, %rdi
callq 0x22c0
nop