// File: /workspace/github_cpp_makefile_star2_O2/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 $0x88, %rsp
movsd %xmm0, -0x88(%rbp)
movl %edx, %ebx
movq %rsi, -0x80(%rbp)
movq %rdi, -0x38(%rbp)
leaq -0x78(%rbp), %rdi
pushq $0x1
popq %rdx
movsd 0x3cb3(%rip), %xmm0     # 0x7008
movl %ebx, %esi
callq 0x248c
leaq -0x70(%rbp), %rax
movq (%rax), %rax
movl %ebx, %ebx
pushq $0x1
popq %rcx
cmpq %rbx, %rcx
ja 0x3384
movl %ecx, %edx
cvtsi2sd %rdx, %xmm0
movq (%rax), %rdx
movsd %xmm0, (%rdx)
incq %rcx
addq $0x18, %rax
jmp 0x3368
xorpd %xmm0, %xmm0
leaq -0xa0(%rbp), %rdi
andq $0x0, 0x10(%rdi)
movapd %xmm0, (%rdi)
andq $0x0, -0x30(%rbp)
leaq -0x58(%rbp), %rsi
andq $0x0, (%rsi)
callq 0x47a4
imulq $0x18, %rbx, %rbx
xorl %r15d, %r15d
leaq -0x58(%rbp), %r12
leaq -0x78(%rbp), %r13
movsd 0x3c47(%rip), %xmm0     # 0x7008
andpd 0x3c47(%rip), %xmm0     # 0x7010
ucomisd -0x88(%rbp), %xmm0
jbe 0x34ae
movq -0x70(%rbp), %rax
xorl %ecx, %ecx
cmpq %rcx, %rbx
je 0x341b
movq (%rax), %rdx
movsd (%rdx), %xmm1
movsd %xmm1, -0x30(%rbp)
movq (%rax,%rcx), %rdx
movsd (%rdx), %xmm0
movapd %xmm0, %xmm2
movapd 0x3c0e(%rip), %xmm3     # 0x7010
andpd %xmm3, %xmm2
andpd %xmm3, %xmm1
ucomisd %xmm1, %xmm2
jb 0x3415
movsd %xmm0, -0x30(%rbp)
addq $0x18, %rcx
jmp 0x33dd
cmpq $0x7a11f, %r15          # imm = 0x7A11F
je 0x34f6
leaq -0xa0(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3ae0
leaq 0x1(%r15), %r14
movq -0xa0(%rbp), %rax
movsd (%rax,%r14,8), %xmm0
subsd (%rax,%r15,8), %xmm0
movapd %xmm0, -0xb0(%rbp)
movsd -0x30(%rbp), %xmm0
movq %r12, %rdi
movq %r13, %rsi
callq 0x2f16
movq %r13, %rdi
movq %r12, %rsi
callq 0x3aba
leaq -0x50(%rbp), %rdi
callq 0x3978
movq %r12, %rdi
movq -0x80(%rbp), %rsi
movq %r13, %rdx
callq 0x2ac4
movq %r13, %rdi
movq %r12, %rsi
callq 0x3aba
leaq -0x50(%rbp), %rdi
callq 0x3978
movq %r14, %r15
movapd -0xb0(%rbp), %xmm0
jmp 0x33c1
movsd -0x30(%rbp), %xmm0
leaq -0x58(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x2f16
leaq -0x78(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x3aba
leaq -0x50(%rbp), %rdi
callq 0x3978
movq -0x38(%rbp), %rdi
andl $0x0, (%rdi)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x8(%rdi)
addq $0x10, %rdi
leaq -0x78(%rbp), %rsi
callq 0x27fc
jmp 0x3535
movq 0x7adb(%rip), %rdi      # 0xafd8
leaq 0x3bbd(%rip), %rsi      # 0x70c1
callq 0x21b0
movq 0x7ac8(%rip), %rdi      # 0xafd8
leaq 0x3bdc(%rip), %rsi      # 0x70f3
callq 0x21b0
movq -0x38(%rbp), %rdi
orl $-0x1, (%rdi)
andq $0x0, 0x8(%rdi)
addq $0x10, %rdi
leaq -0x78(%rbp), %rsi
callq 0x27fc
leaq -0xa0(%rbp), %rdi
callq 0x4456
leaq -0x70(%rbp), %rdi
callq 0x3978
movq -0x38(%rbp), %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x357e
jmp 0x3570
jmp 0x357e
jmp 0x357e
jmp 0x357e
jmp 0x357e
jmp 0x3570
jmp 0x357e
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x3978
jmp 0x3581
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x4456
leaq -0x70(%rbp), %rdi
callq 0x3978
movq %rbx, %rdi
callq 0x22c0