// File: /workspace/github_cpp_makefile_star2_O1/PeterDenton[P]Nu-Pert/src/Linear_Fit.cpp
// Function: void Linear_Fit<double>(double (*)(double, double const*), double (*)(double, double const*), double, double, int, double*, double*, double*, double*)
void Linear_Fit(T (*x)(T t, const T *p), T (*y)(T t, const T *p), T t_min, T t_max, int n, T *p, T *m, T *b, T *rsq)
{
	T sum_x = 0;
	T sum_xsq = 0;
	T sum_y = 0;
	T sum_ysq = 0;
	T sum_xy = 0;

	T x_tmp, y_tmp;
	for (T t = t_min; t <= t_max; t += (t_max - t_min) / (n - 1))
	{
		x_tmp = x(t, p);
		y_tmp = y(t, p);
		sum_x += x_tmp;
		sum_xsq += pow(x_tmp, 2);
		sum_y += y_tmp;
		sum_ysq += pow(y_tmp, 2);
		sum_xy += x_tmp * y_tmp;
	}

	T x_bar = sum_x / n;
	T y_bar = sum_y / n;

	T ss_xx = sum_xsq - n * pow(x_bar, 2);
	T ss_yy = sum_ysq - n * pow(y_bar, 2);
	T ss_xy = sum_xy - n * x_bar * y_bar;

	*m = ss_xy / ss_xx;
	*b = y_bar - *m * x_bar;
	*rsq = pow(ss_xy, 2) / (ss_xx * ss_yy);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %r9, %rbx
movq %r8, %r14
movl %edx, %r15d
movq 0xa0(%rsp), %rax
movsd %xmm1, 0x8(%rsp)
ucomisd %xmm0, %xmm1
jae 0xa2bc
xorpd %xmm7, %xmm7
xorpd %xmm0, %xmm0
xorpd %xmm6, %xmm6
xorpd %xmm5, %xmm5
jmp 0xa39c
movq %rcx, %r12
movapd %xmm0, %xmm2
movq %rsi, %r13
movq %rdi, %rbp
movsd 0x8(%rsp), %xmm1
subsd %xmm0, %xmm1
leal -0x1(%r15), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movsd %xmm1, 0x18(%rsp)
xorpd %xmm5, %xmm5
xorpd %xmm7, %xmm7
xorpd %xmm6, %xmm6
movsd %xmm2, 0x10(%rsp)
movapd %xmm7, 0x30(%rsp)
movapd %xmm6, 0x40(%rsp)
movapd %xmm5, 0x50(%rsp)
movapd %xmm2, %xmm0
movq %r12, %rdi
callq *%rbp
movapd %xmm0, 0x20(%rsp)
movsd 0x10(%rsp), %xmm0
movq %r12, %rdi
callq *%r13
movapd 0x30(%rsp), %xmm7
movapd 0x40(%rsp), %xmm6
movapd 0x50(%rsp), %xmm5
movapd 0x20(%rsp), %xmm4
movapd %xmm4, %xmm1
mulsd %xmm4, %xmm1
movapd %xmm0, %xmm2
movapd %xmm4, %xmm3
mulsd %xmm0, %xmm4
mulsd %xmm0, %xmm0
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
addpd %xmm2, %xmm6
movsd 0x10(%rsp), %xmm2
unpcklpd %xmm1, %xmm3            # xmm3 = xmm3[0],xmm1[0]
addpd %xmm3, %xmm5
addsd %xmm4, %xmm7
addsd 0x18(%rsp), %xmm2
movsd 0x8(%rsp), %xmm0
ucomisd %xmm2, %xmm0
jae 0xa2f4
movapd %xmm6, %xmm0
unpckhpd %xmm6, %xmm0            # xmm0 = xmm0[1],xmm6[1]
shufpd $0x2, %xmm5, %xmm7      # xmm7 = xmm7[0],xmm5[1]
movq 0xa0(%rsp), %rax
xorps %xmm1, %xmm1
cvtsi2sd %r15d, %xmm1
divsd %xmm1, %xmm5
divsd %xmm1, %xmm6
movapd 0x3c6c(%rip), %xmm2     # 0xe020
movapd %xmm1, %xmm3
xorpd %xmm2, %xmm3
movapd %xmm6, %xmm4
mulsd %xmm6, %xmm4
mulsd %xmm1, %xmm4
subsd %xmm4, %xmm0
xorpd %xmm5, %xmm2
unpcklpd %xmm5, %xmm1            # xmm1 = xmm1[0],xmm5[0]
unpcklpd %xmm5, %xmm2            # xmm2 = xmm2[0],xmm5[0]
mulpd %xmm1, %xmm2
movapd %xmm6, %xmm1
unpcklpd %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0]
mulpd %xmm2, %xmm1
addpd %xmm7, %xmm1
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
movapd %xmm1, %xmm3
divsd %xmm2, %xmm3
movsd %xmm3, (%r14)
mulsd %xmm5, %xmm3
subsd %xmm3, %xmm6
movsd %xmm6, (%rbx)
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm2
divsd %xmm2, %xmm1
movsd %xmm1, (%rax)
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq