// File: 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
subq $0x4f0, %rsp            # imm = 0x4F0
movq %rdi, -0x8(%rbp)
movsd %xmm0, -0x10(%rbp)
movsd %xmm1, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x408(%rbp)
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x400(%rbp)
xorl %eax, %eax
movl %eax, %esi
callq 0x5950
movsd -0x400(%rbp), %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jae 0x2183a
movq -0x408(%rbp), %rdi
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x410(%rbp)
callq 0x1d4d0
movq -0x408(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0x5950
movsd -0x410(%rbp), %xmm0
ucomisd (%rax), %xmm0
jb 0x21a01
leaq -0x1a0(%rbp), %rdi
callq 0x4290
leaq -0x190(%rbp), %rdi
leaq 0x17676(%rip), %rsi     # 0x38eca
callq 0x43a0
movq %rax, -0x418(%rbp)
jmp 0x21862
movq -0x408(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x5950
movq -0x418(%rbp), %rdi
movsd (%rax), %xmm0
callq 0x4640
movq %rax, -0x420(%rbp)
jmp 0x2188b
movq -0x420(%rbp), %rdi
leaq 0x172bc(%rip), %rsi     # 0x38b55
callq 0x43a0
movq %rax, -0x428(%rbp)
jmp 0x218a7
movq -0x428(%rbp), %rdi
movsd -0x10(%rbp), %xmm0
callq 0x4640
movq %rax, -0x430(%rbp)
jmp 0x218c1
movq -0x430(%rbp), %rdi
leaq 0x17286(%rip), %rsi     # 0x38b55
callq 0x43a0
movq %rax, -0x438(%rbp)
jmp 0x218dd
movq -0x408(%rbp), %rdi
callq 0x1d4d0
movq -0x408(%rbp), %rdi
movq %rax, %rsi
decq %rsi
callq 0x5950
movq -0x438(%rbp), %rdi
movsd (%rax), %xmm0
callq 0x4640
movq %rax, -0x440(%rbp)
jmp 0x21914
movq -0x440(%rbp), %rdi
leaq 0x16bd7(%rip), %rsi     # 0x384f9
callq 0x43a0
jmp 0x21929
movb $0x1, -0x1d1(%rbp)
movl $0x10, %edi
callq 0x41b0
movq %rax, -0x448(%rbp)
leaq -0x1d0(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x4390
jmp 0x21956
movq -0x448(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x4570
jmp 0x2196b
movq -0x448(%rbp), %rdi
movb $0x0, -0x1d1(%rbp)
movq 0x2d670(%rip), %rsi     # 0x4eff0
movq 0x2d619(%rip), %rdx     # 0x4efa0
callq 0x45b0
jmp 0x22049
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
jmp 0x219f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
jmp 0x219d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x4220
testb $0x1, -0x1d1(%rbp)
jne 0x219e2
jmp 0x219ee
movq -0x448(%rbp), %rdi
callq 0x42b0
jmp 0x219f0
leaq -0x1a0(%rbp), %rdi
callq 0x42c0
jmp 0x2203d
movq -0x408(%rbp), %rdi
movsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x450(%rbp)
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x5950
movsd -0x450(%rbp), %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jae 0x21a84
movq -0x408(%rbp), %rdi
movsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x458(%rbp)
movq %rdi, %rax
addq $0x18, %rax
movq %rax, -0x460(%rbp)
addq $0x18, %rdi
callq 0x1d4d0
movq -0x460(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0x5950
movsd -0x458(%rbp), %xmm0
ucomisd (%rax), %xmm0
jb 0x21c5a
leaq -0x360(%rbp), %rdi
callq 0x4290
leaq -0x350(%rbp), %rdi
leaq 0x17468(%rip), %rsi     # 0x38f06
callq 0x43a0
movq %rax, -0x468(%rbp)
jmp 0x21aac
movq -0x408(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x5950
movq -0x468(%rbp), %rdi
movsd (%rax), %xmm0
callq 0x4640
movq %rax, -0x470(%rbp)
jmp 0x21ad9
movq -0x470(%rbp), %rdi
leaq 0x1706e(%rip), %rsi     # 0x38b55
callq 0x43a0
movq %rax, -0x478(%rbp)
jmp 0x21af5
movq -0x478(%rbp), %rdi
movsd -0x18(%rbp), %xmm0
callq 0x4640
movq %rax, -0x480(%rbp)
jmp 0x21b0f
movq -0x480(%rbp), %rdi
leaq 0x17038(%rip), %rsi     # 0x38b55
callq 0x43a0
movq %rax, -0x488(%rbp)
jmp 0x21b2b
movq -0x408(%rbp), %rdi
addq $0x18, %rdi
movq %rdi, -0x498(%rbp)
callq 0x1d4d0
movq -0x498(%rbp), %rdi
movq %rax, %rsi
decq %rsi
callq 0x5950
movq -0x488(%rbp), %rdi
movsd (%rax), %xmm0
callq 0x4640
movq %rax, -0x490(%rbp)
jmp 0x21b6d
movq -0x490(%rbp), %rdi
leaq 0x1697e(%rip), %rsi     # 0x384f9
callq 0x43a0
jmp 0x21b82
movb $0x1, -0x381(%rbp)
movl $0x10, %edi
callq 0x41b0
movq %rax, -0x4a0(%rbp)
leaq -0x380(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0x4390
jmp 0x21baf
movq -0x4a0(%rbp), %rdi
leaq -0x380(%rbp), %rsi
callq 0x4570
jmp 0x21bc4
movq -0x4a0(%rbp), %rdi
movb $0x0, -0x381(%rbp)
movq 0x2d417(%rip), %rsi     # 0x4eff0
movq 0x2d3c0(%rip), %rdx     # 0x4efa0
callq 0x45b0
jmp 0x22049
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
jmp 0x21c49
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
jmp 0x21c30
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
leaq -0x380(%rbp), %rdi
callq 0x4220
testb $0x1, -0x381(%rbp)
jne 0x21c3b
jmp 0x21c47
movq -0x4a0(%rbp), %rdi
callq 0x42b0
jmp 0x21c49
leaq -0x360(%rbp), %rdi
callq 0x42c0
jmp 0x2203d
movq -0x408(%rbp), %rdi
callq 0x1da50
movq -0x408(%rbp), %rdi
movq %rax, -0x398(%rbp)
callq 0x1dfe0
movq %rax, -0x3a0(%rbp)
movq -0x398(%rbp), %rdi
movq -0x3a0(%rbp), %rsi
leaq -0x10(%rbp), %rdx
callq 0x22820
movq -0x408(%rbp), %rdi
movq %rax, -0x390(%rbp)
callq 0x1da50
movq %rax, -0x3a8(%rbp)
leaq -0x390(%rbp), %rdi
leaq -0x3a8(%rbp), %rsi
callq 0x1df70
movq -0x408(%rbp), %rdi
subq $0x1, %rax
movl %eax, -0x388(%rbp)
addq $0x18, %rdi
callq 0x1da50
movq -0x408(%rbp), %rdi
movq %rax, -0x3c0(%rbp)
addq $0x18, %rdi
callq 0x1dfe0
movq %rax, -0x3c8(%rbp)
movq -0x3c0(%rbp), %rdi
movq -0x3c8(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x22820
movq -0x408(%rbp), %rdi
movq %rax, -0x3b8(%rbp)
addq $0x18, %rdi
callq 0x1da50
movq %rax, -0x3d0(%rbp)
leaq -0x3b8(%rbp), %rdi
leaq -0x3d0(%rbp), %rsi
callq 0x1df70
movq -0x408(%rbp), %rdi
subq $0x1, %rax
movl %eax, -0x3ac(%rbp)
movl -0x388(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x5950
movq -0x408(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x4f0(%rbp)
movl -0x388(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x5950
movsd -0x4f0(%rbp), %xmm1
movq -0x408(%rbp), %rdi
subsd (%rax), %xmm1
movsd 0x14263(%rip), %xmm0    # 0x36008
divsd %xmm1, %xmm0
movsd %xmm0, -0x3d8(%rbp)
addq $0x18, %rdi
movl -0x3ac(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x5950
movq -0x408(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x4e8(%rbp)
addq $0x18, %rdi
movl -0x3ac(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x5950
movsd -0x4e8(%rbp), %xmm1
movq -0x408(%rbp), %rdi
subsd (%rax), %xmm1
movsd 0x141ff(%rip), %xmm0    # 0x36008
divsd %xmm1, %xmm0
movsd %xmm0, -0x3e0(%rbp)
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x4e0(%rbp)
movl -0x388(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x5950
movsd -0x4e0(%rbp), %xmm0
movq -0x408(%rbp), %rdi
subsd (%rax), %xmm0
mulsd -0x3d8(%rbp), %xmm0
movsd %xmm0, -0x3e8(%rbp)
movsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x4d8(%rbp)
addq $0x18, %rdi
movl -0x3ac(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x5950
movsd -0x4d8(%rbp), %xmm0
movq -0x408(%rbp), %rdi
subsd (%rax), %xmm0
mulsd -0x3e0(%rbp), %xmm0
movsd %xmm0, -0x3f0(%rbp)
addq $0x30, %rdi
movl -0x388(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x22870
movq %rax, %rdi
movl -0x3ac(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x5950
movq -0x408(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x4d0(%rbp)
movsd 0x14129(%rip), %xmm0    # 0x36008
subsd -0x3f0(%rbp), %xmm0
movsd %xmm0, -0x4c8(%rbp)
addq $0x30, %rdi
movl -0x388(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x22870
movq %rax, %rdi
movl -0x3ac(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x5950
movsd -0x4d0(%rbp), %xmm0
movsd -0x4c8(%rbp), %xmm2
movq -0x408(%rbp), %rdi
movsd (%rax), %xmm1
mulsd -0x3f0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x4b0(%rbp)
movsd 0x140b5(%rip), %xmm0    # 0x36008
subsd -0x3e8(%rbp), %xmm0
movsd %xmm0, -0x4a8(%rbp)
addq $0x30, %rdi
movl -0x388(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x22870
movq %rax, %rdi
movl -0x3ac(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x5950
movq -0x408(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x4c0(%rbp)
movsd 0x14061(%rip), %xmm0    # 0x36008
subsd -0x3f0(%rbp), %xmm0
movsd %xmm0, -0x4b8(%rbp)
addq $0x30, %rdi
movl -0x388(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x22870
movq %rax, %rdi
movl -0x3ac(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0x5950
movsd -0x4c0(%rbp), %xmm1
movsd -0x4b8(%rbp), %xmm4
movsd -0x4b0(%rbp), %xmm0
movsd -0x4a8(%rbp), %xmm2
movsd (%rax), %xmm3
mulsd -0x3f0(%rbp), %xmm3
mulsd %xmm4, %xmm1
addsd %xmm3, %xmm1
mulsd -0x3e8(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x3f8(%rbp)
movsd -0x3f8(%rbp), %xmm0
addq $0x4f0, %rsp            # imm = 0x4F0
popq %rbp
retq
movq -0x1a8(%rbp), %rdi
callq 0x45e0
nopl (%rax)