// File: /workspace/github_c_makefile_star2_O3/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 0x3e8b
retq
pushq %r15
pushq %r14
pushq %rbx
subq $0x30, %rsp
movq %rdi, %rbx
movq %rdx, %r14
movapd %xmm0, (%rsp)
movaps %xmm1, 0x20(%rsp)
callq 0x2fc0
movapd 0x20(%rsp), %xmm4
movdqu 0x3bd8(%rbx), %xmm1
movdqa 0x7191(%rip), %xmm2     # 0xb050
pand %xmm1, %xmm2
por 0x7195(%rip), %xmm2     # 0xb060
movapd %xmm0, %xmm5
psrlq $0x20, %xmm1
por 0x7194(%rip), %xmm1     # 0xb070
subpd 0x719c(%rip), %xmm1     # 0xb080
addpd %xmm2, %xmm1
shufpd $0x2, %xmm1, %xmm5      # xmm5 = xmm5[0],xmm1[1]
movapd %xmm4, %xmm0
unpcklpd %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0]
divpd %xmm0, %xmm5
movapd %xmm5, %xmm6
unpckhpd %xmm5, %xmm6            # xmm6 = xmm6[1],xmm5[1]
movapd %xmm6, %xmm1
subsd 0xc3b3(%rip), %xmm1     # 0x102c0
xorpd %xmm0, %xmm0
ucomisd 0x71f7(%rip), %xmm1     # 0xb110
movapd %xmm5, 0x10(%rsp)
jbe 0x4014
ucomisd 0x71fb(%rip), %xmm5     # 0xb128
movapd (%rsp), %xmm7
jbe 0x3f5e
movsd 0x71dc(%rip), %xmm1     # 0xb118
cmpltpd %xmm6, %xmm1
movsd 0x71d7(%rip), %xmm2     # 0xb120
movapd %xmm7, %xmm3
cmpltpd %xmm2, %xmm3
orpd %xmm1, %xmm3
movd %xmm3, %eax
testb $0x1, %al
jne 0x3f90
movapd 0x712a(%rip), %xmm1     # 0xb090
cmpltpd %xmm5, %xmm1
movsd 0x71bd(%rip), %xmm2     # 0xb130
ucomisd %xmm7, %xmm2
movmskpd %xmm1, %eax
seta %cl
testb $0x1, %al
je 0x4014
shrb %al
orb %al, %cl
je 0x4014
shrq $0xb, %r14
movsd 0x719c(%rip), %xmm0     # 0xb138
mulsd %xmm5, %xmm0
movsd %xmm0, (%rsp)
movq %rbx, %rdi
callq 0x3128
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %r14d, %xmm0
callq 0x2200
movapd 0x10(%rsp), %xmm5
mulsd (%rsp), %xmm0
movdqu 0x3bd8(%rbx), %xmm1
movdqa 0x706d(%rip), %xmm2     # 0xb050
pand %xmm1, %xmm2
por 0x7071(%rip), %xmm2     # 0xb060
psrlq $0x20, %xmm1
por 0x7074(%rip), %xmm1     # 0xb070
subpd 0x707c(%rip), %xmm1     # 0xb080
addpd %xmm2, %xmm1
movapd %xmm1, %xmm6
unpckhpd %xmm1, %xmm6            # xmm6 = xmm6[1],xmm1[1]
divsd %xmm1, %xmm6
ucomisd 0x7124(%rip), %xmm5     # 0xb140
jbe 0x4061
ucomisd 0x7122(%rip), %xmm6     # 0xb148
jbe 0x4061
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 0x70e9(%rip), %xmm0     # 0xb148
jmp 0x406f
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x4300
movsd %xmm0, (%rsp)
movq 0xbf4d(%rip), %r14      # 0xffc8
leaq 0x7555(%rip), %rsi      # 0xb5d7
movl $0x8, %edx
movq %r14, %rdi
callq 0x22b0
movsd (%rsp), %xmm0
mulsd 0x70b4(%rip), %xmm0     # 0xb150
movq %r14, %rdi
callq 0x23d0
movq %rax, %r15
leaq 0x7532(%rip), %rsi      # 0xb5e0
movl $0x7, %edx
movq %rax, %rdi
callq 0x22b0
movdqu 0x3bd8(%rbx), %xmm1
movdqa %xmm1, %xmm0
pand 0x6f81(%rip), %xmm0     # 0xb050
por 0x6f89(%rip), %xmm0     # 0xb060
psrlq $0x20, %xmm1
por 0x6f8c(%rip), %xmm1     # 0xb070
subpd 0x6f94(%rip), %xmm1     # 0xb080
addpd %xmm0, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
divsd %xmm1, %xmm0
mulsd 0x704c(%rip), %xmm0     # 0xb150
movq %r15, %rdi
callq 0x23d0
movsd 0x3bd8(%rbx), %xmm0
movsd 0x6f04(%rip), %xmm1     # 0xb020
unpcklps %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x6f09(%rip), %xmm2     # 0xb030
subpd %xmm2, %xmm0
movapd %xmm0, %xmm3
unpckhpd %xmm0, %xmm3            # xmm3 = xmm3[1],xmm0[1]
addsd %xmm0, %xmm3
movsd 0x3be0(%rbx), %xmm0
unpcklps %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
subpd %xmm2, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
mulsd (%rsp), %xmm3
subsd %xmm3, %xmm1
cvttsd2si %xmm1, %rax
movq %rax, %rcx
subsd 0x6fed(%rip), %xmm1     # 0xb158
cvttsd2si %xmm1, %rdx
sarq $0x3f, %rcx
andq %rcx, %rdx
orq %rax, %rdx
movq %rdx, 0x3be0(%rbx)
leaq 0x7460(%rip), %rsi      # 0xb5e8
movl $0x5, %edx
movq %r14, %rdi
callq 0x22b0
movdqu 0x3bd8(%rbx), %xmm1
movdqa %xmm1, %xmm0
pand 0x6ea7(%rip), %xmm0     # 0xb050
por 0x6eaf(%rip), %xmm0     # 0xb060
psrlq $0x20, %xmm1
por 0x6eb2(%rip), %xmm1     # 0xb070
subpd 0x6eba(%rip), %xmm1     # 0xb080
addpd %xmm0, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
divsd %xmm1, %xmm0
mulsd 0x6f72(%rip), %xmm0     # 0xb150
movq %r14, %rdi
callq 0x23d0
movq %rax, %r15
leaq 0x73fe(%rip), %rsi      # 0xb5ee
movl $0x11, %edx
movq %rax, %rdi
callq 0x22b0
movq %rbx, %rdi
callq 0x2fc0
movq %r15, %rdi
callq 0x23d0
leaq 0x73ec(%rip), %rsi      # 0xb600
movl $0x19, %edx
movq %r14, %rdi
callq 0x22b0
movq %r14, %rdi
movaps 0x10(%rsp), %xmm0
callq 0x23d0
movq %rax, %r14
leaq 0x73e2(%rip), %rsi      # 0xb61a
movl $0x1, %edx
movq %rax, %rdi
callq 0x22b0
movq %r14, %rdi
movaps 0x20(%rsp), %xmm0
callq 0x23d0
movq %rax, %r14
leaq 0x73c0(%rip), %rsi      # 0xb61c
movl $0x2, %edx
movq %rax, %rdi
callq 0x22b0
movq %rbx, %rdi
callq 0x31b2
movq %r14, %rdi
callq 0x23d0
movq %rax, %r14
leaq 0x6fa4(%rip), %rsi      # 0xb227
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
movdqu 0x3bd8(%rbx), %xmm0
movdqa 0x6d89(%rip), %xmm1     # 0xb050
pand %xmm0, %xmm1
por 0x6d8d(%rip), %xmm1     # 0xb060
psrlq $0x20, %xmm0
por 0x6d90(%rip), %xmm0     # 0xb070
subpd 0x6d98(%rip), %xmm0     # 0xb080
addpd %xmm1, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
divsd %xmm0, %xmm1
movsd %xmm1, 0xbfc0(%rip)     # 0x102c0
addq $0x30, %rsp
popq %rbx
popq %r14
popq %r15
retq