// File: /workspace/github_c_makefile_star2_O0/debbiemarkslab[P]plmc/src/inference.c
// Function: EstimatePairModelMAP
void EstimatePairModelMAP(numeric_t *x, numeric_t *lambdas, alignment_t *ali,
    options_t *options) {
    /* Computes Maximum a posteriori (MAP) estimates for the parameters of 
       and undirected graphical model by L-BFGS */

    /* Start timer */
    gettimeofday(&ali->start, NULL);

    /* Initialize L-BFGS */
    lbfgs_parameter_t param;
    lbfgs_parameter_init(&param);
    param.epsilon = 1E-3;
    param.max_iterations = options->maxIter; /* 0 is unbounded */

    /* Estimate parameters by optimization */
    static lbfgs_evaluate_t algo;
    switch(options->estimatorMAP) {
        case INFER_MAP_PLM:
            algo = PLMNegLogPosterior;
            break;
        case INFER_MAP_PLM_GAPREDUCE:
            algo = PLMNegLogPosteriorGapReduce;
            break;
        case INFER_MAP_PLM_BLOCK:
            algo = PLMNegLogPosteriorBlock;
            break;
        case INFER_MAP_PLM_DROPOUT:
            algo = PLMNegLogPosteriorDO;
            break;
        default:
            algo = PLMNegLogPosterior;
    }

    if (options->zeroAPC == 1) fprintf(stderr,
            "Estimating coupling hyperparameters le = 1/2 inverse variance\n");

    /* Problem instance in void array */
    void *d[3] = {(void *)ali, (void *)options, (void *)lambdas};

    if (options->sgd == 1) {
        /* Scale hyperparams for minibatch */
        numeric_t scale = (numeric_t) options->sgdBatchSize / ali->nEff;
        options->lambdaGroup *= scale;
        for (int i = 0; i < ali->nSites; i++) lambdaHi(i) *= scale;
        for (int i = 0; i < ali->nSites - 1; i++)
            for (int j = i + 1; j < ali->nSites; j++)
                lambdaEij(i, j) *= scale;

        /* SGD optimization */
        numeric_t crit = 0.01;
        void *d[4] = {(void *)ali, (void *)options, (void *)lambdas, (void *) algo};
        SGDOptimize(SGDWrapperPLM, d, x, ali->nParams, options->maxIter, crit);

        /* Unscale hyperparams for minibatch */
        numeric_t invScale = ali->nEff / (numeric_t) options->sgdBatchSize;
        options->lambdaGroup *= invScale;
        for (int i = 0; i < ali->nSites; i++) lambdaHi(i) *= invScale;
        for (int i = 0; i < ali->nSites - 1; i++)
            for (int j = i + 1; j < ali->nSites; j++)
                lambdaEij(i, j) *= invScale;
    } else {
        /* L-BFGS optimization */
        int ret = 0;
        lbfgsfloatval_t fx;
        ret = lbfgs(ali->nParams, x, &fx, algo, ReportProgresslBFGS,
            (void*)d, &param);
        fprintf(stderr, "Gradient optimization: %s\n", LBFGSErrorString(ret));
    }

    /* Optionally re-estimate parameters with adjusted hyperparameters */
    if (options->zeroAPC == 1) {
        /* Form new priors on the variances */
        ZeroAPCPriors(ali, options, lambdas, x);

        /* Reinitialize coupling parameters */
        for (int i = 0; i < ali->nSites - 1; i++)
            for (int j = i + 1; j < ali->nSites; j++)
                for (int ai = 0; ai < ali->nCodes; ai++)
                    for (int aj = 0; aj < ali->nCodes; aj++)
                        xEij(i, j, ai, aj) = 0.0;

        /* Iterate estimation with new hyperparameter estimates */
        options->zeroAPC = 2;
        lbfgsfloatval_t fx2;
        int ret2 = lbfgs(ali->nParams, x, &fx2, algo,
            ReportProgresslBFGS, (void*)d, &param);
        fprintf(stderr, "Gradient optimization: %s\n", LBFGSErrorString(ret2));
    }
}

