// File: canzarlab[P]Trajan/geno/lbfgsb.cpp
// Function: LBFGSB::lineSearchMT(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, unsigned long)
Scalar LBFGSB::lineSearchMT(const Vector& deltaX, size_t iter) {
  Scalar const INF = std::numeric_limits<Scalar>::infinity();
  double stp;
  double a1, a2;
  double big  = 1.0e10;
  double ftol = 1.0e-3,
         gtol = 0.9,
         xtol = 0.1;
  Scalar dnorm = deltaX.norm();
  // Determine the maximum step length.
  Scalar stpmx = big;
  if (_constrained) {
    if (iter == 1) {
      stpmx = 1.0;
    } else {
      for (Index i = 0; i < _x.size(); ++i) {
        a1 = deltaX[i];
	//        if (_nbd[i] != 0) {     
	if (_lb[i] != -INF || _ub[i] != INF) {
	  //      if (a1 < zero && _nbd[i] <= 2) {
	  if (a1 < 0.0 && _lb[i] != -INF) {
	    a2 = _lb(i) - _x(i);
            if (a2 >= 0.0) {
              stpmx = 0.0;
            } else if (a1*stpmx < a2) {
              stpmx = a2/a1;
            }
	    //          } else if (a1 > zero && _nbd[i] >= 2) {
          } else if (a1 > 0.0 && _ub[i] != INF) {
            a2 = _ub(i) - _x(i);
            if (a2 <= 0.0) {
              stpmx = 0.0;
            } else if (a1*stpmx > a2) {
              stpmx = a2/a1;
            }
          }
        }
      }
    }
  }
  if (iter == 1 && !_boxed)
    stp = std::min(1.0/dnorm, stpmx);
  else
    stp = 1.0;
  _gNew = _g;
  _fNew = _f;
  TaskType csave = TaskType::START;
  Scalar gd = _gNew.dot(deltaX);
  if (gd >= 0.0) {
    std::cerr << "ascent direction in projection gd = " << gd << std::endl;
    stp = -1;
    return stp;
    //    std::exit(EXIT_FAILURE);
  }
  int funIter = 0;
  TMPContainer TCON;
  do {
    dcsrch(_fNew, gd, stp, ftol, gtol, xtol, 0.0, stpmx, csave, TCON);
    if (TaskType::ERROR == csave)
      std::exit(EXIT_FAILURE);
    if (csave == TaskType::CONVERGENCE || csave == TaskType::WARNING)
      break;
    _xNew = stp * deltaX + _x;
    _genoNLP.functionValueAndGradient(_xNew.data(), _fNew, _gNew.data());
    ++_funEval;
    gd = _gNew.dot(deltaX);
    ++funIter;
    if (funIter >= 19) {
      stp = -1;  // something went wrong
      break;
    }
  } while(true);
  return stp;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x188(%rbp)
callq 0x26640
movsd %xmm0, -0x28(%rbp)
movsd 0xe9d44(%rip), %xmm0    # 0x10dc88
movsd %xmm0, -0x48(%rbp)
movsd 0xe9d2f(%rip), %xmm0    # 0x10dc80
movsd %xmm0, -0x50(%rbp)
movsd 0xe9d1a(%rip), %xmm0    # 0x10dc78
movsd %xmm0, -0x58(%rbp)
movsd 0xe9d05(%rip), %xmm0    # 0x10dc70
movsd %xmm0, -0x60(%rbp)
movq -0x18(%rbp), %rdi
callq 0x29030
movq -0x188(%rbp), %rax
movsd %xmm0, -0x68(%rbp)
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
testb $0x1, 0x258(%rax)
je 0x241ed
cmpq $0x1, -0x20(%rbp)
jne 0x23fb5
movsd 0xe9cbd(%rip), %xmm0    # 0x10dc68
movsd %xmm0, -0x70(%rbp)
jmp 0x241eb
movq $0x0, -0x78(%rbp)
movq -0x188(%rbp), %rdi
movq -0x78(%rbp), %rax
movq %rax, -0x190(%rbp)
addq $0x10, %rdi
callq 0x14700
movq %rax, %rcx
movq -0x190(%rbp), %rax
cmpq %rcx, %rax
jge 0x241e9
movq -0x18(%rbp), %rdi
movq -0x78(%rbp), %rsi
callq 0x29510
movq -0x188(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
addq $0x20, %rdi
movq -0x78(%rbp), %rsi
callq 0x26650
movsd (%rax), %xmm0
movsd 0xe738f(%rip), %xmm1    # 0x10b3b0
ucomisd %xmm1, %xmm0
jne 0x24056
jp 0x24056
movq -0x188(%rbp), %rdi
addq $0x30, %rdi
movq -0x78(%rbp), %rsi
callq 0x26650
movsd (%rax), %xmm0
movsd 0xe7357(%rip), %xmm1    # 0x10b3a0
ucomisd %xmm1, %xmm0
jne 0x24056
jp 0x24056
jmp 0x241d6
xorps %xmm0, %xmm0
ucomisd -0x38(%rbp), %xmm0
jbe 0x24119
movq -0x188(%rbp), %rdi
addq $0x20, %rdi
movq -0x78(%rbp), %rsi
callq 0x26650
movsd (%rax), %xmm0
movsd 0xe732c(%rip), %xmm1    # 0x10b3b0
ucomisd %xmm1, %xmm0
jne 0x24091
jp 0x24091
jmp 0x24119
movq -0x188(%rbp), %rdi
addq $0x20, %rdi
movq -0x78(%rbp), %rsi
callq 0x145f0
movq -0x188(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x198(%rbp)
addq $0x10, %rdi
movq -0x78(%rbp), %rsi
callq 0x145f0
movsd -0x198(%rbp), %xmm0
subsd (%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
movsd -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x240ee
xorps %xmm0, %xmm0
movsd %xmm0, -0x70(%rbp)
jmp 0x24114
movsd -0x38(%rbp), %xmm1
mulsd -0x70(%rbp), %xmm1
movsd -0x40(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x24112
movsd -0x40(%rbp), %xmm0
divsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
jmp 0x24114
jmp 0x241d4
movsd -0x38(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x241d2
movq -0x188(%rbp), %rdi
addq $0x30, %rdi
movq -0x78(%rbp), %rsi
callq 0x26650
movsd (%rax), %xmm0
movsd 0xe7255(%rip), %xmm1    # 0x10b3a0
ucomisd %xmm1, %xmm0
jne 0x24155
jp 0x24155
jmp 0x241d2
movq -0x188(%rbp), %rdi
addq $0x30, %rdi
movq -0x78(%rbp), %rsi
callq 0x145f0
movq -0x188(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x1a0(%rbp)
addq $0x10, %rdi
movq -0x78(%rbp), %rsi
callq 0x145f0
movsd -0x1a0(%rbp), %xmm0
subsd (%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x40(%rbp), %xmm0
jb 0x241ae
xorps %xmm0, %xmm0
movsd %xmm0, -0x70(%rbp)
jmp 0x241d0
movsd -0x38(%rbp), %xmm0
mulsd -0x70(%rbp), %xmm0
ucomisd -0x40(%rbp), %xmm0
jbe 0x241ce
movsd -0x40(%rbp), %xmm0
divsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
jmp 0x241d0
jmp 0x241d2
jmp 0x241d4
jmp 0x241d6
jmp 0x241d8
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
jmp 0x23fbd
jmp 0x241eb
jmp 0x241ed
cmpq $0x1, -0x20(%rbp)
jne 0x2422e
movq -0x188(%rbp), %rax
testb $0x1, 0x259(%rax)
jne 0x2422e
movsd 0xe9a5c(%rip), %xmm0    # 0x10dc68
divsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x148e0
movsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
jmp 0x2423b
movsd 0xe9a32(%rip), %xmm0    # 0x10dc68
movsd %xmm0, -0x30(%rbp)
movq -0x188(%rbp), %rdi
movq %rdi, %rsi
addq $0x40, %rsi
addq $0x248, %rdi            # imm = 0x248
callq 0x145a0
movq -0x188(%rbp), %rdi
movsd 0x8(%rdi), %xmm0
movsd %xmm0, 0x230(%rdi)
movl $0x0, -0x84(%rbp)
addq $0x248, %rdi            # imm = 0x248
movq -0x18(%rbp), %rsi
callq 0x266e0
movsd %xmm0, -0x90(%rbp)
movsd -0x90(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x242ea
movq 0x17cd4d(%rip), %rdi    # 0x1a0ff0
leaq 0xe9c8f(%rip), %rsi     # 0x10df39
callq 0xa440
movq %rax, %rdi
movsd -0x90(%rbp), %xmm0
callq 0xa870
movq %rax, %rdi
movq 0x17cc97(%rip), %rsi    # 0x1a0f60
callq 0xa4a0
movsd 0xe70aa(%rip), %xmm0    # 0x10b380
movsd %xmm0, -0x30(%rbp)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x24480
movl $0x0, -0x94(%rbp)
movq -0x188(%rbp), %rdi
addq $0x230, %rdi            # imm = 0x230
movsd -0x50(%rbp), %xmm0
movsd -0x58(%rbp), %xmm1
movsd -0x60(%rbp), %xmm2
movsd -0x70(%rbp), %xmm4
leaq -0x90(%rbp), %rsi
leaq -0x30(%rbp), %rdx
xorps %xmm3, %xmm3
leaq -0x84(%rbp), %rcx
leaq -0x108(%rbp), %r8
callq 0x95d80
movl $0x1, %eax
cmpl -0x84(%rbp), %eax
jne 0x2434e
movl $0x1, %edi
callq 0xa540
cmpl $0x4, -0x84(%rbp)
je 0x24360
cmpl $0x3, -0x84(%rbp)
jne 0x24365
jmp 0x24476
movq -0x18(%rbp), %rdx
leaq -0x180(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x161e0
movq -0x188(%rbp), %rdx
addq $0x10, %rdx
leaq -0x150(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x295a0
movq -0x188(%rbp), %rdi
addq $0x238, %rdi            # imm = 0x238
leaq -0x150(%rbp), %rsi
callq 0x29610
movq -0x188(%rbp), %rdi
movq (%rdi), %rax
movq %rax, -0x1b8(%rbp)
addq $0x238, %rdi            # imm = 0x238
callq 0x13cd0
movq -0x188(%rbp), %rdi
movq %rax, -0x1b0(%rbp)
movq %rdi, %rax
addq $0x230, %rax            # imm = 0x230
movq %rax, -0x1a8(%rbp)
addq $0x248, %rdi            # imm = 0x248
callq 0x13cd0
movq -0x1b8(%rbp), %rdi
movq -0x1b0(%rbp), %rsi
movq -0x1a8(%rbp), %rdx
movq %rax, %rcx
movq (%rdi), %rax
callq *0x48(%rax)
movq -0x188(%rbp), %rdi
movq 0x50(%rdi), %rax
addq $0x1, %rax
movq %rax, 0x50(%rdi)
addq $0x248, %rdi            # imm = 0x248
movq -0x18(%rbp), %rsi
callq 0x266e0
movsd %xmm0, -0x90(%rbp)
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
cmpl $0x13, -0x94(%rbp)
jl 0x24468
movsd 0xe6f1f(%rip), %xmm0    # 0x10b380
movsd %xmm0, -0x30(%rbp)
jmp 0x24476
jmp 0x2446a
movb $0x1, %al
testb $0x1, %al
jne 0x242f4
jmp 0x24476
movsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
nop