// File: /workspace/github_c_makefile_star2_O0/PoulinV[P]AxiCLASS/build/../source/transfer.c
// Function: transfer_integrate
int transfer_integrate(
                       struct perturbations * ppt,
                       struct transfer * ptr,
                       struct transfer_workspace *ptw,
                       int index_q,
                       int index_md,
                       int index_tt,
                       double l,
                       int index_l,
                       double k,
                       radial_function_type radial_type,
                       double * trsf
                       ) {

  /** Summary: */

  /** - define local variables */

  double * tau0_minus_tau = ptw->tau0_minus_tau;
  double * w_trapz = ptw->w_trapz;
  double * sources = ptw->sources;

  /* minimum value of \f$ (\tau0-\tau) \f$ at which \f$ j_l(k[\tau_0-\tau]) \f$ is known, given that \f$ j_l(x) \f$ is sampled above some finite value \f$ x_{\min} \f$ (below which it can be approximated by zero) */
  double tau0_minus_tau_min_bessel;

  /* index in the source's tau list corresponding to the last point in the overlapping region between sources and bessels. Also the index of possible Bessel truncation. */
  int index_tau_max, index_tau_max_Bessel;

  double bessel, *radial_function;

  double x_turning_point;

  /** - find minimum value of (tau0-tau) at which \f$ j_l(k[\tau_0-\tau]) \f$ is known, given that \f$ j_l(x) \f$ is sampled above some finite value \f$ x_{\min} \f$ (below which it can be approximated by zero) */
  //tau0_minus_tau_min_bessel = x_min_l/k; /* segmentation fault impossible, checked before that k != 0 */
  //printf("index_l=%d\n",index_l);
  if (ptw->sgnK==0){
    tau0_minus_tau_min_bessel = ptw->pBIS->chi_at_phimin[index_l]/k; /* segmentation fault impossible, checked before that k != 0 */
  }
  else{

    if (index_q < ptr->index_q_flat_approximation) {

      tau0_minus_tau_min_bessel = ptw->HIS.chi_at_phimin[index_l]/sqrt(ptw->sgnK*ptw->K);

    }
    else {

      tau0_minus_tau_min_bessel = ptw->pBIS->chi_at_phimin[index_l]/sqrt(ptw->sgnK*ptw->K);

      if (ptw->sgnK == 1) {
        x_turning_point = asin(sqrt(l*(l+1.))/ptr->q[index_q]*sqrt(ptw->sgnK*ptw->K));
        tau0_minus_tau_min_bessel *= x_turning_point/sqrt(l*(l+1.));
      }
      else {
        x_turning_point = asinh(sqrt(l*(l+1.))/ptr->q[index_q]*sqrt(ptw->sgnK*ptw->K));
        tau0_minus_tau_min_bessel *= x_turning_point/sqrt(l*(l+1.));
      }
    }
  }
  /** - if there is no overlap between the region in which bessels and sources are non-zero, return zero */
  if (tau0_minus_tau_min_bessel >= tau0_minus_tau[0]) {
    *trsf = 0.;
    return _SUCCESS_;
  }

  /** - if there is an overlap: */

  /** - --> trivial case: the source is a Dirac function and is sampled in only one point */
  if (ptw->tau_size == 1) {

    class_call(transfer_radial_function(
                                        ptw,
                                        ppt,
                                        ptr,
                                        k,
                                        index_q,
                                        index_l,
                                        1,
                                        &bessel,
                                        radial_type
                                        ),
               ptr->error_message,
               ptr->error_message);

    *trsf = sources[0] * bessel;
    return _SUCCESS_;
  }

  /** - --> other cases */

  /** - ---> (a) find index in the source's tau list corresponding to the last point in the overlapping region. After this step, index_tau_max can be as small as zero, but not negative. */
  index_tau_max = ptw->tau_size-1;
  while (tau0_minus_tau[index_tau_max] < tau0_minus_tau_min_bessel)
    index_tau_max--;
  /* Set index so we know if the truncation of the convolution integral is due to Bessel and not
     due to the source. */
  index_tau_max_Bessel = index_tau_max;

  /** - ---> (b) the source function can vanish at large \f$ \tau \f$. Check if further points can be eliminated. After this step and if we did not return a null transfer function, index_tau_max can be as small as zero, but not negative. */
  while (sources[index_tau_max] == 0.) {
    index_tau_max--;
    if (index_tau_max < 0) {
      *trsf = 0.;
      return _SUCCESS_;
    }
  }

  if (ptw->neglect_late_source == _TRUE_) {

    while (tau0_minus_tau[index_tau_max] < ptw->tau0_minus_tau_cut) {
      index_tau_max--;
      if (index_tau_max < 0) {
        *trsf = 0.;
        return _SUCCESS_;
      }
    }
  }

  /** - Compute the radial function: */
  class_alloc(radial_function,sizeof(double)*(index_tau_max+1),ptr->error_message);

  class_call(transfer_radial_function(
                                      ptw,
                                      ppt,
                                      ptr,
                                      k,
                                      index_q,
                                      index_l,
                                      index_tau_max+1,
                                      radial_function,
                                      radial_type
                                      ),
             ptr->error_message,
             ptr->error_message);

  /** - Now we do most of the convolution integral: */
  class_call(array_trapezoidal_convolution(sources,
                                           radial_function,
                                           index_tau_max+1,
                                           w_trapz,
                                           trsf,
                                           ptr->error_message),
             ptr->error_message,
             ptr->error_message);

  /** - This integral is correct for the case where no truncation has
      occurred. If it has been truncated at some index_tau_max because
      f[index_tau_max+1]==0, it is still correct. The 'mistake' in using
      the wrong weight w_trapz[index_tau_max] is exactly compensated by the
      triangle we miss. However, for the Bessel cut off, we must subtract the
      wrong triangle and add the correct triangle. */
  if ((index_tau_max!=(ptw->tau_size-1))&&(index_tau_max==index_tau_max_Bessel)){
    //Bessel truncation
    *trsf -= 0.5*(tau0_minus_tau[index_tau_max+1]-tau0_minus_tau_min_bessel)*
      radial_function[index_tau_max]*sources[index_tau_max];
  }


  free(radial_function);
  return _SUCCESS_;
}