// Assembly:
subq $0x198, %rsp            # imm = 0x198
movq %rdi, 0x190(%rsp)
movq %rsi, 0x188(%rsp)
movq %rdx, 0x180(%rsp)
movq %rcx, 0x178(%rsp)
movq 0x180(%rsp), %rdi
addq $0x78, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x10e0
leaq 0x108(%rsp), %rdi
callq 0x1aa0
movabsq $0x3f50624dd2f1a9fc, %rax # imm = 0x3F50624DD2F1A9FC
movq %rax, 0x110(%rsp)
movq 0x178(%rsp), %rax
movl 0x1c(%rax), %eax
movl %eax, 0x128(%rsp)
movq 0x178(%rsp), %rax
movl 0x18(%rax), %eax
movq %rax, 0x68(%rsp)
subq $0x3, %rax
ja 0xa7c8
movq 0x68(%rsp), %rax
leaq 0xec89(%rip), %rcx      # 0x19408
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x811(%rip), %rax       # 0xafa0
movq %rax, 0x12d6a(%rip)     # 0x1d500
jmp 0xa7d6
leaq 0x27a1(%rip), %rax      # 0xcf40
movq %rax, 0x12d5a(%rip)     # 0x1d500
jmp 0xa7d6
leaq 0x48b1(%rip), %rax      # 0xf060
movq %rax, 0x12d4a(%rip)     # 0x1d500
jmp 0xa7d6
leaq 0x6531(%rip), %rax      # 0x10cf0
movq %rax, 0x12d3a(%rip)     # 0x1d500
jmp 0xa7d6
leaq 0x7d1(%rip), %rax       # 0xafa0
movq %rax, 0x12d2a(%rip)     # 0x1d500
movq 0x178(%rsp), %rax
cmpl $0x1, 0x58(%rax)
jne 0xa7fc
movq 0x1180d(%rip), %rax     # 0x1bff8
movq (%rax), %rdi
leaq 0xec5c(%rip), %rsi      # 0x19451
movb $0x0, %al
callq 0x1140
movq 0x180(%rsp), %rax
movq %rax, 0xf0(%rsp)
movq 0x178(%rsp), %rax
movq %rax, 0xf8(%rsp)
movq 0x188(%rsp), %rax
movq %rax, 0x100(%rsp)
movq 0x178(%rsp), %rax
cmpl $0x1, 0x20(%rax)
jne 0xac51
movq 0x178(%rsp), %rax
cvtsi2sdl 0x24(%rax), %xmm0
movq 0x180(%rsp), %rax
divsd 0x48(%rax), %xmm0
movsd %xmm0, 0xe8(%rsp)
movsd 0xe8(%rsp), %xmm0
movq 0x178(%rsp), %rax
mulsd 0x50(%rax), %xmm0
movsd %xmm0, 0x50(%rax)
movl $0x0, 0xe4(%rsp)
movl 0xe4(%rsp), %eax
movq 0x180(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0xa8d1
movsd 0xe8(%rsp), %xmm0
movq 0x188(%rsp), %rax
movslq 0xe4(%rsp), %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
jmp 0xa887
movl $0x0, 0xe0(%rsp)
movl 0xe0(%rsp), %eax
movq 0x180(%rsp), %rcx
movl 0x4(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0xa9fd
movl 0xe0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
movl 0xdc(%rsp), %eax
movq 0x180(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0xa9e5
movsd 0xe8(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0x188(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x180(%rsp), %rax
movl 0x4(%rax), %eax
movl %eax, 0x64(%rsp)
movl 0xe0(%rsp), %eax
cmpl 0xdc(%rsp), %eax
jge 0xa986
movl 0xdc(%rsp), %eax
movl 0xdc(%rsp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl 0xe0(%rsp), %eax
movl %eax, 0x4c(%rsp)
jmp 0xa9ad
movl 0xe0(%rsp), %eax
movl 0xe0(%rsp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl 0xdc(%rsp), %eax
movl %eax, 0x4c(%rsp)
movq 0x58(%rsp), %rax
movsd 0x50(%rsp), %xmm0
movl 0x64(%rsp), %ecx
movl 0x4c(%rsp), %edx
addl %edx, %ecx
movslq %ecx, %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl 0xdc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
jmp 0xa90a
jmp 0xa9e7
movl 0xe0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe0(%rsp)
jmp 0xa8dc
movsd 0xe70b(%rip), %xmm0     # 0x19110
movsd %xmm0, 0xd0(%rsp)
movq 0x180(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0x178(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0x188(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0x12abb(%rip), %rax     # 0x1d500
movq %rax, 0xc8(%rsp)
leaq 0xb0(%rsp), %rsi
movq 0x190(%rsp), %rdx
movq 0x180(%rsp), %rax
movl 0x68(%rax), %ecx
movq 0x178(%rsp), %rax
movl 0x1c(%rax), %r8d
movsd 0xd0(%rsp), %xmm0
leaq 0x8f5c(%rip), %rdi      # 0x139e0
callq 0x132c0
movq 0x180(%rsp), %rax
movsd 0x48(%rax), %xmm0
movq 0x178(%rsp), %rax
cvtsi2sdl 0x24(%rax), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0xa8(%rsp)
movsd 0xa8(%rsp), %xmm0
movq 0x178(%rsp), %rax
mulsd 0x50(%rax), %xmm0
movsd %xmm0, 0x50(%rax)
movl $0x0, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
movq 0x180(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0xab20
movsd 0xa8(%rsp), %xmm0
movq 0x188(%rsp), %rax
movslq 0xa4(%rsp), %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl 0xa4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa4(%rsp)
jmp 0xaad6
movl $0x0, 0xa0(%rsp)
movl 0xa0(%rsp), %eax
movq 0x180(%rsp), %rcx
movl 0x4(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0xac4c
movl 0xa0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
movl 0x9c(%rsp), %eax
movq 0x180(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0xac34
movsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x188(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x180(%rsp), %rax
movl 0x4(%rax), %eax
movl %eax, 0x48(%rsp)
movl 0xa0(%rsp), %eax
cmpl 0x9c(%rsp), %eax
jge 0xabd5
movl 0x9c(%rsp), %eax
movl 0x9c(%rsp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl 0xa0(%rsp), %eax
movl %eax, 0x34(%rsp)
jmp 0xabfc
movl 0xa0(%rsp), %eax
movl 0xa0(%rsp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl 0x9c(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0x40(%rsp), %rax
movsd 0x38(%rsp), %xmm0
movl 0x48(%rsp), %ecx
movl 0x34(%rsp), %edx
addl %edx, %ecx
movslq %ecx, %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0xab59
jmp 0xac36
movl 0xa0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa0(%rsp)
jmp 0xab2b
jmp 0xacd6
movl $0x0, 0x98(%rsp)
movq 0x180(%rsp), %rax
movl 0x68(%rax), %edi
movq 0x190(%rsp), %rsi
movq 0x1288a(%rip), %rcx     # 0x1d500
leaq 0xf0(%rsp), %r9
leaq 0x90(%rsp), %rdx
leaq 0x9313(%rip), %r8       # 0x13fa0
leaq 0x108(%rsp), %rax
movq %rax, (%rsp)
callq 0x1ac0
movl %eax, 0x98(%rsp)
movq 0x1134c(%rip), %rax     # 0x1bff8
movq (%rax), %rax
movq %rax, 0x28(%rsp)
movl 0x98(%rsp), %edi
callq 0x143b0
movq 0x28(%rsp), %rdi
movq %rax, %rdx
leaq 0xe7c1(%rip), %rsi      # 0x19490
movb $0x0, %al
callq 0x1140
movq 0x178(%rsp), %rax
cmpl $0x1, 0x58(%rax)
jne 0xaf8c
movq 0x180(%rsp), %rdi
movq 0x178(%rsp), %rsi
movq 0x188(%rsp), %rdx
movq 0x190(%rsp), %rcx
callq 0x147f0
movl $0x0, 0x8c(%rsp)
movl 0x8c(%rsp), %eax
movq 0x180(%rsp), %rcx
movl 0x4(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0xaf0c
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
movl 0x88(%rsp), %eax
movq 0x180(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0xaef4
movl $0x0, 0x84(%rsp)
movl 0x84(%rsp), %eax
movq 0x180(%rsp), %rcx
cmpl 0x8(%rcx), %eax
jge 0xaedc
movl $0x0, 0x80(%rsp)
movl 0x80(%rsp), %eax
movq 0x180(%rsp), %rcx
cmpl 0x8(%rcx), %eax
jge 0xaec4
movq 0x190(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x180(%rsp), %rax
movl 0x4(%rax), %eax
movq 0x180(%rsp), %rcx
imull 0x8(%rcx), %eax
movl %eax, 0x24(%rsp)
movl 0x8c(%rsp), %eax
cmpl 0x88(%rsp), %eax
jge 0xae39
movl 0x88(%rsp), %eax
movl 0x88(%rsp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl 0x8c(%rsp), %eax
movq 0x180(%rsp), %rcx
imull 0x8(%rcx), %eax
movq 0x180(%rsp), %rcx
imull 0x8(%rcx), %eax
movl 0x80(%rsp), %ecx
movq 0x180(%rsp), %rdx
imull 0x8(%rdx), %ecx
addl %ecx, %eax
addl 0x84(%rsp), %eax
movl %eax, 0x14(%rsp)
jmp 0xae94
movl 0x8c(%rsp), %eax
movl 0x8c(%rsp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
movl $0x2, %ecx
cltd
idivl %ecx
addl 0x88(%rsp), %eax
movq 0x180(%rsp), %rcx
imull 0x8(%rcx), %eax
movq 0x180(%rsp), %rcx
imull 0x8(%rcx), %eax
movl 0x84(%rsp), %ecx
movq 0x180(%rsp), %rdx
imull 0x8(%rdx), %ecx
addl %ecx, %eax
addl 0x80(%rsp), %eax
movl %eax, 0x14(%rsp)
movq 0x18(%rsp), %rax
movl 0x24(%rsp), %ecx
movl 0x14(%rsp), %edx
addl %edx, %ecx
movslq %ecx, %rcx
xorps %xmm0, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl 0x80(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x80(%rsp)
jmp 0xad8c
jmp 0xaec6
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0xad69
jmp 0xaede
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0xad46
jmp 0xaef6
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0xad18
movq 0x178(%rsp), %rax
movl $0x2, 0x58(%rax)
movq 0x180(%rsp), %rax
movl 0x68(%rax), %edi
movq 0x190(%rsp), %rsi
movq 0x125cb(%rip), %rcx     # 0x1d500
leaq 0xf0(%rsp), %r9
leaq 0x78(%rsp), %rdx
leaq 0x9057(%rip), %r8       # 0x13fa0
leaq 0x108(%rsp), %rax
movq %rax, (%rsp)
callq 0x1ac0
movl %eax, 0x74(%rsp)
movq 0x11093(%rip), %rax     # 0x1bff8
movq (%rax), %rax
movq %rax, 0x8(%rsp)
movl 0x74(%rsp), %edi
callq 0x143b0
movq 0x8(%rsp), %rdi
movq %rax, %rdx
leaq 0xe50b(%rip), %rsi      # 0x19490
movb $0x0, %al
callq 0x1140
addq $0x198, %rsp            # imm = 0x198
retq
nopw %cs:(%rax,%rax)