// File: /workspace/github_c_makefile_star2_O1/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:
movabsq $0x346dc5d63886594b, %rax # imm = 0x346DC5D63886594B
mulq 0x3bd8(%rdi)
movabsq $0x1cac083126e978d5, %rax # imm = 0x1CAC083126E978D5
imulq 0x3be0(%rdi), %rax
rorq $0x2, %rax
movabsq $0x83126e978d4fdf, %rcx # imm = 0x83126E978D4FDF
cmpq %rcx, %rax
jbe 0x3ec9
retq
pushq %r15
pushq %r14
pushq %rbx
subq $0x20, %rsp
movq %rdi, %rbx
movq %rdx, %r14
movapd %xmm0, (%rsp)
movsd %xmm1, 0x18(%rsp)
callq 0x2fe2
movsd 0x18(%rsp), %xmm4
movapd %xmm0, %xmm5
divsd %xmm4, %xmm5
movsd 0x3be0(%rbx), %xmm1
movsd 0x71ba(%rip), %xmm2     # 0xb0c0
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x71bf(%rip), %xmm3     # 0xb0d0
subpd %xmm3, %xmm1
movapd %xmm1, %xmm6
unpckhpd %xmm1, %xmm6            # xmm6 = xmm6[1],xmm1[1]
addsd %xmm1, %xmm6
movsd 0x3bd8(%rbx), %xmm1
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
subpd %xmm3, %xmm1
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd %xmm2, %xmm6
movapd %xmm6, %xmm1
subsd 0xc374(%rip), %xmm1     # 0x102c0
xorpd %xmm0, %xmm0
ucomisd 0x70e0(%rip), %xmm1     # 0xb038
movsd %xmm5, 0x10(%rsp)
jbe 0x4010
ucomisd 0x70e4(%rip), %xmm5     # 0xb050
movapd (%rsp), %xmm7
jbe 0x3f9d
movsd 0x70c5(%rip), %xmm1     # 0xb040
cmpltpd %xmm6, %xmm1
movsd 0x70c0(%rip), %xmm2     # 0xb048
movapd %xmm7, %xmm3
cmpltpd %xmm2, %xmm3
orpd %xmm1, %xmm3
movd %xmm3, %eax
testb $0x1, %al
jne 0x3fcd
ucomisd 0x70bb(%rip), %xmm5     # 0xb060
jbe 0x4010
movsd 0x7079(%rip), %xmm1     # 0xb028
cmpltpd %xmm6, %xmm1
movsd 0x709c(%rip), %xmm2     # 0xb058
cmpltpd %xmm2, %xmm7
orpd %xmm1, %xmm7
movd %xmm7, %eax
testb $0x1, %al
je 0x4010
shrq $0xb, %r14
movsd 0x708f(%rip), %xmm0     # 0xb068
mulsd %xmm5, %xmm0
movsd %xmm0, (%rsp)
movq %rbx, %rdi
callq 0x314a
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %r14d, %xmm0
callq 0x2200
movsd 0x10(%rsp), %xmm5
mulsd (%rsp), %xmm0
ucomisd 0x7058(%rip), %xmm5     # 0xb070
jbe 0x40a9
movsd 0x3be0(%rbx), %xmm6
movsd 0x7092(%rip), %xmm2     # 0xb0c0
unpcklps %xmm2, %xmm6            # xmm6 = xmm6[0],xmm2[0],xmm6[1],xmm2[1]
movapd 0x7097(%rip), %xmm3     # 0xb0d0
subpd %xmm3, %xmm6
movapd %xmm6, %xmm1
unpckhpd %xmm6, %xmm1            # xmm1 = xmm1[1],xmm6[1]
addsd %xmm6, %xmm1
movsd 0x3bd8(%rbx), %xmm6
unpcklps %xmm2, %xmm6            # xmm6 = xmm6[0],xmm2[0],xmm6[1],xmm2[1]
subpd %xmm3, %xmm6
movapd %xmm6, %xmm2
unpckhpd %xmm6, %xmm2            # xmm2 = xmm2[1],xmm6[1]
addsd %xmm6, %xmm2
divsd %xmm2, %xmm1
ucomisd 0x7008(%rip), %xmm1     # 0xb078
jbe 0x40a9
leaq 0x408(%rbx), %r14
movl $0x0, 0x400(%rbx)
movl $0x3fc, %edx            # imm = 0x3FC
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2140
movl $0x1f60, %edx           # imm = 0x1F60
movq %r14, %rdi
xorl %esi, %esi
callq 0x2140
movsd 0x6fcf(%rip), %xmm0     # 0xb078
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x4365
movq 0xbf0a(%rip), %r14      # 0xffc8
leaq 0x7482(%rip), %rsi      # 0xb547
movl $0x8, %edx
movq %r14, %rdi
movsd %xmm0, (%rsp)
callq 0x22b0
movsd (%rsp), %xmm0
mulsd 0x6f9c(%rip), %xmm0     # 0xb080
movq %r14, %rdi
callq 0x23d0
movq %rax, %r15
leaq 0x745a(%rip), %rsi      # 0xb550
movl $0x7, %edx
movq %rax, %rdi
callq 0x22b0
movsd 0x3be0(%rbx), %xmm1
movsd 0x6fad(%rip), %xmm2     # 0xb0c0
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x6fb2(%rip), %xmm3     # 0xb0d0
subpd %xmm3, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
movsd 0x3bd8(%rbx), %xmm1
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
subpd %xmm3, %xmm1
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd %xmm2, %xmm0
mulsd 0x6f2b(%rip), %xmm0     # 0xb080
movq %r15, %rdi
callq 0x23d0
movsd 0x3bd8(%rbx), %xmm0
movsd 0x6f53(%rip), %xmm2     # 0xb0c0
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x6f58(%rip), %xmm3     # 0xb0d0
subpd %xmm3, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd 0x3be0(%rbx), %xmm0
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
subpd %xmm3, %xmm0
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
mulsd (%rsp), %xmm1
subsd %xmm1, %xmm2
cvttsd2si %xmm2, %rax
movq %rax, %rcx
subsd 0x6ecc(%rip), %xmm2     # 0xb088
cvttsd2si %xmm2, %rdx
sarq $0x3f, %rcx
andq %rcx, %rdx
orq %rax, %rdx
movq %rdx, 0x3be0(%rbx)
leaq 0x737f(%rip), %rsi      # 0xb558
movl $0x5, %edx
movq %r14, %rdi
callq 0x22b0
movsd 0x3be0(%rbx), %xmm1
movsd 0x6eca(%rip), %xmm2     # 0xb0c0
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x6ecf(%rip), %xmm3     # 0xb0d0
subpd %xmm3, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
movsd 0x3bd8(%rbx), %xmm1
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
subpd %xmm3, %xmm1
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd %xmm2, %xmm0
mulsd 0x6e48(%rip), %xmm0     # 0xb080
movq %r14, %rdi
callq 0x23d0
movq %rax, %r15
leaq 0x7314(%rip), %rsi      # 0xb55e
movl $0x11, %edx
movq %rax, %rdi
callq 0x22b0
movq %rbx, %rdi
callq 0x2fe2
movq %r15, %rdi
callq 0x23d0
leaq 0x7302(%rip), %rsi      # 0xb570
movl $0x19, %edx
movq %r14, %rdi
callq 0x22b0
movq %r14, %rdi
movsd 0x10(%rsp), %xmm0
callq 0x23d0
movq %rax, %r14
leaq 0x72f7(%rip), %rsi      # 0xb58a
movl $0x1, %edx
movq %rax, %rdi
callq 0x22b0
movq %r14, %rdi
movsd 0x18(%rsp), %xmm0
callq 0x23d0
movq %rax, %r14
leaq 0x72d4(%rip), %rsi      # 0xb58c
movl $0x2, %edx
movq %rax, %rdi
callq 0x22b0
movq %rbx, %rdi
callq 0x31d4
movq %r14, %rdi
callq 0x23d0
movq %rax, %r14
leaq 0x6eb8(%rip), %rsi      # 0xb197
movl $0x1, %edx
movq %rax, %rdi
callq 0x22b0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2250
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x21a0
movsd 0x3be0(%rbx), %xmm0
movsd 0x6d9d(%rip), %xmm2     # 0xb0c0
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x6da2(%rip), %xmm3     # 0xb0d0
subpd %xmm3, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd 0x3bd8(%rbx), %xmm0
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
subpd %xmm3, %xmm0
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
divsd %xmm2, %xmm1
movsd %xmm1, 0xbf5b(%rip)     # 0x102c0
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
nop