// Assembly:
subq $0x20d8, %rsp           # imm = 0x20D8
movq 0x20f0(%rsp), %rax
movl 0x20e8(%rsp), %eax
movl 0x20e0(%rsp), %eax
movq %rdi, 0x20c8(%rsp)
movq %rsi, 0x20c0(%rsp)
movq %rdx, 0x20b8(%rsp)
movl %ecx, 0x20b4(%rsp)
movl %r8d, 0x20b0(%rsp)
movl %r9d, 0x20ac(%rsp)
movsd %xmm0, 0x20a0(%rsp)
movsd %xmm1, 0x2098(%rsp)
movq 0x20b8(%rsp), %rax
movq 0x90(%rax), %rax
movq %rax, 0x2090(%rsp)
movq 0x20b8(%rsp), %rax
movq 0x98(%rax), %rax
movq %rax, 0x2088(%rsp)
movq 0x20b8(%rsp), %rax
movq 0x88(%rax), %rax
movq %rax, 0x2080(%rsp)
movq 0x20b8(%rsp), %rax
cmpl $0x0, 0xc0(%rax)
jne 0x143c78
movq 0x20b8(%rsp), %rax
movq 0x68(%rax), %rax
movq 0x28(%rax), %rax
movslq 0x20e0(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
divsd 0x2098(%rsp), %xmm0
movsd %xmm0, 0x2078(%rsp)
jmp 0x143f16
movl 0x20b4(%rsp), %eax
movq 0x20c0(%rsp), %rcx
cmpl 0x938(%rcx), %eax
jge 0x143cee
movq 0x20b8(%rsp), %rax
movq 0x28(%rax), %rax
movslq 0x20e0(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x20b8(%rsp), %rax
cvtsi2sdl 0xc0(%rax), %xmm0
movq 0x20b8(%rsp), %rax
mulsd 0xb8(%rax), %xmm0
callq 0x82e0
movaps %xmm0, %xmm1
movsd 0x38(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x2078(%rsp)
jmp 0x143f14
movq 0x20b8(%rsp), %rax
movq 0x68(%rax), %rax
movq 0x28(%rax), %rax
movslq 0x20e0(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x20b8(%rsp), %rax
cvtsi2sdl 0xc0(%rax), %xmm0
movq 0x20b8(%rsp), %rax
mulsd 0xb8(%rax), %xmm0
callq 0x82e0
movaps %xmm0, %xmm1
movsd 0x30(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x2078(%rsp)
movq 0x20b8(%rsp), %rax
cmpl $0x1, 0xc0(%rax)
jne 0x143e3c
movsd 0x20a0(%rsp), %xmm0
movsd 0x8e4d6(%rip), %xmm1    # 0x1d2248
addsd 0x20a0(%rsp), %xmm1
mulsd %xmm1, %xmm0
callq 0x82e0
movq 0x20c0(%rsp), %rax
movq 0x928(%rax), %rax
movslq 0x20b4(%rsp), %rcx
divsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0x20b8(%rsp), %rax
cvtsi2sdl 0xc0(%rax), %xmm0
movq 0x20b8(%rsp), %rax
mulsd 0xb8(%rax), %xmm0
callq 0x82e0
movaps %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
mulsd %xmm1, %xmm0
callq 0x8590
movsd %xmm0, 0x2058(%rsp)
movsd 0x2058(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x20a0(%rsp), %xmm0
movsd 0x8e442(%rip), %xmm1    # 0x1d2248
addsd 0x20a0(%rsp), %xmm1
mulsd %xmm1, %xmm0
callq 0x82e0
movaps %xmm0, %xmm1
movsd 0x28(%rsp), %xmm0
divsd %xmm1, %xmm0
mulsd 0x2078(%rsp), %xmm0
movsd %xmm0, 0x2078(%rsp)
jmp 0x143f12
movsd 0x20a0(%rsp), %xmm0
movsd 0x8e3fb(%rip), %xmm1    # 0x1d2248
addsd 0x20a0(%rsp), %xmm1
mulsd %xmm1, %xmm0
callq 0x82e0
movq 0x20c0(%rsp), %rax
movq 0x928(%rax), %rax
movslq 0x20b4(%rsp), %rcx
divsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x20b8(%rsp), %rax
cvtsi2sdl 0xc0(%rax), %xmm0
movq 0x20b8(%rsp), %rax
mulsd 0xb8(%rax), %xmm0
callq 0x82e0
movaps %xmm0, %xmm1
movsd 0x10(%rsp), %xmm0
mulsd %xmm1, %xmm0
callq 0x8480
movsd %xmm0, 0x2058(%rsp)
movsd 0x2058(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x20a0(%rsp), %xmm0
movsd 0x8e367(%rip), %xmm1    # 0x1d2248
addsd 0x20a0(%rsp), %xmm1
mulsd %xmm1, %xmm0
callq 0x82e0
movaps %xmm0, %xmm1
movsd 0x18(%rsp), %xmm0
divsd %xmm1, %xmm0
mulsd 0x2078(%rsp), %xmm0
movsd %xmm0, 0x2078(%rsp)
jmp 0x143f14
jmp 0x143f16
movsd 0x2078(%rsp), %xmm0
movq 0x2090(%rsp), %rax
ucomisd (%rax), %xmm0
jb 0x143f4c
movq 0x20f0(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl $0x0, 0x20d4(%rsp)
jmp 0x144472
movq 0x20b8(%rsp), %rax
cmpl $0x1, 0x74(%rax)
jne 0x144053
movq 0x20b8(%rsp), %rdi
movq 0x20c8(%rsp), %rsi
movq 0x20c0(%rsp), %rdx
movsd 0x2098(%rsp), %xmm0
movl 0x20b4(%rsp), %ecx
movl 0x20e0(%rsp), %r8d
movl 0x20e8(%rsp), %eax
movl $0x1, %r9d
leaq 0x2068(%rsp), %r10
movq %r10, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x144490
cmpl $0x1, %eax
jne 0x144022
leaq 0x1850(%rsp), %rdi
movq 0x20c0(%rsp), %rcx
addq $0x96a, %rcx            # imm = 0x96A
leaq 0x8e405(%rip), %rsi     # 0x1d23d8
leaq 0xc031e(%rip), %rdx     # 0x2042f8
movb $0x0, %al
callq 0x5b9c0
movq 0x20c0(%rsp), %rdi
addq $0x96a, %rdi            # imm = 0x96A
leaq 0x1850(%rsp), %r8
leaq 0x8e035(%rip), %rsi     # 0x1d2034
leaq 0xc034a(%rip), %rdx     # 0x204350
movl $0xdb3, %ecx            # imm = 0xDB3
movb $0x0, %al
callq 0x5b9c0
movl $0x1, 0x20d4(%rsp)
jmp 0x144472
movq 0x2080(%rsp), %rax
movsd (%rax), %xmm0
mulsd 0x2068(%rsp), %xmm0
movq 0x20f0(%rsp), %rax
movsd %xmm0, (%rax)
movl $0x0, 0x20d4(%rsp)
jmp 0x144472
movq 0x20b8(%rsp), %rax
movl 0x74(%rax), %eax
subl $0x1, %eax
movl %eax, 0x2074(%rsp)
movq 0x2090(%rsp), %rax
movslq 0x2074(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movsd 0x2078(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x14409f
movl 0x2074(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x2074(%rsp)
jmp 0x144068
movl 0x2074(%rsp), %eax
movl %eax, 0x2070(%rsp)
movq 0x2080(%rsp), %rax
movslq 0x2074(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x144109
jp 0x144109
movl 0x2074(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x2074(%rsp)
cmpl $0x0, 0x2074(%rsp)
jge 0x144107
movq 0x20f0(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl $0x0, 0x20d4(%rsp)
jmp 0x144472
jmp 0x1440ad
movq 0x20b8(%rsp), %rax
movswl 0xd0(%rax), %eax
cmpl $0x1, %eax
jne 0x144188
jmp 0x14411f
movq 0x2090(%rsp), %rax
movslq 0x2074(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movq 0x20b8(%rsp), %rax
movsd 0xc8(%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x144186
movl 0x2074(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x2074(%rsp)
cmpl $0x0, 0x2074(%rsp)
jge 0x144184
movq 0x20f0(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl $0x0, 0x20d4(%rsp)
jmp 0x144472
jmp 0x14411f
jmp 0x144188
movl 0x2074(%rsp), %eax
addl $0x1, %eax
movslq %eax, %rdi
shlq $0x3, %rdi
callq 0x8460
movq %rax, 0x2060(%rsp)
cmpq $0x0, 0x2060(%rsp)
jne 0x14422d
movl 0x2074(%rsp), %eax
addl $0x1, %eax
cltq
shlq $0x3, %rax
movl %eax, 0x184c(%rsp)
leaq 0x1040(%rsp), %rdi
movl 0x184c(%rsp), %ecx
leaq 0x8de26(%rip), %rsi     # 0x1d2004
leaq 0xc088f(%rip), %rdx     # 0x204a74
movb $0x0, %al
callq 0x5b9c0
movq 0x20c0(%rsp), %rdi
addq $0x96a, %rdi            # imm = 0x96A
leaq 0x1040(%rsp), %r8
leaq 0x8de2a(%rip), %rsi     # 0x1d2034
leaq 0xc013f(%rip), %rdx     # 0x204350
movl $0xdd8, %ecx            # imm = 0xDD8
movb $0x0, %al
callq 0x5b9c0
movl $0x1, 0x20d4(%rsp)
jmp 0x144472
movq 0x20b8(%rsp), %rdi
movq 0x20c8(%rsp), %rsi
movq 0x20c0(%rsp), %rdx
movsd 0x2098(%rsp), %xmm0
movl 0x20b4(%rsp), %ecx
movl 0x20e0(%rsp), %r8d
movl 0x2074(%rsp), %r9d
addl $0x1, %r9d
movq 0x2060(%rsp), %r10
movl 0x20e8(%rsp), %eax
movq %r10, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x144490
cmpl $0x1, %eax
jne 0x1442f7
leaq 0x840(%rsp), %rdi
movq 0x20c0(%rsp), %rcx
addq $0x96a, %rcx            # imm = 0x96A
leaq 0x8e130(%rip), %rsi     # 0x1d23d8
leaq 0xc00b4(%rip), %rdx     # 0x204363
movb $0x0, %al
callq 0x5b9c0
movq 0x20c0(%rsp), %rdi
addq $0x96a, %rdi            # imm = 0x96A
leaq 0x840(%rsp), %r8
leaq 0x8dd60(%rip), %rsi     # 0x1d2034
leaq 0xc0075(%rip), %rdx     # 0x204350
movl $0xde6, %ecx            # imm = 0xDE6
movb $0x0, %al
callq 0x5b9c0
movl $0x1, 0x20d4(%rsp)
jmp 0x144472
movq 0x2080(%rsp), %rdi
movq 0x2060(%rsp), %rsi
movl 0x2074(%rsp), %edx
addl $0x1, %edx
movq 0x2088(%rsp), %rcx
movq 0x20f0(%rsp), %r8
movq 0x20c0(%rsp), %r9
addq $0x96a, %r9             # imm = 0x96A
callq 0x2aba0
cmpl $0x1, %eax
jne 0x1443a1
leaq 0x40(%rsp), %rdi
movq 0x20c0(%rsp), %rcx
addq $0x96a, %rcx            # imm = 0x96A
leaq 0x8e083(%rip), %rsi     # 0x1d23d8
leaq 0xc0075(%rip), %rdx     # 0x2043d1
movb $0x0, %al
callq 0x5b9c0
movq 0x20c0(%rsp), %rdi
addq $0x96a, %rdi            # imm = 0x96A
leaq 0x40(%rsp), %r8
leaq 0x8dcb6(%rip), %rsi     # 0x1d2034
leaq 0xbffcb(%rip), %rdx     # 0x204350
movl $0xdf0, %ecx            # imm = 0xDF0
movb $0x0, %al
callq 0x5b9c0
movl $0x1, 0x20d4(%rsp)
jmp 0x144472
movl 0x2074(%rsp), %eax
movq 0x20b8(%rsp), %rcx
movl 0x74(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x14445a
movl 0x2074(%rsp), %eax
cmpl 0x2070(%rsp), %eax
jne 0x14445a
movq 0x2090(%rsp), %rax
movl 0x2074(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm1
subsd 0x2078(%rsp), %xmm1
movsd 0x8e88b(%rip), %xmm0    # 0x1d2c88
mulsd %xmm1, %xmm0
movq 0x2060(%rsp), %rax
movslq 0x2074(%rsp), %rcx
mulsd (%rax,%rcx,8), %xmm0
movq 0x2080(%rsp), %rax
movslq 0x2074(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm2
movq 0x20f0(%rsp), %rax
movsd (%rax), %xmm1
movq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq 0x2060(%rsp), %rdi
callq 0x8420
movl $0x0, 0x20d4(%rsp)
movl 0x20d4(%rsp), %eax
addq $0x20d8, %rsp           # imm = 0x20D8
retq
nopw %cs:(%rax,%rax)