// File: /workspace/github_cpp_makefile_star2_O3/TBody[P]atomicpp/atomicpp/Spline/BicubicSpline.cpp
// Function: atomicpp::BicubicSpline::call0D(double, double)
double BicubicSpline::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])*x_norm;
	double y = (eval_y - y_values[low_y])*y_norm;

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

	grid_matrix alpha_sub = alpha_coeff[low_x][low_y];

	double x_vector[4] = {1, x, x*x, x*x*x}; //Row vector
	double y_vector[4] = {1, y, y*y, y*y*y}; //Column vector

	double return_value = 0.0;
	for(int i=0; i<4; ++i){
		for(int j=0; j<4; ++j){
			return_value += x_vector[i] * alpha_sub[i][j] * y_vector[j];
		}
	}
	// return_value = x_vector[0] * alpha_sub[0][0] * y_vector[0];

	return return_value;
}

// 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, -0x70(%rbp)
movsd %xmm1, -0x38(%rbp)
movsd %xmm1, -0x68(%rbp)
xorl %esi, %esi
callq 0x539c
movsd (%rax), %xmm0
movsd -0x30(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jae 0x175af
movq %rbx, %rdi
callq 0x12b22
leaq -0x1(%rax), %rsi
movq %rbx, %rdi
callq 0x539c
movsd -0x30(%rbp), %xmm0
ucomisd (%rax), %xmm0
jae 0x175af
leaq 0x18(%rbx), %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x539c
movsd (%rax), %xmm0
ucomisd -0x38(%rbp), %xmm0
jae 0x17688
movq %r14, %rdi
callq 0x12b22
leaq -0x1(%rax), %rsi
movq %r14, %rdi
callq 0x539c
movsd -0x38(%rbp), %xmm0
ucomisd (%rax), %xmm0
jae 0x17688
movq %rbx, %rdi
callq 0x12e68
movq %rax, %r15
movq %rbx, %rdi
callq 0x131be
leaq -0x70(%rbp), %rdx
movq %r15, %rdi
movq %rax, %rsi
callq 0x15c6b
leaq -0x210(%rbp), %r12
movq %rax, (%r12)
movq %rbx, %rdi
callq 0x12e68
leaq -0x60(%rbp), %r13
movq %rax, (%r13)
movq %r12, %rdi
movq %r13, %rsi
callq 0x13187
movq %rax, -0x30(%rbp)
movq %r14, %rdi
callq 0x12e68
movq %rax, %r15
movq %r14, %rdi
callq 0x131be
leaq -0x68(%rbp), %rdx
movq %r15, %rdi
movq %rax, %rsi
callq 0x15c6b
movq %rax, (%r12)
movq %r14, %rdi
callq 0x12e68
movq %rax, (%r13)
leaq -0x60(%rbp), %rsi
movq %r12, %rdi
callq 0x13187
movq %rax, %r15
movslq -0x30(%rbp), %r13
movq %rbx, %rdi
movq %r13, %rsi
callq 0x539c
movsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
decl %r13d
movslq %r13d, %r13
movq %rbx, %rdi
movq %r13, %rsi
callq 0x539c
movsd -0x30(%rbp), %xmm1
subsd (%rax), %xmm1
movsd 0xac19(%rip), %xmm0     # 0x22008
movsd %xmm0, -0x30(%rbp)
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movslq %r15d, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x539c
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
decl %r15d
movslq %r15d, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x539c
movsd -0x38(%rbp), %xmm1
subsd (%rax), %xmm1
movsd -0x30(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
leaq -0x70(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x539c
movsd -0x38(%rbp), %xmm0
subsd (%rax), %xmm0
mulsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
leaq -0x68(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x539c
movsd -0x40(%rbp), %xmm0
subsd (%rax), %xmm0
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x40(%rbp)
addq $0x48, %rbx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x18356
movq %rax, %rdi
movq %r15, %rsi
callq 0x1145a
leaq -0x88(%rbp), %rbx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x14dc0
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, (%r12)
movsd -0x38(%rbp), %xmm1
movsd %xmm1, 0x8(%r12)
movapd %xmm1, %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x10(%r12)
mulsd %xmm1, %xmm0
movsd %xmm0, 0x18(%r12)
leaq -0x60(%rbp), %rcx
movq %rax, (%rcx)
movsd -0x40(%rbp), %xmm1
movsd %xmm1, 0x8(%rcx)
movapd %xmm1, %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rcx)
mulsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rcx)
xorpd %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
xorl %r14d, %r14d
movsd -0x210(%rbp,%r14,8), %xmm0
movsd %xmm0, -0x38(%rbp)
xorl %r15d, %r15d
movsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x15c9c
movq %rax, %rdi
movq %r15, %rsi
callq 0x539c
movsd (%rax), %xmm0
mulsd -0x38(%rbp), %xmm0
mulsd -0x60(%rbp,%r15,8), %xmm0
movsd -0x30(%rbp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, -0x30(%rbp)
movsd -0x30(%rbp), %xmm0
incq %r15
cmpq $0x4, %r15
jne 0x1753c
incq %r14
cmpq $0x4, %r14
jne 0x17525
leaq -0x88(%rbp), %rdi
callq 0x10424
movsd -0x30(%rbp), %xmm0
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x210(%rbp), %rdi
callq 0x4250
leaq -0x200(%rbp), %rdi
leaq 0xd781(%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 0xd3e7(%rip), %rsi      # 0x249d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rdi
movsd -0x30(%rbp), %xmm0
callq 0x45f0
leaq 0xd3cb(%rip), %rsi      # 0x249d5
movq %rax, %rdi
callq 0x4360
movq %rax, %r14
movq %rbx, %rdi
callq 0x12b22
leaq -0x1(%rax), %rsi
movq %rbx, %rdi
callq 0x539c
movsd (%rax), %xmm0
movq %r14, %rdi
callq 0x45f0
leaq 0xcd3d(%rip), %rsi      # 0x24379
movq %rax, %rdi
callq 0x4360
movl $0x10, %edi
callq 0x41b0
movq %rax, %r14
leaq -0x60(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0x4350
leaq -0x60(%rbp), %rsi
movq %r14, %rdi
callq 0x4510
movq 0x2397c(%rip), %rsi     # 0x3aff0
movq 0x23925(%rip), %rdx     # 0x3afa0
movq %r14, %rdi
callq 0x4560
jmp 0x1775c
leaq -0x210(%rbp), %rdi
callq 0x4250
leaq -0x200(%rbp), %rdi
leaq 0xd6e4(%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 0xd30e(%rip), %rsi      # 0x249d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rdi
movsd -0x38(%rbp), %xmm0
callq 0x45f0
leaq 0xd2f2(%rip), %rsi      # 0x249d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rbx
movq %r14, %rdi
callq 0x12b22
leaq -0x1(%rax), %rsi
movq %r14, %rdi
callq 0x539c
movsd (%rax), %xmm0
movq %rbx, %rdi
callq 0x45f0
leaq 0xcc64(%rip), %rsi      # 0x24379
movq %rax, %rdi
callq 0x4360
movl $0x10, %edi
callq 0x41b0
movq %rax, %r14
leaq -0x60(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0x4350
leaq -0x60(%rbp), %rsi
movq %r14, %rdi
callq 0x4510
movq 0x238a3(%rip), %rsi     # 0x3aff0
movq 0x2384c(%rip), %rdx     # 0x3afa0
movq %r14, %rdi
callq 0x4560
jmp 0x17760
jmp 0x1776e
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x41a0
jmp 0x17790
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x41a0
jmp 0x17781
jmp 0x1777e
movq %rax, %rbx
movq %r14, %rdi
callq 0x4270
jmp 0x17790
jmp 0x1778d
movq %rax, %rbx
leaq -0x210(%rbp), %rdi
callq 0x4280
movq %rbx, %rdi
callq 0x45a0