// File: /workspace/github_cpp_makefile_star2_O2/bobverity[P]MavericK/misc.cpp
// Function: calculateAutoCorr(std::vector<double, std::allocator<double>>&)
double calculateAutoCorr(vector<double> &v) {
    
    // get basic properties of vector
    int v_size = int(v.size());
    double mu = mean(v);
    double sigma2 = var(v);
    
    // calculate x range over which autocorrelation will be calculated
    vector<int> x;
    int x_largest = 0;
    int dx = 1;
    bool break_on = false;
    for (int l=0; l<100; l++) {
        for (int j=0; j<100; j++) {
            x_largest += dx;
            if (x_largest>v_size) {
                break_on = true;
                break;
            }
            x.push_back(x_largest);
        }
        if (break_on) {
            break;
        }
        dx *= 2;
    }
    
    // calculate raw autocorrelation
    int x_size = int(x.size());
    vector<double> yy(x_size);
    vector<double> n(x_size);
    for (int i=0; i<v_size; i++) {
        for (int j=0; j<x_size; j++) {
            if ((i+x[j])>(v_size-1)) {
                continue;
            }
            yy[j] += (v[i]-mu)*(v[i+x[j]]-mu)/sigma2;
            n[j]++;
        }
    }
    for (int j=0; j<x_size; j++) {
        yy[j] /= double(n[j]);
    }
    
    // calculate total autocorrelation
    double autoCorr = yy[0];
    for (int i=1; i<x_size; i++) {
        dx = x[i]-x[i-1];
        if (yy[i]>0) {
            autoCorr += dx*yy[i-1] - 0.5*(dx+1)*(yy[i-1]-yy[i]);
        } else {
            dx = int(floor((dx*yy[i-1])/(yy[i-1]-yy[i])));
            autoCorr += dx*yy[i-1] - 0.5*(dx+1)*(yy[i-1]-yy[i]);
            break;
        }
    }
    autoCorr = 1 + 2*autoCorr;
    
    // correct for possible issues
    if (sigma2==0 || autoCorr<1)
        autoCorr = 1;
    
    return(autoCorr);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdi, %rbx
movq 0x8(%rdi), %r12
subq (%rdi), %r12
shrq $0x3, %r12
callq 0x14ada
movsd %xmm0, 0x40(%rsp)
pushq $0x1
popq %rbp
xorpd %xmm0, %xmm0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x14b15
movapd %xmm0, 0x10(%rsp)
leaq 0x20(%rsp), %r14
andq $0x0, 0x10(%r14)
leaq 0x4(%rsp), %r15
andl $0x0, (%r15)
xorpd %xmm0, %xmm0
movapd %xmm0, (%r14)
xorl %eax, %eax
movl %eax, 0x8(%rsp)
cmpl $0x64, %eax
je 0x162ad
pushq $0x64
popq %r13
subl $0x1, %r13d
jb 0x162a3
movl 0x4(%rsp), %eax
addl %ebp, %eax
movl %eax, 0x4(%rsp)
cmpl %r12d, %eax
jg 0x162ad
movq %r14, %rdi
movq %r15, %rsi
callq 0x5f5e
jmp 0x16281
addl %ebp, %ebp
movl 0x8(%rsp), %eax
incl %eax
jmp 0x16274
movq 0x28(%rsp), %r15
subq 0x20(%rsp), %r15
shrq $0x2, %r15
movslq %r15d, %r14
leaq 0x58(%rsp), %rdi
leaq 0x70(%rsp), %rdx
movq %r14, %rsi
callq 0x4f6c
leaq 0x70(%rsp), %rdi
leaq 0x3(%rsp), %rdx
movq %r14, %rsi
callq 0x4f6c
xorl %ecx, %ecx
testl %r15d, %r15d
movl $0x0, %eax
cmovgl %r15d, %eax
testl %r12d, %r12d
movl $0x0, %edx
cmovgl %r12d, %edx
movsd 0x10f0c(%rip), %xmm4    # 0x27210
movsd 0x40(%rsp), %xmm2
cmpq %rdx, %rcx
je 0x1637b
movq 0x20(%rsp), %rsi
movq (%rbx), %rdi
movq 0x58(%rsp), %r8
movq 0x70(%rsp), %r9
movslq %ecx, %r10
xorl %r11d, %r11d
cmpq %r11, %rax
je 0x16376
movslq (%rsi,%r11,4), %r14
addq %r10, %r14
cmpl %r12d, %r14d
jge 0x16371
movsd (%rdi,%rcx,8), %xmm0
subsd %xmm2, %xmm0
movsd (%rdi,%r14,8), %xmm1
subsd %xmm2, %xmm1
mulsd %xmm0, %xmm1
divsd 0x10(%rsp), %xmm1
addsd (%r8,%r11,8), %xmm1
movsd %xmm1, (%r8,%r11,8)
movsd (%r9,%r11,8), %xmm0
addsd %xmm4, %xmm0
movsd %xmm0, (%r9,%r11,8)
incq %r11
jmp 0x16327
incq %rcx
jmp 0x1630a
movq 0x70(%rsp), %rcx
movq 0x58(%rsp), %rdx
xorl %esi, %esi
cmpq %rsi, %rax
je 0x163a0
movsd (%rdx,%rsi,8), %xmm0
divsd (%rcx,%rsi,8), %xmm0
movsd %xmm0, (%rdx,%rsi,8)
incq %rsi
jmp 0x16387
movq 0x58(%rsp), %rax
movsd (%rax), %xmm5
movq 0x20(%rsp), %rcx
movslq %r15d, %rdx
pushq $0x1
popq %rsi
xorpd %xmm1, %xmm1
movsd 0x11730(%rip), %xmm2    # 0x27af0
cmpq %rdx, %rsi
jge 0x16467
movl (%rcx,%rsi,4), %edi
subl -0x4(%rcx,%rsi,4), %edi
movsd -0x8(%rax,%rsi,8), %xmm6
movsd (%rax,%rsi,8), %xmm3
ucomisd %xmm1, %xmm3
cvtsi2sd %edi, %xmm0
movapd %xmm6, %xmm7
subsd %xmm3, %xmm7
jbe 0x1640c
incl %edi
cvtsi2sd %edi, %xmm3
mulsd %xmm2, %xmm3
mulsd %xmm7, %xmm3
mulsd %xmm6, %xmm0
addsd %xmm3, %xmm0
addsd %xmm0, %xmm5
incq %rsi
jmp 0x163c0
mulsd %xmm6, %xmm0
divsd %xmm7, %xmm0
movapd %xmm5, 0x40(%rsp)
movsd %xmm6, 0x8(%rsp)
movsd %xmm7, 0x50(%rsp)
callq 0x3530
movapd 0x40(%rsp), %xmm5
movsd 0x10dd7(%rip), %xmm4    # 0x27210
cvttsd2si %xmm0, %eax
cvttpd2dq %xmm0, %xmm0
cvtdq2pd %xmm0, %xmm0
incl %eax
cvtsi2sd %eax, %xmm1
mulsd 0x1169d(%rip), %xmm1    # 0x27af0
mulsd 0x50(%rsp), %xmm1
mulsd 0x8(%rsp), %xmm0
addsd %xmm1, %xmm0
addsd %xmm0, %xmm5
addsd %xmm5, %xmm5
addsd %xmm4, %xmm5
xorpd %xmm0, %xmm0
cmpeqpd 0x10(%rsp), %xmm0
movapd %xmm5, %xmm1
cmpltpd %xmm4, %xmm1
orpd %xmm0, %xmm1
movd %xmm1, %eax
testb $0x1, %al
jne 0x16493
movapd %xmm5, %xmm4
movapd %xmm4, 0x10(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x51a2
leaq 0x58(%rsp), %rdi
callq 0x51a2
leaq 0x20(%rsp), %rdi
callq 0x61d0
movaps 0x10(%rsp), %xmm0
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x51a2
jmp 0x164e2
jmp 0x164df
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x61d0
movq %rbx, %rdi
callq 0x35a0