// File: /workspace/github_c_makefile_star2_O3/PoulinV[P]AxiCLASS/build/../source/fourier.c
// Function: fourier_get_source
int fourier_get_source(
                       struct background * pba,
                       struct perturbations * ppt,
                       struct fourier * pfo,
                       int index_k,
                       int index_ic,
                       int index_tp,
                       int index_tau,
                       double ** sources,
                       double * source
                       ) {

  double k,k_max,k_previous;
  double source_max,source_previous;
  double scaled_factor,log_scaled_factor;

  /** - use precomputed values */
  if (index_k < pfo->k_size) {
    *source = sources[index_ic * ppt->tp_size[pfo->index_md_scalars] + index_tp][index_tau * pfo->k_size + index_k];
  }
  /** - extrapolate **/
  else {

    k = pfo->k[index_k];

    /**
     * --> Get last source and k, which are used in (almost) all methods
     */
    k_max = pfo->k[pfo->k_size-1];
    source_max = sources[index_ic * ppt->tp_size[pfo->index_md_scalars] + index_tp][index_tau * pfo->k_size + pfo->k_size - 1];

    /**
     * --> Get previous source and k, which are used in best methods
     */
    k_previous = pfo->k[pfo->k_size-2];
    source_previous = sources[index_ic * ppt->tp_size[pfo->index_md_scalars] + index_tp][index_tau * pfo->k_size + pfo->k_size - 2];

    switch(pfo->extrapolation_method){
      /**
       * --> Extrapolate by assuming the source to vanish Has terrible
       * discontinuity
       */
    case extrap_zero:
      {
        *source=0.0;
        break;
      }
      /**
       * --> Extrapolate starting from the maximum value, assuming  growth ~ ln(k)
       * Has a terrible bend in log slope, discontinuity only in derivative
       */
    case extrap_only_max:
      {
        *source = source_max*(log(k)/log(k_max));
        break;
      }
      /**
       * --> Extrapolate starting from the maximum value, assuming
       * growth ~ ln(k) Here we use k in h/Mpc instead of 1/Mpc as it
       * is done in the CAMB implementation of HMcode Has a terrible
       * bend in log slope, discontinuity only in derivative
       */
    case extrap_only_max_units:
      {
        *source = source_max*(log(k/pba->h)/log(k_max/pba->h));
        break;
      }
      /**
       * --> Extrapolate assuming source ~ ln(a*k) where a is obtained
       * from the data at k_0 Mostly continuous derivative, quite good
       */
    case extrap_max_scaled:
      {
        log_scaled_factor = (source_previous*log(k_max)-source_max*log(k_previous))/(source_max-source_previous);
        *source = source_max*((log_scaled_factor+log(k))/(log_scaled_factor+log(k_max)));
        break;
      }
      /**
       * --> Extrapolate assuming source ~ ln(e+a*k) where a is
       * estimated like is done in original HMCode
       */
    case extrap_hmcode:
      {
        scaled_factor = 1.8/(13.41*pba->a_eq*pba->H_eq);
        *source = source_max*(log(_E_+scaled_factor*k)/log(_E_+scaled_factor*k_max));
        break;
      }
      /**
       * --> If the user has a complicated model and wants to
       * interpolate differently, they can define their interpolation
       * here and switch to using it instead
       */
    case extrap_user_defined:
      {
        class_stop(pfo->error_message,"Method of source extrapolation 'user_defined' was not yet defined.");
        break;
      }
    }
  }
  return _SUCCESS_;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x1038, %rsp           # imm = 0x1038
movq %rdx, %r14
movq %rdi, %r15
movq 0x1070(%rsp), %r12
movq 0x1068(%rsp), %rdi
movl 0x1060(%rsp), %edx
movslq 0x6c(%r14), %rax
cmpl %ecx, %eax
jle 0xa3996
movq 0x998(%rsi), %rsi
movslq 0x3c(%r14), %r10
imull (%rsi,%r10,4), %r8d
addl %r9d, %r8d
movslq %r8d, %rsi
movq (%rdi,%rsi,8), %rsi
imull %edx, %eax
addl %ecx, %eax
cltq
movsd (%rsi,%rax,8), %xmm0
movsd %xmm0, (%r12)
xorl %ebx, %ebx
jmp 0xa3bec
movl 0x4(%r14), %r10d
xorl %ebx, %ebx
cmpq $0x5, %r10
ja 0xa3bec
movq 0x78(%r14), %r11
movslq %ecx, %rcx
movsd (%r11,%rcx,8), %xmm2
movsd -0x8(%r11,%rax,8), %xmm1
movq 0x998(%rsi), %rcx
movslq 0x3c(%r14), %rsi
imull (%rcx,%rsi,4), %r8d
addl %r9d, %r8d
movslq %r8d, %rcx
movq (%rdi,%rcx,8), %rcx
incl %edx
imull %eax, %edx
movslq %edx, %rdx
movsd -0x8(%rcx,%rdx,8), %xmm0
leaq 0x77967(%rip), %rsi     # 0x11b350
movslq (%rsi,%r10,4), %rdi
addq %rsi, %rdi
jmpq *%rdi
movq $0x0, (%r12)
jmp 0xa3bec
movsd %xmm0, 0x8(%rsp)
movsd 0x360(%r15), %xmm0
mulsd 0x7791a(%rip), %xmm0    # 0x11b330
mulsd 0x368(%r15), %xmm0
movsd 0x4d569(%rip), %xmm3    # 0xf0f90
divsd %xmm0, %xmm3
movsd %xmm3, 0x18(%rsp)
mulsd %xmm3, %xmm2
addsd 0x778fb(%rip), %xmm2    # 0x11b338
movapd %xmm2, %xmm0
movsd %xmm1, 0x10(%rsp)
callq 0x82c0
movsd %xmm0, (%rsp)
movsd 0x18(%rsp), %xmm0
mulsd 0x10(%rsp), %xmm0
addsd 0x778d3(%rip), %xmm0    # 0x11b338
jmp 0xa3b6e
divsd 0x8(%r15), %xmm2
movsd %xmm0, 0x8(%rsp)
movapd %xmm2, %xmm0
movsd %xmm1, 0x10(%rsp)
callq 0x82c0
movsd %xmm0, (%rsp)
movsd 0x10(%rsp), %xmm0
divsd 0x8(%r15), %xmm0
jmp 0xa3b6e
movsd -0x10(%rcx,%rdx,8), %xmm3
movsd %xmm3, 0x28(%rsp)
movsd -0x10(%r11,%rax,8), %xmm3
movsd %xmm3, 0x20(%rsp)
movsd %xmm0, 0x8(%rsp)
movapd %xmm1, %xmm0
movsd %xmm1, 0x10(%rsp)
movsd %xmm2, 0x18(%rsp)
callq 0x82c0
movsd %xmm0, (%rsp)
movsd 0x20(%rsp), %xmm0
callq 0x82c0
movsd 0x8(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd (%rsp), %xmm2
movsd 0x28(%rsp), %xmm3
mulsd %xmm3, %xmm2
subsd %xmm0, %xmm2
movapd %xmm1, %xmm0
subsd %xmm3, %xmm0
divsd %xmm0, %xmm2
movsd %xmm2, (%rsp)
movsd 0x18(%rsp), %xmm0
callq 0x82c0
addsd (%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x10(%rsp), %xmm0
callq 0x82c0
addsd (%rsp), %xmm0
movsd 0x18(%rsp), %xmm1
divsd %xmm0, %xmm1
mulsd 0x8(%rsp), %xmm1
movsd %xmm1, (%r12)
jmp 0xa3bec
movsd %xmm0, 0x8(%rsp)
movapd %xmm2, %xmm0
movsd %xmm1, 0x10(%rsp)
callq 0x82c0
movsd %xmm0, (%rsp)
movsd 0x10(%rsp), %xmm0
callq 0x82c0
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, (%r12)
jmp 0xa3bec
leaq 0x7a020(%rip), %rsi     # 0x11dbb5
leaq 0x830(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x30af0
leaq 0x4a9d7(%rip), %rsi     # 0xee585
leaq 0x30(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x30af0
addq $0x192, %r14            # imm = 0x192
leaq 0x4a466(%rip), %rsi     # 0xee034
leaq 0x7a023(%rip), %rdx     # 0x11dbf8
movq %r14, %rdi
movl $0x930, %ecx            # imm = 0x930
movq %r15, %r8
xorl %eax, %eax
callq 0x30af0
movl $0x1, %ebx
movl %ebx, %eax
addq $0x1038, %rsp           # imm = 0x1038
popq %rbx
popq %r12
popq %r14
popq %r15
retq