// File: /workspace/github_cpp_makefile_star2_O2/mateuz[P]MTS-LS1/source/main.cpp
// Function: mts_ls1(Benchmarks*, unsigned int, std::vector<double, std::allocator<double>>&)
void mts_ls1(Benchmarks * bench, unsigned maxevals, vector<double>& sol){
  //unsigned int n_dim = ndim;
  unsigned totalevals = 0;
  double best_fitness = bench->compute(sol.data());

  vector<double> SR(sol.size());
  for( unsigned i = 0; i < SR.size(); i++ ){
    SR[i] = (bench->getMaxX() - bench->getMinX()) * 0.4;
  }

  LSresult result;
  LSresult current_best = {sol, best_fitness, 0};

  vector<double> improvement(dim, 0.0);

  vector<double> dim_sorted(dim);
  iota(dim_sorted.begin(), dim_sorted.end(), 0);

  double improve;
  //warm-up
  if( totalevals < maxevals ){
    next_permutation(dim_sorted.begin(), dim_sorted.end());
    for( auto it = dim_sorted.begin(); it != dim_sorted.end(); it++ ){
      result = mts_ls1_improve_dim(bench, sol, best_fitness, *it, SR);
      totalevals += result.evals;
      improve = max(current_best.fitness - result.fitness, 0.0);
      improvement[*it] = improve;

      if( improve > 0.0 ){
        printf("[1] %.10lf > %.10lf ~ improve: %.20lf\n", current_best.fitness, result.fitness, improve);
        current_best = result;
      } else {
        SR[*it] /= 2.0f;
      }
    }
  }

  iota(dim_sorted.begin(), dim_sorted.end(), 0);
  sort(dim_sorted.begin(), dim_sorted.end(), [&](unsigned i1, unsigned i2) { return improvement[i1] > improvement[i2]; });

  int i, d = 0, next_d, next_i;
  while( totalevals < maxevals ){
    i = dim_sorted[d];
    result = mts_ls1_improve_dim(bench, current_best.solution, current_best.fitness, i, SR);
    totalevals += result.evals;
    improve = max(current_best.fitness - result.fitness, 0.0);
    improvement[i] = improve;
    next_d = (d+1)%dim;
    next_i = dim_sorted[next_d];

    if( improve > 0.0 ){
      printf("[2] %.10lf > %.10lf ~ improve: %.20lf\n", current_best.fitness, result.fitness, improve);
      current_best = result;

      if( improvement[i] < improvement[next_i] ){
        iota(dim_sorted.begin(), dim_sorted.end(), 0);
        sort(dim_sorted.begin(), dim_sorted.end(), [&](unsigned i1, unsigned i2) { return improvement[i1] > improvement[i2]; });
      }
    } else {
      SR[i] /= 2.0;
      d = next_d;
      if( SR[i] < 1e-15 ){
        SR[i] = (bench->getMaxX() - bench->getMinX()) * 0.4;
      }
    }
  }
  sol = current_best.solution;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %rdx, %rbx
movl %esi, -0x44(%rbp)
movq %rdi, %r12
movq (%rdx), %rsi
movq (%rdi), %rax
callq *0x10(%rax)
movsd %xmm0, -0x50(%rbp)
movq 0x8(%rbx), %rsi
movq %rbx, -0x58(%rbp)
subq (%rbx), %rsi
sarq $0x3, %rsi
leaq -0x98(%rbp), %rbx
leaq -0xf0(%rbp), %rdx
movq %rbx, %rdi
callq 0x95e4
xorl %ecx, %ecx
movq (%rbx), %rax
movl %ecx, %r14d
movq -0x90(%rbp), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r14, %rcx
jbe 0x84a7
movq %r12, %rdi
callq 0x5928
movl %eax, %ebx
movq %r12, %rdi
callq 0x591c
subl %eax, %ebx
cvtsi2sd %ebx, %xmm0
mulsd 0x1d44(%rip), %xmm0     # 0xa1d8
movq -0x98(%rbp), %rax
movsd %xmm0, (%rax,%r14,8)
leal 0x1(%r14), %ecx
jmp 0x845e
xorpd %xmm0, %xmm0
movapd %xmm0, -0xf0(%rbp)
andq $0x0, -0xe0(%rbp)
leaq -0xc0(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x94c0
movsd -0x50(%rbp), %xmm0
movsd %xmm0, -0xa8(%rbp)
andl $0x0, -0xa0(%rbp)
movl 0x6cbb(%rip), %esi      # 0xf1a0
leaq -0x118(%rbp), %rdx
andq $0x0, (%rdx)
leaq -0x80(%rbp), %rdi
leaq -0x40(%rbp), %rcx
callq 0x9636
movl 0x6c9d(%rip), %esi      # 0xf1a0
leaq -0x40(%rbp), %rdi
leaq -0x118(%rbp), %rdx
callq 0x95e4
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rsi
xorl %r15d, %r15d
xorl %edx, %edx
callq 0x9696
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rsi
cmpl $0x0, -0x44(%rbp)
movq %r12, -0x60(%rbp)
je 0x866b
callq 0x9904
xorl %r15d, %r15d
movq -0x40(%rbp), %r13
leaq -0x118(%rbp), %rbx
leaq -0x98(%rbp), %r14
leaq -0xf0(%rbp), %r12
movq -0x38(%rbp), %rsi
cmpq %rsi, %r13
je 0x8667
cvttsd2si (%r13), %rcx
movq %rbx, %rdi
movq -0x60(%rbp), %rsi
movq -0x58(%rbp), %rdx
movsd -0x50(%rbp), %xmm0
movq %r14, %r8
callq 0x824c
movq %r12, %rdi
movq %rbx, %rsi
callq 0x96b2
movq %rbx, %rdi
callq 0x97aa
movsd -0xa8(%rbp), %xmm0
subsd -0xd8(%rbp), %xmm0
xorpd %xmm2, %xmm2
maxsd %xmm0, %xmm2
movsd (%r13), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
movsd 0x1bfc(%rip), %xmm1     # 0xa1c8
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
addl -0xd0(%rbp), %r15d
movq -0x80(%rbp), %rax
movsd %xmm2, (%rax,%rdx,8)
ucomisd 0x1a35(%rip), %xmm2     # 0xa028
jbe 0x8624
movsd -0xa8(%rbp), %xmm0
movsd -0xd8(%rbp), %xmm1
leaq 0x1c54(%rip), %rdi      # 0xa260
movb $0x3, %al
callq 0x3050
leaq -0xc0(%rbp), %rdi
movq %r12, %rsi
callq 0x96dc
jmp 0x865e
movsd (%r13), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movq -0x98(%rbp), %rax
movsd (%rax,%rdx,8), %xmm0
mulsd 0x19d7(%rip), %xmm0     # 0xa030
movsd %xmm0, (%rax,%rdx,8)
addq $0x8, %r13
jmp 0x855c
movq -0x40(%rbp), %rdi
xorl %r14d, %r14d
xorl %edx, %edx
callq 0x9696
movq -0x40(%rbp), %r13
movq -0x38(%rbp), %rbx
cmpq %rbx, %r13
je 0x86f2
movq %rbx, %r12
subq %r13, %r12
movq %r12, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x80(%rbp), %rcx
movq %r13, %rdi
movq %rbx, %rsi
callq 0x8da2
cmpq $0x81, %r12
jl 0x86e3
movq %r13, %rdi
addq $0x80, %r13
leaq -0x80(%rbp), %r12
movq %r13, %rsi
movq %r12, %rdx
callq 0x905d
cmpq %rbx, %r13
je 0x86f2
movq %r13, %rdi
movq %r12, %rsi
callq 0x90f7
addq $0x8, %r13
jmp 0x86cd
leaq -0x80(%rbp), %rdx
movq %r13, %rdi
movq %rbx, %rsi
callq 0x905d
leaq -0x80(%rbp), %rbx
movslq %r14d, %rcx
movq %rcx, -0x50(%rbp)
leal 0x1(%rcx), %eax
movl %eax, -0x64(%rbp)
cmpl -0x44(%rbp), %r15d
jae 0x88f4
movq -0x40(%rbp), %rax
movq -0x50(%rbp), %rcx
cvttsd2si (%rax,%rcx,8), %r14d
movsd -0xa8(%rbp), %xmm0
leaq -0x118(%rbp), %r13
movq %r13, %rdi
movq -0x60(%rbp), %rsi
leaq -0xc0(%rbp), %rdx
movl %r14d, %ecx
leaq -0x98(%rbp), %r8
callq 0x824c
leaq -0xf0(%rbp), %r12
movq %r12, %rdi
movq %r13, %rsi
callq 0x96b2
movq %r13, %rdi
callq 0x97aa
movsd -0xa8(%rbp), %xmm0
subsd -0xd8(%rbp), %xmm0
xorpd %xmm2, %xmm2
maxsd %xmm0, %xmm2
movslq %r14d, %r13
movq -0x80(%rbp), %rax
addl -0xd0(%rbp), %r15d
movsd %xmm2, (%rax,%r13,8)
movl -0x64(%rbp), %eax
xorl %edx, %edx
divl 0x6a08(%rip)            # 0xf1a0
movl %edx, %r14d
ucomisd 0x1885(%rip), %xmm2     # 0xa028
jbe 0x888e
movslq %r14d, %rax
movq -0x40(%rbp), %rcx
cvttsd2si (%rcx,%rax,8), %r14d
movsd -0xa8(%rbp), %xmm0
movsd -0xd8(%rbp), %xmm1
leaq 0x1aba(%rip), %rdi      # 0xa287
movb $0x3, %al
callq 0x3050
leaq -0xc0(%rbp), %rdi
movq %r12, %rsi
callq 0x96dc
movq -0x80(%rbp), %rax
movslq %r14d, %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd (%rax,%r13,8), %xmm0
jbe 0x8703
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x9696
movq -0x40(%rbp), %r13
movq -0x38(%rbp), %r14
cmpq %r14, %r13
je 0x8703
movq %r14, %r12
subq %r13, %r12
movq %r12, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r13, %rdi
movq %r14, %rsi
movq %rbx, %rcx
callq 0x9131
cmpq $0x81, %r12
jl 0x887b
leaq 0x80(%r13), %r12
movq %r13, %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x93ec
cmpq %r14, %r12
je 0x8703
movq %r12, %rdi
movq %rbx, %rsi
callq 0x9486
addq $0x8, %r12
jmp 0x8861
movq %r13, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x93ec
jmp 0x8703
movq -0x98(%rbp), %rax
movsd (%rax,%r13,8), %xmm0
mulsd 0x178d(%rip), %xmm0     # 0xa030
movsd %xmm0, (%rax,%r13,8)
movsd 0x191f(%rip), %xmm1     # 0xa1d0
ucomisd %xmm0, %xmm1
jbe 0x86f6
movq -0x60(%rbp), %r12
movq %r12, %rdi
callq 0x5928
movq %r12, %rdi
movl %eax, %r12d
callq 0x591c
subl %eax, %r12d
cvtsi2sd %r12d, %xmm0
mulsd 0x18f6(%rip), %xmm0     # 0xa1d8
movq -0x98(%rbp), %rax
movsd %xmm0, (%rax,%r13,8)
jmp 0x86f6
leaq -0xc0(%rbp), %rsi
movq -0x58(%rbp), %rdi
callq 0x9518
leaq -0x40(%rbp), %rdi
callq 0x97aa
leaq -0x80(%rbp), %rdi
callq 0x97aa
leaq -0xc0(%rbp), %rdi
callq 0x97aa
leaq -0xf0(%rbp), %rdi
callq 0x97aa
leaq -0x98(%rbp), %rdi
callq 0x97aa
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x8967
jmp 0x8967
jmp 0x8967
movq %rax, %rbx
jmp 0x8973
movq %rax, %rbx
jmp 0x897c
movq %rax, %rbx
jmp 0x8988
jmp 0x8967
jmp 0x8967
jmp 0x8967
movq %rax, %rbx
leaq -0x40(%rbp), %rdi
callq 0x97aa
leaq -0x80(%rbp), %rdi
callq 0x97aa
leaq -0xc0(%rbp), %rdi
callq 0x97aa
leaq -0xf0(%rbp), %rdi
callq 0x97aa
jmp 0x8999
movq %rax, %rbx
leaq -0x98(%rbp), %rdi
callq 0x97aa
movq %rbx, %rdi
callq 0x32d0