// File: /workspace/github_cpp_makefile_star2_O1/TBody[P]atomicpp/atomicpp/Spline/BilinearSpline.cpp
// Function: atomicpp::BilinearSpline::call0D(double, double)
double BilinearSpline::call0D(const double eval_x, const double eval_y){
	
	// Bounds checking -- make sure you haven't dropped off the end of the array
	if ((eval_x <= x_values[0]) or (eval_x >= x_values[x_values.size()-1])){
		// An easy error to make is supplying the function arguments already having taken the log10
		std::stringstream errMsg;
		errMsg << "X value off grid - require (" << x_values[0] << " < " << eval_x << " < " << x_values[x_values.size()-1] << ")";
		throw std::runtime_error(errMsg.str());
	};
	if ((eval_y <= y_values[0]) or (eval_y >= y_values[y_values.size()-1])){
		// An easy error to make is supplying the function arguments already having taken the log10
		std::stringstream errMsg;
		errMsg << "Y value off grid - require (" << y_values[0] << " < " << eval_y << " < " << y_values[y_values.size()-1] << ")";
		throw std::runtime_error(errMsg.str());
	};

	// Perform a basic interpolation based on linear distance
	// values to search for
	// Look through the x_values and y_values attributes of RateCoefficient to find nearest (strictly lower)
	// Subtract 1 from answer to account for indexing from 0
	int low_x = lower_bound(x_values.begin(), x_values.end(), eval_x) - x_values.begin() - 1;
	int low_y = lower_bound(y_values.begin(), y_values.end(), eval_y) - y_values.begin() - 1;

	double x_norm = 1/(x_values[low_x+1] - x_values[low_x+0]); //Spacing between grid points
	double y_norm = 1/(y_values[low_y+1] - y_values[low_y+0]); //Spacing between grid points

	double x = (eval_x - x_values[low_x+0])*x_norm;
	double y = (eval_y - y_values[low_y+0])*y_norm;

	// // Construct the simple interpolation grid
	// // Find weightings based on linear distance
	// // w01 ------ w11    y
	// //  | \     / |      |
	// //  |  w(x,y) |    --/--x
	// //  | /     \ |      |
	// // w00 ------ w10

	double eval_coeff =
	 (z_values[low_x+0][low_y+0]*(1-y) + z_values[low_x+0][low_y+1]*y)*(1-x)
	+(z_values[low_x+1][low_y+0]*(1-y) + z_values[low_x+1][low_y+1]*y)*x;

	return eval_coeff;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1e8, %rsp            # imm = 0x1E8
movsd %xmm0, -0x30(%rbp)
movq %rdi, %rbx
movsd %xmm0, -0x50(%rbp)
movsd %xmm1, -0x48(%rbp)
xorl %esi, %esi
callq 0x539c
movsd (%rax), %xmm0
ucomisd -0x30(%rbp), %xmm0
jae 0x155a5
movsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movq %rbx, %rdi
callq 0x12b54
leaq -0x1(%rax), %rsi
movq %rbx, %rdi
callq 0x539c
movsd -0x30(%rbp), %xmm0
ucomisd (%rax), %xmm0
jae 0x155a5
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
leaq 0x18(%rbx), %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x539c
movsd (%rax), %xmm0
ucomisd -0x30(%rbp), %xmm0
jae 0x15684
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movq %r14, %rdi
callq 0x12b54
leaq -0x1(%rax), %rsi
movq %r14, %rdi
callq 0x539c
movsd -0x30(%rbp), %xmm0
ucomisd (%rax), %xmm0
jae 0x15684
movq %rbx, %rdi
callq 0x12e9a
movq %rax, %r15
movq %rbx, %rdi
callq 0x131ee
leaq -0x50(%rbp), %rdx
movq %r15, %rdi
movq %rax, %rsi
callq 0x15c83
leaq -0x208(%rbp), %r12
movq %rax, (%r12)
movq %rbx, %rdi
callq 0x12e9a
leaq -0x80(%rbp), %r13
movq %rax, (%r13)
movq %r12, %rdi
movq %r13, %rsi
callq 0x131b7
movq %rax, -0x30(%rbp)
movq %r14, %rdi
callq 0x12e9a
movq %rax, %r15
movq %r14, %rdi
callq 0x131ee
leaq -0x48(%rbp), %rdx
movq %r15, %rdi
movq %rax, %rsi
callq 0x15c83
movq %rax, (%r12)
movq %r14, %rdi
callq 0x12e9a
movq %rax, (%r13)
leaq -0x208(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x131b7
movq %rax, %r12
movslq -0x30(%rbp), %r15
movq %r15, -0x60(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x539c
movsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
leal -0x1(%r15), %eax
movslq %eax, %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x539c
movsd -0x30(%rbp), %xmm1
subsd (%rax), %xmm1
movsd 0xcbe1(%rip), %xmm0     # 0x22008
divsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movslq %r12d, %r12
movq %r14, %rdi
movq %r12, %rsi
callq 0x539c
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
leal -0x1(%r12), %eax
movslq %eax, %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x539c
movsd -0x38(%rbp), %xmm1
subsd (%rax), %xmm1
movsd 0xcb9d(%rip), %xmm0     # 0x22008
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
leaq -0x50(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x539c
movsd -0x38(%rbp), %xmm0
subsd (%rax), %xmm0
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
leaq -0x48(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
movq %r14, %rdi
movq %r13, %rsi
callq 0x539c
movsd -0x30(%rbp), %xmm0
subsd (%rax), %xmm0
mulsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
addq $0x30, %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x15cb4
movq %rax, %rdi
movq %r13, %rsi
callq 0x539c
movsd 0xcb1c(%rip), %xmm0     # 0x22008
subsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x40(%rbp)
movsd (%rax), %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, -0x58(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x15cb4
movq %rax, %rdi
movq %r12, %rsi
callq 0x539c
movsd (%rax), %xmm0
mulsd -0x30(%rbp), %xmm0
addsd -0x58(%rbp), %xmm0
movsd 0xcad9(%rip), %xmm1     # 0x22008
subsd -0x38(%rbp), %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, -0x58(%rbp)
movq %rbx, %rdi
movq -0x60(%rbp), %r14
movq %r14, %rsi
callq 0x15cb4
movq %rax, %rdi
movq %r13, %rsi
callq 0x539c
movsd -0x40(%rbp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x15cb4
movq %rax, %rdi
movq %r12, %rsi
callq 0x539c
movsd -0x30(%rbp), %xmm0
mulsd (%rax), %xmm0
addsd -0x40(%rbp), %xmm0
mulsd -0x38(%rbp), %xmm0
addsd -0x58(%rbp), %xmm0
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x208(%rbp), %rdi
callq 0x4250
leaq -0x1f8(%rbp), %rdi
leaq 0xf78b(%rip), %rsi      # 0x24d4a
callq 0x4360
movq %rax, %r14
movq %rbx, %rdi
xorl %esi, %esi
callq 0x539c
movsd (%rax), %xmm0
movq %r14, %rdi
callq 0x45f0
leaq 0xf3f1(%rip), %rsi      # 0x249d5
movq %rax, %rdi
callq 0x4360
movsd -0x50(%rbp), %xmm0
movq %rax, %rdi
callq 0x45f0
leaq 0xf3d5(%rip), %rsi      # 0x249d5
movq %rax, %rdi
callq 0x4360
movq %rax, %r14
movq %rbx, %rdi
callq 0x12b54
leaq -0x1(%rax), %rsi
movq %rbx, %rdi
callq 0x539c
movsd (%rax), %xmm0
movq %r14, %rdi
callq 0x45f0
leaq 0xed47(%rip), %rsi      # 0x24379
movq %rax, %rdi
callq 0x4360
movl $0x10, %edi
callq 0x41b0
movq %rax, %r14
leaq -0x80(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x4350
movb $0x1, %r15b
leaq -0x80(%rbp), %rsi
movq %r14, %rdi
callq 0x4510
xorl %r15d, %r15d
movq 0x25980(%rip), %rsi     # 0x3aff0
movq 0x25929(%rip), %rdx     # 0x3afa0
movq %r14, %rdi
callq 0x4560
jmp 0x1575e
leaq -0x208(%rbp), %rdi
callq 0x4250
leaq -0x1f8(%rbp), %rdi
leaq 0xf6e8(%rip), %rsi      # 0x24d86
callq 0x4360
movq %rax, %rbx
movq %r14, %rdi
xorl %esi, %esi
callq 0x539c
movsd (%rax), %xmm0
movq %rbx, %rdi
callq 0x45f0
leaq 0xf312(%rip), %rsi      # 0x249d5
movq %rax, %rdi
callq 0x4360
movsd -0x48(%rbp), %xmm0
movq %rax, %rdi
callq 0x45f0
leaq 0xf2f6(%rip), %rsi      # 0x249d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rbx
movq %r14, %rdi
callq 0x12b54
leaq -0x1(%rax), %rsi
movq %r14, %rdi
callq 0x539c
movsd (%rax), %xmm0
movq %rbx, %rdi
callq 0x45f0
leaq 0xec68(%rip), %rsi      # 0x24379
movq %rax, %rdi
callq 0x4360
movl $0x10, %edi
callq 0x41b0
movq %rax, %r14
leaq -0x80(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x4350
movb $0x1, %r15b
leaq -0x80(%rbp), %rsi
movq %r14, %rdi
callq 0x4510
xorl %r15d, %r15d
movq 0x258a1(%rip), %rsi     # 0x3aff0
movq 0x2584a(%rip), %rdx     # 0x3afa0
movq %r14, %rdi
callq 0x4560
jmp 0x15762
jmp 0x15770
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x41a0
jmp 0x15776
movq %rax, %rbx
movb $0x1, %r15b
testb %r15b, %r15b
je 0x1578a
movq %r14, %rdi
callq 0x4270
jmp 0x1578a
jmp 0x15787
movq %rax, %rbx
leaq -0x208(%rbp), %rdi
callq 0x4280
movq %rbx, %rdi
callq 0x45a0