// File: /workspace/github_c_makefile_star2_O1/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 $0x848, %rsp            # imm = 0x848
movl %ecx, %ebp
movq %rdx, %r15
movq %rsi, %rbx
movl 0x880(%rsp), %r8d
movq 0x88(%rdx), %r14
movq 0x90(%rdx), %r13
movq 0x98(%rdx), %r12
movl 0xc0(%rdx), %ecx
movslq %r8d, %rax
testl %ecx, %ecx
je 0xb15cc
movapd %xmm0, %xmm3
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
cmpl %ebp, 0x938(%rbx)
jle 0xb15e2
movq 0x28(%r15), %rcx
mulsd 0xb8(%r15), %xmm0
movsd (%rcx,%rax,8), %xmm2
xorpd %xmm3, %xmm3
ucomisd %xmm3, %xmm0
jb 0xb1618
sqrtsd %xmm0, %xmm0
jmp 0xb163b
movq 0x68(%r15), %rcx
movq 0x28(%rcx), %rcx
movsd (%rcx,%rax,8), %xmm2
divsd %xmm1, %xmm2
jmp 0xb1754
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, 0x10(%rsp)
movq %r12, 0x20(%rsp)
movsd %xmm1, (%rsp)
jb 0xb1644
sqrtsd %xmm0, %xmm0
jmp 0xb1659
movsd %xmm2, 0x10(%rsp)
movsd %xmm1, (%rsp)
callq 0x82b0
movl 0x880(%rsp), %r8d
movsd (%rsp), %xmm1
movsd 0x10(%rsp), %xmm2
divsd %xmm0, %xmm2
jmp 0xb1754
movsd %xmm3, 0x8(%rsp)
callq 0x82b0
xorpd %xmm4, %xmm4
movsd 0x8(%rsp), %xmm3
movsd %xmm0, 0x28(%rsp)
movl 0xc0(%r15), %r12d
movsd 0x3fbf2(%rip), %xmm0    # 0xf1260
addsd %xmm3, %xmm0
mulsd %xmm3, %xmm0
ucomisd %xmm4, %xmm0
movsd %xmm0, 0x8(%rsp)
jb 0xb168b
xorps %xmm2, %xmm2
sqrtsd %xmm0, %xmm2
jmp 0xb1694
callq 0x82b0
movapd %xmm0, %xmm2
movq 0x928(%rbx), %rax
movslq %ebp, %rcx
divsd (%rax,%rcx,8), %xmm2
xorps %xmm0, %xmm0
cvtsi2sdl 0xc0(%r15), %xmm0
mulsd 0xb8(%r15), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0xb16c8
sqrtsd %xmm0, %xmm0
jmp 0xb16d9
movsd %xmm2, 0x18(%rsp)
callq 0x82b0
movsd 0x18(%rsp), %xmm2
movsd 0x10(%rsp), %xmm1
mulsd %xmm0, %xmm2
divsd 0x28(%rsp), %xmm1
movsd %xmm1, 0x10(%rsp)
movapd %xmm2, %xmm0
cmpl $0x1, %r12d
jne 0xb1700
callq 0x85a0
jmp 0xb1705
callq 0x8470
movapd %xmm0, %xmm3
xorpd %xmm0, %xmm0
movsd 0x8(%rsp), %xmm1
ucomisd %xmm0, %xmm1
movapd %xmm1, %xmm0
jb 0xb1723
sqrtsd %xmm0, %xmm0
jmp 0xb1734
movsd %xmm3, 0x8(%rsp)
callq 0x82b0
movsd 0x8(%rsp), %xmm3
movsd (%rsp), %xmm1
movl 0x880(%rsp), %r8d
movq 0x20(%rsp), %r12
divsd %xmm0, %xmm3
movsd 0x10(%rsp), %xmm2
mulsd %xmm3, %xmm2
movq 0x890(%rsp), %rsi
ucomisd (%r13), %xmm2
jae 0xb1892
movq %r12, 0x20(%rsp)
movl 0x888(%rsp), %r10d
movslq 0x74(%r15), %r12
cmpq $0x1, %r12
jne 0xb1803
movq %rsi, %r12
leaq 0x38(%rsp), %rax
movl $0x1, %r13d
movq %r15, %rdi
movq %rbx, %rdx
movapd %xmm1, %xmm0
movl %ebp, %ecx
movl $0x1, %r9d
pushq %r10
pushq %rax
callq 0xb1a8d
addq $0x10, %rsp
testl %eax, %eax
je 0xb1967
addq $0x96a, %rbx            # imm = 0x96A
leaq 0x3fc2b(%rip), %rsi     # 0xf13f0
leaq 0x7152a(%rip), %rdx     # 0x122cf6
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x30c2c
leaq 0x3f84f(%rip), %rsi     # 0xf1034
leaq 0x71562(%rip), %rdx     # 0x122d4e
movq %rbx, %rdi
movl $0xdb3, %ecx            # imm = 0xDB3
movq %r14, %r8
xorl %eax, %eax
callq 0x30c2c
jmp 0xb189c
movl %ebp, 0x8(%rsp)
leal -0x1(%r12), %eax
movslq %eax, %rcx
leaq 0x8(,%rcx,8), %rax
addq %r13, %rax
movq %r13, 0x28(%rsp)
leaq -0x8(,%r12,8), %rdx
addq %r13, %rdx
xorl %r13d, %r13d
addq $-0x8, %rax
ucomisd (%rdx,%r13,8), %xmm2
leaq -0x1(%r13), %r13
ja 0xb182d
leaq (%rcx,%r13), %rbp
incq %rbp
xorpd %xmm0, %xmm0
movsd (%r14,%rbp,8), %xmm3
ucomisd %xmm0, %xmm3
jne 0xb1868
jp 0xb1868
leaq -0x1(%rbp), %rcx
addq $-0x8, %rax
testq %rbp, %rbp
movq %rcx, %rbp
jg 0xb1848
jmp 0xb1892
cmpw $0x1, 0xd0(%r15)
jne 0xb18b1
movsd 0xc8(%r15), %xmm0
ucomisd (%rax), %xmm0
jbe 0xb18b1
leaq -0x1(%rbp), %rcx
addq $-0x8, %rax
testq %rbp, %rbp
movq %rcx, %rbp
jg 0xb187c
movq $0x0, (%rsi)
xorl %r13d, %r13d
movl %r13d, %eax
addq $0x848, %rsp            # imm = 0x848
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movsd %xmm1, (%rsp)
movsd %xmm2, 0x10(%rsp)
movslq %ebp, %rax
movq %rax, 0x18(%rsp)
leaq 0x8(,%rax,8), %rdi
movq %rdi, 0x30(%rsp)
callq 0x8460
testq %rax, %rax
je 0xb197d
movq %rax, %rsi
movq 0x18(%rsp), %r9
incq %r9
movq %r15, %rdi
movq %rbx, %rdx
movsd (%rsp), %xmm0
movl 0x8(%rsp), %ecx
movl 0x880(%rsp), %r8d
movq %r9, 0x18(%rsp)
movl 0x888(%rsp), %eax
pushq %rax
pushq %rsi
movq %rsi, 0x10(%rsp)
callq 0xb1a8d
addq $0x10, %rsp
addq $0x96a, %rbx            # imm = 0x96A
testl %eax, %eax
je 0xb19be
leaq 0x3fabd(%rip), %rsi     # 0xf13f0
leaq 0x71427(%rip), %rdx     # 0x122d61
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x30c2c
leaq 0x3f6e1(%rip), %rsi     # 0xf1034
leaq 0x713f4(%rip), %rdx     # 0x122d4e
movq %rbx, %rdi
movl $0xde6, %ecx            # imm = 0xDE6
jmp 0xb1a1a
movsd (%r14), %xmm0
mulsd 0x38(%rsp), %xmm0
movsd %xmm0, (%r12)
jmp 0xb1899
leaq 0x3f680(%rip), %rsi     # 0xf1004
leaq 0x71ae7(%rip), %rdx     # 0x123472
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movq 0x30(%rsp), %rcx
xorl %eax, %eax
callq 0x30c2c
addq $0x96a, %rbx            # imm = 0x96A
leaq 0x3f687(%rip), %rsi     # 0xf1034
leaq 0x7139a(%rip), %rdx     # 0x122d4e
movq %rbx, %rdi
movl $0xdd8, %ecx            # imm = 0xDD8
jmp 0xb1a1a
movq %r14, %rdi
movq (%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x20(%rsp), %rcx
movq 0x890(%rsp), %r8
movq %rbx, %r9
callq 0x1b494
cmpl $0x1, %eax
jne 0xb1a2f
leaq 0x3fa05(%rip), %rsi     # 0xf13f0
leaq 0x713dd(%rip), %rdx     # 0x122dcf
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x30c2c
leaq 0x3f629(%rip), %rsi     # 0xf1034
leaq 0x7133c(%rip), %rdx     # 0x122d4e
movq %rbx, %rdi
movl $0xdf0, %ecx            # imm = 0xDF0
movq %r14, %r8
xorl %eax, %eax
callq 0x30c2c
movl $0x1, %r13d
jmp 0xb189c
negl %r12d
addq %rbp, %r12
cmpl %r13d, %r12d
movq (%rsp), %rdi
jne 0xb1a83
movl 0x74(%r15), %eax
decl %eax
cmpl %ebp, %eax
je 0xb1a83
movq 0x28(%rsp), %rax
movq 0x18(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
subsd 0x10(%rsp), %xmm0
movslq %ebp, %rax
mulsd 0x42a00(%rip), %xmm0    # 0xf4468
mulsd (%rdi,%rax,8), %xmm0
mulsd (%r14,%rax,8), %xmm0
movq 0x890(%rsp), %rax
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
callq 0x8410
jmp 0xb1899