// File: /workspace/github_cpp_makefile_star2_O2/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, -0x58(%rbp)
movsd %xmm1, -0x38(%rbp)
movsd %xmm1, -0x50(%rbp)
xorl %esi, %esi
callq 0x537c
movsd (%rax), %xmm0
movsd -0x30(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jae 0x1507c
movq %rbx, %rdi
callq 0x126f4
leaq -0x1(%rax), %rsi
movq %rbx, %rdi
callq 0x537c
movsd -0x30(%rbp), %xmm0
ucomisd (%rax), %xmm0
jae 0x1507c
leaq 0x18(%rbx), %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x537c
movsd (%rax), %xmm0
ucomisd -0x38(%rbp), %xmm0
jae 0x15159
movq %r14, %rdi
callq 0x126f4
leaq -0x1(%rax), %rsi
movq %r14, %rdi
callq 0x537c
movsd -0x38(%rbp), %xmm0
ucomisd (%rax), %xmm0
jae 0x15159
movq %rbx, %rdi
callq 0x12a3a
movq %rax, %r15
movq %rbx, %rdi
callq 0x12d8e
leaq -0x58(%rbp), %rdx
movq %r15, %rdi
movq %rax, %rsi
callq 0x15723
leaq -0x208(%rbp), %r12
movq %rax, (%r12)
movq %rbx, %rdi
callq 0x12a3a
leaq -0x80(%rbp), %r13
movq %rax, (%r13)
movq %r12, %rdi
movq %r13, %rsi
callq 0x12d57
movq %rax, -0x30(%rbp)
movq %r14, %rdi
callq 0x12a3a
movq %rax, %r15
movq %r14, %rdi
callq 0x12d8e
leaq -0x50(%rbp), %rdx
movq %r15, %rdi
movq %rax, %rsi
callq 0x15723
movq %rax, (%r12)
movq %r14, %rdi
callq 0x12a3a
movq %rax, (%r13)
leaq -0x208(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x12d57
movq %rax, %r12
movslq -0x30(%rbp), %r15
movq %r15, -0x60(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x537c
movsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
leal -0x1(%r15), %eax
movslq %eax, %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x537c
movsd -0x30(%rbp), %xmm1
subsd (%rax), %xmm1
movsd 0xc10a(%rip), %xmm0     # 0x21008
divsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movslq %r12d, %r12
movq %r14, %rdi
movq %r12, %rsi
callq 0x537c
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
leal -0x1(%r12), %eax
movslq %eax, %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x537c
movsd -0x38(%rbp), %xmm1
subsd (%rax), %xmm1
movsd 0xc0c6(%rip), %xmm0     # 0x21008
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
leaq -0x58(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x537c
movsd -0x38(%rbp), %xmm0
subsd (%rax), %xmm0
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
leaq -0x50(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
movq %r14, %rdi
movq %r13, %rsi
callq 0x537c
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 0x15754
movq %rax, %rdi
movq %r13, %rsi
callq 0x537c
movsd 0xc045(%rip), %xmm0     # 0x21008
subsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x40(%rbp)
movsd (%rax), %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, -0x48(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x15754
movq %rax, %rdi
movq %r12, %rsi
callq 0x537c
movsd (%rax), %xmm0
mulsd -0x30(%rbp), %xmm0
addsd -0x48(%rbp), %xmm0
movsd 0xc002(%rip), %xmm1     # 0x21008
subsd -0x38(%rbp), %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, -0x48(%rbp)
movq %rbx, %rdi
movq -0x60(%rbp), %r14
movq %r14, %rsi
callq 0x15754
movq %rax, %rdi
movq %r13, %rsi
callq 0x537c
movsd -0x40(%rbp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x15754
movq %rax, %rdi
movq %r12, %rsi
callq 0x537c
movsd -0x30(%rbp), %xmm0
mulsd (%rax), %xmm0
addsd -0x40(%rbp), %xmm0
mulsd -0x38(%rbp), %xmm0
addsd -0x48(%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 0xecb4(%rip), %rsi      # 0x23d4a
callq 0x4360
movq %rax, %r14
movq %rbx, %rdi
xorl %esi, %esi
callq 0x537c
movsd (%rax), %xmm0
movq %r14, %rdi
callq 0x45f0
leaq 0xe91a(%rip), %rsi      # 0x239d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rdi
movsd -0x30(%rbp), %xmm0
callq 0x45f0
leaq 0xe8fe(%rip), %rsi      # 0x239d5
movq %rax, %rdi
callq 0x4360
movq %rax, %r14
movq %rbx, %rdi
callq 0x126f4
leaq -0x1(%rax), %rsi
movq %rbx, %rdi
callq 0x537c
movsd (%rax), %xmm0
movq %r14, %rdi
callq 0x45f0
leaq 0xe270(%rip), %rsi      # 0x23379
movq %rax, %rdi
callq 0x4360
pushq $0x10
popq %rdi
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 0x24eab(%rip), %rsi     # 0x39ff0
movq 0x24e54(%rip), %rdx     # 0x39fa0
movq %r14, %rdi
callq 0x4560
jmp 0x15231
leaq -0x208(%rbp), %rdi
callq 0x4250
leaq -0x1f8(%rbp), %rdi
leaq 0xec13(%rip), %rsi      # 0x23d86
callq 0x4360
movq %rax, %rbx
movq %r14, %rdi
xorl %esi, %esi
callq 0x537c
movsd (%rax), %xmm0
movq %rbx, %rdi
callq 0x45f0
leaq 0xe83d(%rip), %rsi      # 0x239d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rdi
movsd -0x38(%rbp), %xmm0
callq 0x45f0
leaq 0xe821(%rip), %rsi      # 0x239d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rbx
movq %r14, %rdi
callq 0x126f4
leaq -0x1(%rax), %rsi
movq %r14, %rdi
callq 0x537c
movsd (%rax), %xmm0
movq %rbx, %rdi
callq 0x45f0
leaq 0xe193(%rip), %rsi      # 0x23379
movq %rax, %rdi
callq 0x4360
pushq $0x10
popq %rdi
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 0x24dce(%rip), %rsi     # 0x39ff0
movq 0x24d77(%rip), %rdx     # 0x39fa0
movq %r14, %rdi
callq 0x4560
jmp 0x15235
jmp 0x15248
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x41a0
testb %r15b, %r15b
jne 0x1524b
jmp 0x1525a
movq %rax, %rbx
movq %r14, %rdi
callq 0x4270
jmp 0x1525a
jmp 0x15257
movq %rax, %rbx
leaq -0x208(%rbp), %rdi
callq 0x4280
movq %rbx, %rdi
callq 0x45a0