// File: jmmccracken[P]PAI/ccmsrc.cpp
// Function: FindLagTimeStep(double*, int, int, double, bool)
int FindLagTimeStep(double dX[],int iXlength,int iMaxAutoCorrToCheck,double dCompareTolerance,bool bVerboseFlag){

    if( iMaxAutoCorrToCheck > (iXlength/2) ){
        fprintf(stderr, "Warning in FindLagTimeStep(): the maximum autocorreltaion lag is half the library length; ignoring requested value and checking to a lag of half the library length\n");
        iMaxAutoCorrToCheck = (iXlength/2);
    }

    double dAutoCorrs[iMaxAutoCorrToCheck],
           dCurrentAutoCorr = 0;
    int iTempVecLength = 0;

    //Calculate autocorrelations
    if( bVerboseFlag ){
            fprintf(stderr,"-- FindLagTimeStep() verbose output begin --\n");
    }
    for(int iAutoCorrLagStep = 1;iAutoCorrLagStep <= iMaxAutoCorrToCheck;iAutoCorrLagStep++ ){

        iTempVecLength = iXlength-iAutoCorrLagStep;
        double dXtemp1[iTempVecLength],dXtemp2[iTempVecLength];

        for(int iTempVecBuildStep=0;iTempVecBuildStep < iTempVecLength;iTempVecBuildStep++ ){
            dXtemp1[iTempVecBuildStep] = dX[iTempVecBuildStep];
            dXtemp2[iTempVecBuildStep] = dX[iTempVecBuildStep+iAutoCorrLagStep];
        }

        dCurrentAutoCorr = Pcorr(dXtemp1,dXtemp2,iTempVecLength);
        dAutoCorrs[iAutoCorrLagStep-1] = dCurrentAutoCorr*dCurrentAutoCorr;
        if( bVerboseFlag ){
            fprintf(stderr,"%.20f\n",dAutoCorrs[iAutoCorrLagStep-1]);
        }
    }
    if( bVerboseFlag ){
            fprintf(stderr,"-- FindLagTimeStep() verbose output end --\n");
    }

    //Find max
    int iCurrentMaxAutoCorrLag = 1;
    dCurrentAutoCorr = dAutoCorrs[0];
    for(int iter = 1;iter < iMaxAutoCorrToCheck;iter++ ){

        if( fabs(dAutoCorrs[iter]-dCurrentAutoCorr) < dCompareTolerance ){
            fprintf(stderr, "Warning in FindLagTimeStep(): autocorrelations may be cyclic; run with verbose flag to see all the autocorrelations\n");
        }

    if( fabs(dCurrentAutoCorr-1) < dCompareTolerance ){
            fprintf(stderr, "Warning in FindLagTimeStep(): autocorrelations may be near unity; run with verbose flag to see all the autocorrelations\n");
        }

        if( dAutoCorrs[iter] > dCurrentAutoCorr ){
            dCurrentAutoCorr = dAutoCorrs[iter];
            iCurrentMaxAutoCorrLag = iter+1;
        }
    }

    return(iCurrentMaxAutoCorrLag);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movb %cl, %al
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movsd %xmm0, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
movl -0x10(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0xc(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0x68(%rbp), %eax
cmpl %ecx, %eax
jle 0x34d1
movq 0x15b16(%rip), %rax     # 0x18fc8
movq (%rax), %rdi
leaq 0xcb74(%rip), %rsi      # 0x10030
movb $0x0, %al
callq 0x32a0
movl -0xc(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %eax
movq %rsp, %rcx
movq %rcx, -0x28(%rbp)
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x70(%rbp)
movq %rcx, %rsp
movq %rax, -0x30(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
testb $0x1, -0x19(%rbp)
je 0x3525
movq 0x15ab4(%rip), %rax     # 0x18fc8
movq (%rax), %rdi
leaq 0xcbb7(%rip), %rsi      # 0x100d5
movb $0x0, %al
callq 0x32a0
movl $0x1, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x10(%rbp), %eax
jg 0x3653
movl -0xc(%rbp), %eax
movl -0x40(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movq %rsp, %rcx
movq %rcx, -0x48(%rbp)
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x80(%rbp)
movq %rcx, %rsp
movq %rax, -0x50(%rbp)
movl -0x3c(%rbp), %eax
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x78(%rbp)
movq %rcx, %rsp
movq %rax, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0x35dd
movq -0x78(%rbp), %rax
movq -0x80(%rbp), %rcx
movq -0x8(%rbp), %rdx
movslq -0x5c(%rbp), %rsi
movsd (%rdx,%rsi,8), %xmm0
movslq -0x5c(%rbp), %rdx
movsd %xmm0, (%rcx,%rdx,8)
movq -0x8(%rbp), %rcx
movl -0x5c(%rbp), %edx
addl -0x40(%rbp), %edx
movslq %edx, %rdx
movsd (%rcx,%rdx,8), %xmm0
movslq -0x5c(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x3591
movq -0x78(%rbp), %rsi
movq -0x80(%rbp), %rdi
movl -0x3c(%rbp), %edx
callq 0x3770
movq -0x70(%rbp), %rax
movsd %xmm0, -0x38(%rbp)
movsd -0x38(%rbp), %xmm0
mulsd -0x38(%rbp), %xmm0
movl -0x40(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
testb $0x1, -0x19(%rbp)
je 0x363e
movq -0x70(%rbp), %rax
movq 0x159a9(%rip), %rcx     # 0x18fc8
movq (%rcx), %rdi
movl -0x40(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
leaq 0xcacc(%rip), %rsi      # 0x10103
movb $0x1, %al
callq 0x32a0
movq -0x48(%rbp), %rax
movq %rax, %rsp
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x352c
testb $0x1, -0x19(%rbp)
je 0x3671
movq 0x15968(%rip), %rax     # 0x18fc8
movq (%rax), %rdi
leaq 0xcaa0(%rip), %rsi      # 0x1010a
movb $0x0, %al
callq 0x32a0
movq -0x70(%rbp), %rax
movl $0x1, -0x60(%rbp)
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movl $0x1, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x10(%rbp), %eax
jge 0x3756
movq -0x70(%rbp), %rax
movslq -0x64(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
subsd -0x38(%rbp), %xmm1
movaps 0xc95f(%rip), %xmm0     # 0x10010
pand %xmm0, %xmm1
movsd -0x18(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x36d8
movq 0x15901(%rip), %rax     # 0x18fc8
movq (%rax), %rdi
leaq 0xca65(%rip), %rsi      # 0x10136
movb $0x0, %al
callq 0x32a0
movsd -0x38(%rbp), %xmm1
movsd 0xc93b(%rip), %xmm0     # 0x10020
subsd %xmm0, %xmm1
movaps 0xc920(%rip), %xmm0     # 0x10010
pand %xmm0, %xmm1
movsd -0x18(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x3717
movq 0x158c2(%rip), %rax     # 0x18fc8
movq (%rax), %rdi
leaq 0xca9b(%rip), %rsi      # 0x101ab
movb $0x0, %al
callq 0x32a0
movq -0x70(%rbp), %rax
movslq -0x64(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd -0x38(%rbp), %xmm0
jbe 0x3746
movq -0x70(%rbp), %rax
movslq -0x64(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x38(%rbp)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x3748
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x368c
movl -0x60(%rbp), %eax
movq -0x28(%rbp), %rcx
movq %rcx, %rsp
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)