// File: /workspace/github_c_makefile_star2_O0/waynebhayes[P]SAHap/src/Genome.cpp
// Function: SAHap::Genome::DynamicSchedule(double, double)
void Genome::DynamicSchedule(double pBad, double TARGET_MEC)
{
    //printf("pBad %ld %g\n", this->pBad.len, pBad);
#if SCHEDULE==RETREAT
/*
This schedule seems to be about right... up to 1500 SNPs. Then it fails.  Observations:
- There are a lot of magic numbers here. I think it may be possible to simplify. Ideas:
- it looks like maintaing a ration of about 10x as many 1% retreats as 95% retreats; automating that may help.
- the locations in time (fracTime and pBad) do NOT seem very flexible; you can play with what tolerances
you want at those times/pBad's, but if you shift the times or pBads too much, it all falls apart.
- decreasing the threshold (ie., tightening the tolerance) on the 1% retreats can reduce the 95% retreats,
but if you tighten it too much it never gets past 30% fracTime.
- having the first threhold too loose results in way to many 95% retreats. (ie complete restart)
- oddly, increasing the number of meta-iterations on the command line does not always help; then the retreats
are all mis-calibrated, and we never get past 30% fracTime. So again, something to automatically calibrate
them seems necessary.
- there doesn't seem to be much of a difference between optimizing MEC vs Possion. Poisson is a bit slower but
doesn't seem to give any better aswers.
- the dead-ends seem REALLY tight: sometimes you can still have 90% distance from ground truth even with the MEC
being less than a factor for two from the TARGE_MEC!!! That seems *really* strange. Is that even possible?
Perhaps the data is fucked up? It just seems so unlikely the MEC can be almost to the target while we're
still TOTALLY wrong compared to ground truth. For example, optimizing 2100SNP case, target was 614:
598k (93.4%,74s)  T 0.000  fA 0.004  pBad 0.001  MEC 850 ( Err_vs_truth 1955 Err_Pct 93.10% [2100 2100])
599k (93.6%,74s)  T 0.000  fA 0.000  pBad 0.001  MEC 851 ( Err_vs_truth 1954 Err_Pct 93.05% [2100 2100])
600k (93.8%,74s)  T 0.000  fA 0.000  pBad 0.001  MEC 852 ( Err_vs_truth 1956 Err_Pct 93.14% [2100 2100])
601k (93.9%,74s)  T 0.000  fA 0.000  pBad 0.001  MEC 852 ( Err_vs_truth 1956 Err_Pct 93.14% [2100 2100])
602k (94.1%,74s)  T 0.000  fA 0.001  pBad 0.001  MEC 852 ( Err_vs_truth 1954 Err_Pct 93.05% [2100 2100])
Retreat 94% from 94.0625% to 0.0625% because MEC is 852, too big by factor of 1.38762
We're only a factor of 1.387 above the target MEC and we're still 93% wrong compared to the ground truth??? WTF?

- again with ground truth... sometimes we converge to exactly the right ground truth yet the MEC is still large.
Again, how is that possible?  For example, here's a sequence of final lines to a good solution: (target was 268)
49k (61.3%,159s)  T 0.002  fA 0.009  pBad 0.011  MEC   264  ( Err_vs_truth     0 Err_Pct 0.00% [1000 1000])
50k (62.5%,159s)  T 0.002  fA 0.015  pBad 0.015  MEC   272  ( Err_vs_truth     0 Err_Pct 0.00% [1000 1000])
51k (63.7%,159s)  T 0.002  fA 0.011  pBad 0.009  MEC   260  ( Err_vs_truth     0 Err_Pct 0.00% [1000 1000])
How can the MEC continue to decrease while the Err_vs_truth remains exactly zero? No fucking way. There is a
unique solution---all the reads on the correct side. That solution has a fixed MEC. Can't have one change while
the other remain constant.
*/
    double retreat = 0.0;
    static double prev_retreat_frac;
    int num_meta_iters = this->maxIterations/META_ITER;
#define SMALL_RETREAT 0.01 // Let it grow with number of meta-iters? (0.01*(1+2*log(num_meta_iters)))
#define FULL_RETREAT 0.94 // this needs to be less than (1-(REPORT_INTERVAL/2)) from the next line
    if(curIteration % (REPORT_INTERVAL/2) == 0) {
	double factor = (double)windowMEC()/TARGET_MEC;
	// double factor = (double)pmec()/(TARGET_MEC == 0 ? 0.5 : TARGET_MEC);
	if(fracTime() - prev_retreat_frac > 2*SMALL_RETREAT &&
	    (((fracTime()>0.3||pBad<0.2) && factor > 16) ||   // 14 to 22 seems to work well
	     ((fracTime()>0.5||pBad<0.1) && factor >  8) )){  // quarter to half the above works well?
	    retreat = factor * SMALL_RETREAT / meanCoverage() * log(num_meta_iters);
	}
	if(fracTime()>FULL_RETREAT && factor > 1.3) {//pmec() != 0){
	    retreat = FULL_RETREAT;
	    ResetBuffers();
	}
	if(retreat > 0.0) {
	    cout << "Retreat " << 100*retreat << "% from " << 100 * fracTime();
	    this->curIteration -= retreat * this->maxIterations;
	    assert(this->curIteration>=0);
	    cout << "% to "  << 100 * fracTime() << "% because MEC is " << windowMEC();
	    cout << ", too big by a factor of " << factor << "(" << TARGET_MEC << 
			", " << windowTotalCoverage() << ")" << endl;
	    prev_retreat_frac = fracTime();
	}
    }
#elif SCHEDULE==Betz
    static double computedTdecay, LOWER=atof(getenv("LOWER")),
	ACCEPT_TARGET=atof(getenv("ACCEPT_TARGET")), PBAD_TARGET=atof(getenv("PBAD_TARGET"));
    if(!computedTdecay){
	computedTdecay = this->tDecay;
	printf("Betz values: LOWER %g ACCEPT_TARGET %g PBAD_TARGET %g\n",LOWER,ACCEPT_TARGET,PBAD_TARGET);
    }
    if(this->curIteration > this->fAccept.LENGTH) {
	this->tDecay = computedTdecay * (LOWER +
	    min(fabs(ACCEPT_TARGET-this->fAccept.getAverage()), fabs(PBAD_TARGET-this->pBad.getAverage())));
    }
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movsd %xmm0, -0x10(%rbp)
movsd %xmm1, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x20(%rbp)
movq 0x3bd8(%rax), %rax
movl $0x2710, %ecx           # imm = 0x2710
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0x38(%rbp), %rax
movl %ecx, -0x24(%rbp)
movq 0x3be0(%rax), %rax
movl $0x1f4, %ecx            # imm = 0x1F4
xorl %edx, %edx
divq %rcx
cmpq $0x0, %rdx
jne 0x4607
movq -0x38(%rbp), %rdi
callq 0x2e90
movq -0x38(%rbp), %rdi
divsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
callq 0x3b80
subsd 0x26fd0(%rip), %xmm0    # 0x2b2c0
movsd 0x17d70(%rip), %xmm1    # 0x1c068
ucomisd %xmm1, %xmm0
jbe 0x43b9
movq -0x38(%rbp), %rdi
callq 0x3b80
movsd 0x17d5d(%rip), %xmm1    # 0x1c070
ucomisd %xmm1, %xmm0
ja 0x4328
movsd 0x17d57(%rip), %xmm0    # 0x1c078
ucomisd -0x10(%rbp), %xmm0
jbe 0x433b
movsd -0x30(%rbp), %xmm0
movsd 0x17d4b(%rip), %xmm1    # 0x1c080
ucomisd %xmm1, %xmm0
ja 0x4374
movq -0x38(%rbp), %rdi
callq 0x3b80
movsd 0x17d14(%rip), %xmm1    # 0x1c060
ucomisd %xmm1, %xmm0
ja 0x4361
movsd 0x17d2e(%rip), %xmm0    # 0x1c088
ucomisd -0x10(%rbp), %xmm0
jbe 0x43b9
movsd -0x30(%rbp), %xmm0
movsd 0x17d22(%rip), %xmm1    # 0x1c090
ucomisd %xmm1, %xmm0
jbe 0x43b9
movq -0x38(%rbp), %rdi
movsd 0x17d18(%rip), %xmm0    # 0x1c098
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
callq 0x3060
movaps %xmm0, %xmm1
movsd -0x48(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movl -0x24(%rbp), %edi
callq 0x63a0
movaps %xmm0, %xmm1
movsd -0x40(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rbp)
movq -0x38(%rbp), %rdi
callq 0x3b80
movsd 0x17cd6(%rip), %xmm1    # 0x1c0a0
ucomisd %xmm1, %xmm0
jbe 0x43f9
movsd -0x30(%rbp), %xmm0
movsd 0x17ccb(%rip), %xmm1    # 0x1c0a8
ucomisd %xmm1, %xmm0
jbe 0x43f9
movq -0x38(%rbp), %rdi
movsd 0x17cb1(%rip), %xmm0    # 0x1c0a0
movsd %xmm0, -0x20(%rbp)
callq 0x3be0
movsd -0x20(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x4605
movq 0x26bb6(%rip), %rdi     # 0x2afc8
leaq 0x18126(%rip), %rsi     # 0x1c53f
callq 0x2230
movq %rax, %rdi
movsd -0x20(%rbp), %xmm0
movsd 0x17c82(%rip), %xmm1    # 0x1c0b0
movsd %xmm1, -0x58(%rbp)
mulsd %xmm1, %xmm0
callq 0x2460
movq %rax, %rdi
leaq 0x18102(%rip), %rsi     # 0x1c548
callq 0x2230
movq -0x38(%rbp), %rdi
movq %rax, -0x50(%rbp)
callq 0x3b80
movsd -0x58(%rbp), %xmm1
movq -0x50(%rbp), %rdi
mulsd %xmm1, %xmm0
callq 0x2460
movq -0x38(%rbp), %rax
movsd -0x20(%rbp), %xmm1
movq 0x3bd8(%rax), %xmm2
movaps 0x17b8e(%rip), %xmm4    # 0x1c010
punpckldq %xmm4, %xmm2    # xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
movapd 0x17b92(%rip), %xmm3    # 0x1c020
subpd %xmm3, %xmm2
movaps %xmm2, %xmm0
unpckhpd %xmm2, %xmm2            # xmm2 = xmm2[1,1]
addsd %xmm0, %xmm2
movq 0x3be0(%rax), %xmm0
punpckldq %xmm4, %xmm0    # xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1]
subpd %xmm3, %xmm0
movaps %xmm0, %xmm3
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm3, %xmm0
mulsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movaps %xmm0, %xmm1
cvttsd2si %xmm1, %rcx
movq %rcx, %rsi
sarq $0x3f, %rsi
movsd 0x17be1(%rip), %xmm1    # 0x1c0b8
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rdx
andq %rsi, %rdx
orq %rdx, %rcx
movq %rcx, 0x3be0(%rax)
cmpq $0x0, 0x3be0(%rax)
jb 0x44f9
jmp 0x4518
leaq 0x18050(%rip), %rdi     # 0x1c550
leaq 0x17c54(%rip), %rsi     # 0x1c15b
movl $0x28a, %edx            # imm = 0x28A
leaq 0x18053(%rip), %rcx     # 0x1c566
callq 0x2180
movq 0x26aa9(%rip), %rdi     # 0x2afc8
leaq 0x18074(%rip), %rsi     # 0x1c59a
callq 0x2230
movq -0x38(%rbp), %rdi
movq %rax, -0x70(%rbp)
callq 0x3b80
movq -0x70(%rbp), %rdi
movaps %xmm0, %xmm1
movsd 0x17b69(%rip), %xmm0    # 0x1c0b0
mulsd %xmm1, %xmm0
callq 0x2460
movq %rax, %rdi
leaq 0x18046(%rip), %rsi     # 0x1c5a0
callq 0x2230
movq -0x38(%rbp), %rdi
movq %rax, -0x68(%rbp)
callq 0x2e90
movq -0x68(%rbp), %rdi
callq 0x2460
movq 0x26a4c(%rip), %rdi     # 0x2afc8
leaq 0x1802f(%rip), %rsi     # 0x1c5b2
callq 0x2230
movq %rax, %rdi
movsd -0x30(%rbp), %xmm0
callq 0x2460
movq %rax, %rdi
leaq 0x1802d(%rip), %rsi     # 0x1c5cc
callq 0x2230
movq %rax, %rdi
movsd -0x18(%rbp), %xmm0
callq 0x2460
movq %rax, %rdi
leaq 0x18013(%rip), %rsi     # 0x1c5ce
callq 0x2230
movq -0x38(%rbp), %rdi
movq %rax, -0x60(%rbp)
callq 0x30f0
movq -0x60(%rbp), %rdi
callq 0x2460
movq %rax, %rdi
leaq 0x17baf(%rip), %rsi     # 0x1c18f
callq 0x2230
movq %rax, %rdi
movq 0x269c1(%rip), %rsi     # 0x2afb0
callq 0x2270
movq -0x38(%rbp), %rdi
callq 0x3b80
movsd %xmm0, 0x26cbb(%rip)    # 0x2b2c0
jmp 0x4607
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax)