// File: uclaopt[P]AsyncQVI/include/algo.h
// Function: VRQVI::solve()
void solve(){
			srand (time(NULL));
			for(int t = 0; t < params->max_outer_iter; t++){
				
				// max element of v_fix
				v_outer_max = fabs((*v_outer)[0]);
				for(int index = 1; index < params->len_state; index++){
					if(fabs((*v_outer)[index]) > v_outer_max)
						v_outer_max = fabs((*v_outer)[index]);
				}
				
				// compute a coarse estimate of Q
				for(int i = 0; i < params->len_state; i++){
					for(int a = 0; a < params->len_action; a++){
						double v_sum = 0;
						double v_square_sum = 0;
						double r_sum = 0;
						for(int n = 0; n < params->sample_num_1; n++){
							s.SO(i, a, next_state, r);
							v_sum += (*v_outer)[next_state];
							v_square_sum += pow((*v_outer)[next_state],2);
							r_sum += r;
						}
						double v_ave = v_sum / params->sample_num_1;
						double v_square_ave = v_square_sum / params->sample_num_1;
						double r_ave = r_sum / params->sample_num_1;
						(*w)[i][a] = v_ave - sqrt(2*params->alpha1*(v_square_ave-v_ave))
						            - (4*pow(params->alpha1,0.75) + 2/3*params->alpha1)*v_outer_max;
						(*Q)[i][a] = r_ave + params->gamma * (*w)[i][a];
						
					}
				}
				
			    // improve Q 
				for(int k = 0; k < params->max_inner_iter; k++){				
					// compute the estimate of P(v_inner - v_outer)
					for(int i = 0; i < params->len_state; i++){
						// update v and pi
						if((*v_inner)[i] < *max_element(((*Q)[i]).begin(), ((*Q)[i]).end())){
							(*v_inner)[i] = *max_element(((*Q)[i]).begin(), ((*Q)[i]).end());
							(*pi)[i] =  distance(((*Q)[i]).begin(), max_element(((*Q)[i]).begin(), ((*Q)[i]).end()));
						}
					}
				
					for(int i = 0; i < params->len_state; i++){
						for(int a = 0; a < params->len_action; a++){
							double g = 0.;
							for(int n = 0; n < params->sample_num_2; n++){
								s.SO(i, a, next_state, r);
								g += r + params->gamma * ((*v_inner)[next_state]-(*v_outer)[next_state]);
							}
							(*Q)[i][a] = g/params->sample_num_2 -(1-params->gamma)*params->epsilon/8.
							             + params->gamma * (*w)[i][a];					
						}
					}
				}
				// reset parameters. The resetting fashion is tunable
				params->epsilon /= 2.;
				params->sample_num_1 *= 2; 
				params->sample_num_2 *= 2; 
				
				*v_outer = *v_inner;
				if(t % params->check_step==0){
					test_sailing(s, pi, params);
				}
			}
			return;
		}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xc8(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0x21a0
movl %eax, %edi
callq 0x21c0
movl $0x0, -0xc(%rbp)
movq -0xc8(%rbp), %rcx
movl -0xc(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl 0x34(%rcx), %eax
jge 0x6e3b
movq -0xc8(%rbp), %rax
movq 0x14f0(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x7860
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm0
movaps 0x6b79(%rip), %xmm1     # 0xd090
pand %xmm1, %xmm0
movsd %xmm0, 0x20(%rax)
movl $0x1, -0x10(%rbp)
movq -0xc8(%rbp), %rcx
movl -0x10(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl (%rcx), %eax
jge 0x65b8
movq -0xc8(%rbp), %rax
movq 0x14f0(%rax), %rdi
movslq -0x10(%rbp), %rsi
callq 0x7860
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm0
movaps 0x6b28(%rip), %xmm1     # 0xd090
pand %xmm1, %xmm0
ucomisd 0x20(%rax), %xmm0
jbe 0x65a8
movq -0xc8(%rbp), %rax
movq 0x14f0(%rax), %rdi
movslq -0x10(%rbp), %rsi
callq 0x7860
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm0
movaps 0x6af1(%rip), %xmm1     # 0xd090
pand %xmm1, %xmm0
movsd %xmm0, 0x20(%rax)
jmp 0x65aa
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
jmp 0x6527
movl $0x0, -0x14(%rbp)
movq -0xc8(%rbp), %rcx
movl -0x14(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl (%rcx), %eax
jge 0x68ce
movl $0x0, -0x18(%rbp)
movq -0xc8(%rbp), %rcx
movl -0x18(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl 0x4(%rcx), %eax
jge 0x68be
xorps %xmm0, %xmm0
movsd %xmm0, -0x20(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x28(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movq -0xc8(%rbp), %rcx
movl -0x34(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl 0x3c(%rcx), %eax
jge 0x66d1
movq -0xc8(%rbp), %r8
movq %r8, %rdi
addq $0x28, %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
movq %r8, %rcx
addq $0x8, %rcx
addq $0x10, %r8
callq 0x4dd0
movq -0xc8(%rbp), %rax
movq 0x14f0(%rax), %rdi
movslq 0x8(%rax), %rsi
callq 0x7860
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm0
addsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x20(%rbp)
movq 0x14f0(%rax), %rdi
movslq 0x8(%rax), %rsi
callq 0x7860
movsd (%rax), %xmm0
movl $0x2, %edi
callq 0x4e60
movq -0xc8(%rbp), %rax
addsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movsd 0x10(%rax), %xmm0
addsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x6618
movq -0xc8(%rbp), %rax
movsd -0x20(%rbp), %xmm0
movq 0x1508(%rax), %rcx
cvtsi2sdl 0x3c(%rcx), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movsd -0x28(%rbp), %xmm0
movq 0x1508(%rax), %rcx
cvtsi2sdl 0x3c(%rcx), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
movsd -0x30(%rbp), %xmm0
movq 0x1508(%rax), %rcx
cvtsi2sdl 0x3c(%rcx), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x50(%rbp)
movsd -0x40(%rbp), %xmm0
movsd %xmm0, -0xf8(%rbp)
movq 0x1508(%rax), %rax
movsd 0x68fe(%rip), %xmm0     # 0xd040
mulsd 0x58(%rax), %xmm0
movsd -0x48(%rbp), %xmm1
subsd -0x40(%rbp), %xmm1
mulsd %xmm1, %xmm0
callq 0x2130
movq -0xc8(%rbp), %rax
movaps %xmm0, %xmm1
movsd -0xf8(%rbp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0xf0(%rbp)
movq 0x1508(%rax), %rax
movsd 0x58(%rax), %xmm0
movsd 0x68c4(%rip), %xmm1     # 0xd050
callq 0x2390
movsd -0xf0(%rbp), %xmm1
movq -0xc8(%rbp), %rax
movq 0x1508(%rax), %rcx
xorps %xmm2, %xmm2
mulsd 0x58(%rcx), %xmm2
movsd 0x6869(%rip), %xmm3     # 0xd020
mulsd %xmm3, %xmm0
addsd %xmm2, %xmm0
movsd 0x20(%rax), %xmm2
movq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xe8(%rbp)
movq 0x14e8(%rax), %rdi
movslq -0x14(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
movslq -0x18(%rbp), %rsi
callq 0x7860
movsd -0xe8(%rbp), %xmm0
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd %xmm0, (%rcx)
movsd -0x50(%rbp), %xmm0
movsd %xmm0, -0xd8(%rbp)
movq 0x1508(%rax), %rcx
movsd 0x18(%rcx), %xmm0
movsd %xmm0, -0xe0(%rbp)
movq 0x14e8(%rax), %rdi
movslq -0x14(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
movslq -0x18(%rbp), %rsi
callq 0x7860
movsd -0xe0(%rbp), %xmm0
movsd -0xd8(%rbp), %xmm1
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xd0(%rbp)
movq 0x14e0(%rax), %rdi
movslq -0x14(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
movslq -0x18(%rbp), %rsi
callq 0x7860
movsd -0xd0(%rbp), %xmm0
movsd %xmm0, (%rax)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x65df
jmp 0x68c0
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x65bf
movl $0x0, -0x54(%rbp)
movq -0xc8(%rbp), %rcx
movl -0x54(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl 0x38(%rcx), %eax
jge 0x6d9b
movl $0x0, -0x58(%rbp)
movq -0xc8(%rbp), %rcx
movl -0x58(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl (%rcx), %eax
jge 0x6b29
movq -0xc8(%rbp), %rax
movq 0x14f8(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7860
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm0
movsd %xmm0, -0x100(%rbp)
movq 0x14e0(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
callq 0x7fb0
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movq %rcx, -0x68(%rbp)
movq 0x14e0(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
callq 0x7fe0
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x8800
movq %rax, -0x60(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x8840
movsd -0x100(%rbp), %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x6b19
movq -0xc8(%rbp), %rax
movq 0x14e0(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
callq 0x7fb0
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movq %rcx, -0x80(%rbp)
movq 0x14e0(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
callq 0x7fe0
movq %rax, -0x88(%rbp)
movq -0x80(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x8800
movq %rax, -0x78(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x8840
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm0
movsd %xmm0, -0x110(%rbp)
movq 0x14f8(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7860
movsd -0x110(%rbp), %xmm0
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd %xmm0, (%rcx)
movq 0x14e0(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
callq 0x7fb0
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movq %rcx, -0x90(%rbp)
movq 0x14e0(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
callq 0x7fb0
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movq %rcx, -0xa0(%rbp)
movq 0x14e0(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
callq 0x7fe0
movq %rax, -0xa8(%rbp)
movq -0xa0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
callq 0x8800
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rdi
movq -0x98(%rbp), %rsi
callq 0x8860
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movl %ecx, -0x104(%rbp)
movq 0x1500(%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x4e40
movl -0x104(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x6b1b
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x68f6
movl $0x0, -0xac(%rbp)
movq -0xc8(%rbp), %rcx
movl -0xac(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl (%rcx), %eax
jge 0x6d8b
movl $0x0, -0xb0(%rbp)
movq -0xc8(%rbp), %rcx
movl -0xb0(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl 0x4(%rcx), %eax
jge 0x6d75
xorps %xmm0, %xmm0
movsd %xmm0, -0xb8(%rbp)
movl $0x0, -0xbc(%rbp)
movq -0xc8(%rbp), %rcx
movl -0xbc(%rbp), %eax
movq 0x1508(%rcx), %rcx
cmpl 0x40(%rcx), %eax
jge 0x6c78
movq -0xc8(%rbp), %r8
movq %r8, %rdi
addq $0x28, %rdi
movl -0xac(%rbp), %esi
movl -0xb0(%rbp), %edx
movq %r8, %rcx
addq $0x8, %rcx
addq $0x10, %r8
callq 0x4dd0
movq -0xc8(%rbp), %rax
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x118(%rbp)
movq 0x1508(%rax), %rcx
movsd 0x18(%rcx), %xmm0
movsd %xmm0, -0x120(%rbp)
movq 0x14f8(%rax), %rdi
movslq 0x8(%rax), %rsi
callq 0x7860
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm0
movsd %xmm0, -0x128(%rbp)
movq 0x14f0(%rax), %rdi
movslq 0x8(%rax), %rsi
callq 0x7860
movsd -0x128(%rbp), %xmm2
movsd -0x120(%rbp), %xmm0
movsd -0x118(%rbp), %xmm1
subsd (%rax), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
addsd -0xb8(%rbp), %xmm0
movsd %xmm0, -0xb8(%rbp)
movl -0xbc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xbc(%rbp)
jmp 0x6b8b
movq -0xc8(%rbp), %rax
movsd -0xb8(%rbp), %xmm0
movq 0x1508(%rax), %rcx
cvtsi2sdl 0x40(%rcx), %xmm1
divsd %xmm1, %xmm0
movq 0x1508(%rax), %rcx
movsd 0x6372(%rip), %xmm1     # 0xd018
subsd 0x18(%rcx), %xmm1
movq 0x1508(%rax), %rcx
mulsd 0x60(%rcx), %xmm1
movsd 0x6389(%rip), %xmm2     # 0xd048
divsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x138(%rbp)
movq 0x1508(%rax), %rcx
movsd 0x18(%rcx), %xmm0
movsd %xmm0, -0x140(%rbp)
movq 0x14e8(%rax), %rdi
movslq -0xac(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
movslq -0xb0(%rbp), %rsi
callq 0x7860
movsd -0x140(%rbp), %xmm0
movsd -0x138(%rbp), %xmm1
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movsd (%rcx), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x130(%rbp)
movq 0x14e0(%rax), %rdi
movslq -0xac(%rbp), %rsi
callq 0x7920
movq %rax, %rdi
movslq -0xb0(%rbp), %rsi
callq 0x7860
movsd -0x130(%rbp), %xmm0
movsd %xmm0, (%rax)
movl -0xb0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb0(%rbp)
jmp 0x6b59
jmp 0x6d77
movl -0xac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
jmp 0x6b33
jmp 0x6d8d
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x68d5
movq -0xc8(%rbp), %rax
movq 0x1508(%rax), %rcx
movsd 0x60(%rcx), %xmm0
movsd 0x628a(%rip), %xmm1     # 0xd040
divsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rcx)
movq 0x1508(%rax), %rcx
movl 0x3c(%rcx), %edx
shll %edx
movl %edx, 0x3c(%rcx)
movq 0x1508(%rax), %rcx
movl 0x40(%rcx), %edx
shll %edx
movl %edx, 0x40(%rcx)
movq 0x14f8(%rax), %rsi
movq 0x14f0(%rax), %rdi
callq 0x7ae0
movq -0xc8(%rbp), %rcx
movl -0xc(%rbp), %eax
movq 0x1508(%rcx), %rcx
cltd
idivl 0x6c(%rcx)
cmpl $0x0, %edx
jne 0x6e2b
movq -0xc8(%rbp), %rax
movq %rax, %rdi
addq $0x28, %rdi
movq 0x1500(%rax), %rsi
movq 0x1508(%rax), %rdx
callq 0x38d0
jmp 0x6e2d
movl -0xc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc(%rbp)
jmp 0x64d1
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopw %cs:(%rax,%rax)
nop