// File: /workspace/github_c_makefile_star2_O3/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x858, %rsp            # imm = 0x858
movl %ecx, %ebx
movq %rdx, %r15
movq %rsi, %r12
movl 0x890(%rsp), %r8d
movq 0x88(%rdx), %r14
movq 0x90(%rdx), %rbp
movq 0x98(%rdx), %r13
movl 0xc0(%rdx), %ecx
movslq %r8d, %rax
testl %ecx, %ecx
je 0xae548
movapd %xmm0, %xmm3
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
cmpl %ebx, 0x938(%r12)
jle 0xae55e
movq 0x28(%r15), %rcx
mulsd 0xb8(%r15), %xmm0
movsd (%rcx,%rax,8), %xmm2
xorpd %xmm3, %xmm3
ucomisd %xmm3, %xmm0
jb 0xae595
sqrtsd %xmm0, %xmm0
jmp 0xae5ba
movq 0x68(%r15), %rcx
movq 0x28(%rcx), %rcx
movsd (%rcx,%rax,8), %xmm2
divsd %xmm1, %xmm2
jmp 0xae6d5
movq 0x68(%r15), %rcx
movq 0x28(%rcx), %rcx
mulsd 0xb8(%r15), %xmm0
movsd (%rcx,%rax,8), %xmm2
xorpd %xmm4, %xmm4
ucomisd %xmm4, %xmm0
movsd %xmm2, 0x18(%rsp)
movq %r13, 0x20(%rsp)
movsd %xmm1, 0x10(%rsp)
jb 0xae5c3
sqrtsd %xmm0, %xmm0
jmp 0xae5d8
movsd %xmm2, 0x18(%rsp)
movsd %xmm1, 0x10(%rsp)
callq 0x82b0
movl 0x890(%rsp), %r8d
movsd 0x10(%rsp), %xmm1
movsd 0x18(%rsp), %xmm2
divsd %xmm0, %xmm2
jmp 0xae6d5
movsd %xmm3, 0x8(%rsp)
callq 0x82b0
xorpd %xmm4, %xmm4
movsd 0x8(%rsp), %xmm3
movsd %xmm0, 0x30(%rsp)
movl 0xc0(%r15), %r13d
movsd 0x3fc73(%rip), %xmm0    # 0xee260
addsd %xmm3, %xmm0
mulsd %xmm3, %xmm0
ucomisd %xmm4, %xmm0
movsd %xmm0, 0x8(%rsp)
jb 0xae60a
xorps %xmm2, %xmm2
sqrtsd %xmm0, %xmm2
jmp 0xae613
callq 0x82b0
movapd %xmm0, %xmm2
movq 0x928(%r12), %rax
movslq %ebx, %rcx
divsd (%rax,%rcx,8), %xmm2
xorps %xmm0, %xmm0
cvtsi2sdl 0xc0(%r15), %xmm0
mulsd 0xb8(%r15), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0xae648
sqrtsd %xmm0, %xmm0
jmp 0xae659
movsd %xmm2, 0x38(%rsp)
callq 0x82b0
movsd 0x38(%rsp), %xmm2
movsd 0x18(%rsp), %xmm1
mulsd %xmm0, %xmm2
divsd 0x30(%rsp), %xmm1
movsd %xmm1, 0x18(%rsp)
movapd %xmm2, %xmm0
cmpl $0x1, %r13d
jne 0xae680
callq 0x85a0
jmp 0xae685
callq 0x8470
movapd %xmm0, %xmm3
xorpd %xmm0, %xmm0
movsd 0x8(%rsp), %xmm1
ucomisd %xmm0, %xmm1
movapd %xmm1, %xmm0
jb 0xae6a3
sqrtsd %xmm0, %xmm0
jmp 0xae6b4
movsd %xmm3, 0x8(%rsp)
callq 0x82b0
movsd 0x8(%rsp), %xmm3
movsd 0x10(%rsp), %xmm1
movl 0x890(%rsp), %r8d
movq 0x20(%rsp), %r13
divsd %xmm0, %xmm3
movsd 0x18(%rsp), %xmm2
mulsd %xmm3, %xmm2
movq 0x8a0(%rsp), %rdi
ucomisd (%rbp), %xmm2
jae 0xae822
movq %r13, 0x20(%rsp)
movl 0x898(%rsp), %esi
movslq 0x74(%r15), %r13
cmpq $0x1, %r13
jne 0xae77d
movq %rdi, %rbp
leaq 0x48(%rsp), %rax
movl $0x1, %r13d
movq %r15, %rdi
movq %r12, %rdx
movapd %xmm1, %xmm0
movl %ebx, %ecx
movl $0x1, %r9d
pushq %rsi
pushq %rax
callq 0xaea40
addq $0x10, %rsp
testl %eax, %eax
je 0xae900
addq $0x96a, %r12            # imm = 0x96A
leaq 0x3fcb1(%rip), %rsi     # 0xee3f0
leaq 0x715f0(%rip), %rdx     # 0x11fd36
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movq %r12, %rcx
xorl %eax, %eax
callq 0x30af0
leaq 0x3f8d5(%rip), %rsi     # 0xee034
leaq 0x71628(%rip), %rdx     # 0x11fd8e
movq %r12, %rdi
movl $0xdb3, %ecx            # imm = 0xDB3
movq %r14, %r8
xorl %eax, %eax
callq 0x30af0
jmp 0xae82c
movl %ebx, 0x30(%rsp)
movq %r12, 0x8(%rsp)
leal -0x1(%r13), %eax
movslq %eax, %rcx
leaq 0x8(,%rcx,8), %rax
addq %rbp, %rax
movq %r13, %r12
shlq $0x20, %r12
movq %rbp, 0x38(%rsp)
leaq -0x8(,%r13,8), %rdx
addq %rbp, %rdx
xorl %ebp, %ebp
movabsq $-0x100000000, %rsi     # imm = 0xFFFFFFFF00000000
addq %rsi, %r12
addq $-0x8, %rax
ucomisd (%rdx,%rbp,8), %xmm2
leaq -0x1(%rbp), %rbp
ja 0xae7bb
leaq (%rcx,%rbp), %rbx
incq %rbx
xorpd %xmm0, %xmm0
movsd (%r14,%rbx,8), %xmm3
ucomisd %xmm0, %xmm3
jne 0xae7f8
jp 0xae7f8
leaq -0x1(%rbx), %rcx
addq $-0x8, %rax
testq %rbx, %rbx
movq %rcx, %rbx
jg 0xae7d8
jmp 0xae822
cmpw $0x1, 0xd0(%r15)
jne 0xae841
movsd 0xc8(%r15), %xmm0
ucomisd (%rax), %xmm0
jbe 0xae841
leaq -0x1(%rbx), %rcx
addq $-0x8, %rax
testq %rbx, %rbx
movq %rcx, %rbx
jg 0xae80c
movq $0x0, (%rdi)
xorl %r13d, %r13d
movl %r13d, %eax
addq $0x858, %rsp            # imm = 0x858
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movsd %xmm1, 0x10(%rsp)
movsd %xmm2, 0x18(%rsp)
movslq %ebx, %rax
movq %rax, 0x28(%rsp)
leaq 0x8(,%rax,8), %rdi
movq %rdi, 0x40(%rsp)
callq 0x8460
testq %rax, %rax
je 0xae915
movq %rax, %rsi
movq 0x28(%rsp), %r9
incq %r9
movq %r15, %rdi
movq 0x8(%rsp), %rdx
movsd 0x10(%rsp), %xmm0
movl 0x30(%rsp), %ecx
movl 0x890(%rsp), %r8d
movq %r9, 0x28(%rsp)
movl 0x898(%rsp), %eax
pushq %rax
pushq %rsi
movq %rsi, 0x20(%rsp)
callq 0xaea40
addq $0x10, %rsp
testl %eax, %eax
je 0xae958
movq 0x8(%rsp), %rbx
addq $0x96a, %rbx            # imm = 0x96A
leaq 0x3fb24(%rip), %rsi     # 0xee3f0
leaq 0x714ce(%rip), %rdx     # 0x11fda1
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x30af0
leaq 0x3f748(%rip), %rsi     # 0xee034
leaq 0x7149b(%rip), %rdx     # 0x11fd8e
movq %rbx, %rdi
movl $0xde6, %ecx            # imm = 0xDE6
jmp 0xae9c8
movsd (%r14), %xmm0
mulsd 0x48(%rsp), %xmm0
movsd %xmm0, (%rbp)
jmp 0xae829
leaq 0x3f6e8(%rip), %rsi     # 0xee004
leaq 0x71b8f(%rip), %rdx     # 0x1204b2
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movq 0x40(%rsp), %rcx
xorl %eax, %eax
callq 0x30af0
movq 0x8(%rsp), %rdi
addq $0x96a, %rdi            # imm = 0x96A
leaq 0x3f6ea(%rip), %rsi     # 0xee034
leaq 0x7143d(%rip), %rdx     # 0x11fd8e
movl $0xdd8, %ecx            # imm = 0xDD8
jmp 0xae9c8
movq 0x8(%rsp), %r9
addq $0x96a, %r9             # imm = 0x96A
movq %r14, %rdi
movq 0x10(%rsp), %rsi
movq 0x28(%rsp), %rdx
movq 0x20(%rsp), %rcx
movq 0x8a0(%rsp), %r8
movq %r9, 0x8(%rsp)
callq 0x1b547
cmpl $0x1, %eax
jne 0xae9dd
leaq 0x3fa5c(%rip), %rsi     # 0xee3f0
leaq 0x71474(%rip), %rdx     # 0x11fe0f
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movq 0x8(%rsp), %rbx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x30af0
leaq 0x3f67b(%rip), %rsi     # 0xee034
leaq 0x713ce(%rip), %rdx     # 0x11fd8e
movq %rbx, %rdi
movl $0xdf0, %ecx            # imm = 0xDF0
movq %r14, %r8
xorl %eax, %eax
callq 0x30af0
movl $0x1, %r13d
jmp 0xae82c
negl %r13d
movq %rbx, %rax
addq %r13, %rax
cmpl %ebp, %eax
movq 0x10(%rsp), %rdi
jne 0xaea36
movl 0x74(%r15), %eax
decl %eax
cmpl %ebx, %eax
je 0xaea36
movq 0x38(%rsp), %rax
movq 0x28(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
subsd 0x18(%rsp), %xmm0
sarq $0x1d, %r12
mulsd 0x42a5e(%rip), %xmm0    # 0xf1478
mulsd (%rdi,%r12), %xmm0
mulsd (%r14,%r12), %xmm0
movq 0x8a0(%rsp), %rax
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
callq 0x8410
jmp 0xae829