// File: /workspace/github_cpp_makefile_star2_O2/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, -0x50(%rbp)
movsd %xmm1, -0x38(%rbp)
movsd %xmm1, -0x48(%rbp)
xorl %esi, %esi
callq 0x537c
movsd (%rax), %xmm0
movsd -0x30(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jae 0x17032
movq %rbx, %rdi
callq 0x126f4
leaq -0x1(%rax), %rsi
movq %rbx, %rdi
callq 0x537c
movsd -0x30(%rbp), %xmm0
ucomisd (%rax), %xmm0
jae 0x17032
leaq 0x18(%rbx), %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x537c
movsd (%rax), %xmm0
ucomisd -0x38(%rbp), %xmm0
jae 0x1710f
movq %r14, %rdi
callq 0x126f4
leaq -0x1(%rax), %rsi
movq %r14, %rdi
callq 0x537c
movsd -0x38(%rbp), %xmm0
ucomisd (%rax), %xmm0
jae 0x1710f
movq %rbx, %rdi
callq 0x12a3a
movq %rax, %r15
movq %rbx, %rdi
callq 0x12d8e
leaq -0x50(%rbp), %rdx
movq %r15, %rdi
movq %rax, %rsi
callq 0x15723
leaq -0x210(%rbp), %r12
movq %rax, (%r12)
movq %rbx, %rdi
callq 0x12a3a
leaq -0x70(%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 -0x48(%rbp), %rdx
movq %r15, %rdi
movq %rax, %rsi
callq 0x15723
movq %rax, (%r12)
movq %r14, %rdi
callq 0x12a3a
movq %rax, (%r13)
leaq -0x70(%rbp), %rsi
movq %r12, %rdi
callq 0x12d57
movq %rax, %r15
movslq -0x30(%rbp), %r13
movq %rbx, %rdi
movq %r13, %rsi
callq 0x537c
movsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
decl %r13d
movslq %r13d, %r13
movq %rbx, %rdi
movq %r13, %rsi
callq 0x537c
movsd -0x30(%rbp), %xmm1
subsd (%rax), %xmm1
movsd 0xa18b(%rip), %xmm0     # 0x21008
movsd %xmm0, -0x30(%rbp)
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movslq %r15d, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x537c
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
decl %r15d
movslq %r15d, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x537c
movsd -0x38(%rbp), %xmm1
subsd (%rax), %xmm1
movsd -0x30(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
leaq -0x50(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x537c
movsd -0x38(%rbp), %xmm0
subsd (%rax), %xmm0
mulsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
leaq -0x48(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x537c
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 0x17d6c
movq %rax, %rdi
movq %r15, %rsi
callq 0x110d4
leaq -0x88(%rbp), %rbx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x148c4
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 -0x70(%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
cmpq $0x4, %r14
je 0x1700f
movsd -0x210(%rbp,%r14,8), %xmm0
movsd %xmm0, -0x38(%rbp)
xorl %r15d, %r15d
cmpq $0x4, %r15
je 0x1700a
movq %rbx, %rdi
movq %r14, %rsi
callq 0x15754
movq %rax, %rdi
movq %r15, %rsi
callq 0x537c
movsd (%rax), %xmm0
mulsd -0x38(%rbp), %xmm0
mulsd -0x70(%rbp,%r15,8), %xmm0
movsd -0x30(%rbp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, -0x30(%rbp)
incq %r15
jmp 0x16fcb
incq %r14
jmp 0x16fb3
leaq -0x88(%rbp), %rdi
callq 0x100f2
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 0xccfe(%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 0xc964(%rip), %rsi      # 0x239d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rdi
movsd -0x30(%rbp), %xmm0
callq 0x45f0
leaq 0xc948(%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 0xc2ba(%rip), %rsi      # 0x23379
movq %rax, %rdi
callq 0x4360
pushq $0x10
popq %rdi
callq 0x41b0
movq %rax, %r14
leaq -0x70(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0x4350
movb $0x1, %r15b
leaq -0x70(%rbp), %rsi
movq %r14, %rdi
callq 0x4510
xorl %r15d, %r15d
movq 0x22ef5(%rip), %rsi     # 0x39ff0
movq 0x22e9e(%rip), %rdx     # 0x39fa0
movq %r14, %rdi
callq 0x4560
jmp 0x171e7
leaq -0x210(%rbp), %rdi
callq 0x4250
leaq -0x200(%rbp), %rdi
leaq 0xcc5d(%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 0xc887(%rip), %rsi      # 0x239d5
movq %rax, %rdi
callq 0x4360
movq %rax, %rdi
movsd -0x38(%rbp), %xmm0
callq 0x45f0
leaq 0xc86b(%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 0xc1dd(%rip), %rsi      # 0x23379
movq %rax, %rdi
callq 0x4360
pushq $0x10
popq %rdi
callq 0x41b0
movq %rax, %r14
leaq -0x70(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0x4350
movb $0x1, %r15b
leaq -0x70(%rbp), %rsi
movq %r14, %rdi
callq 0x4510
xorl %r15d, %r15d
movq 0x22e18(%rip), %rsi     # 0x39ff0
movq 0x22dc1(%rip), %rdx     # 0x39fa0
movq %r14, %rdi
callq 0x4560
jmp 0x171eb
jmp 0x171fe
movq %rax, %rbx
leaq -0x70(%rbp), %rdi
callq 0x41a0
testb %r15b, %r15b
jne 0x17201
jmp 0x17210
movq %rax, %rbx
movq %r14, %rdi
callq 0x4270
jmp 0x17210
jmp 0x1720d
movq %rax, %rbx
leaq -0x210(%rbp), %rdi
callq 0x4280
movq %rbx, %rdi
callq 0x45a0