// File: /workspace/github_cpp_makefile_star2_O1/gersteinlab[P]MUSIC/src/ms_filter_utils.cpp
// Function: mean_filter_data(double*, int, int, int)
double* mean_filter_data(double* track_data,
						int l_track_data, 
						int l_averaging_win,
						int skip_value) // This is the value to be skipped from the window values.
{
	// Do copying from start to end.
    double* cur_filtered_track = new double[l_track_data + 2];

	int half_l_averaging = l_averaging_win / 2;
		
	// Initialize the current pdf.
	double cur_total_win_val = 0;
	bool val_inited = false;

	int prev_avg_start = -1;
	int prev_avg_end = -1;

	// Go over all the positions as the middle of the filtering window.
	for(int cur_win_mid = 1; cur_win_mid <= l_track_data; cur_win_mid++)
	{
		cur_filtered_track[cur_win_mid] = 0;

		int cur_avg_start = (cur_win_mid > half_l_averaging)?(cur_win_mid - half_l_averaging):(1);
		int cur_avg_end = (cur_win_mid + half_l_averaging <= l_track_data)?(cur_win_mid + half_l_averaging):(l_track_data);
		if(!val_inited)
		{
			for(int i = cur_avg_start; i <= cur_avg_end; i++)
			{
				cur_total_win_val += track_data[i];
			} // i loop.

			val_inited = true;
		}
		else
		{
			// Exclude the signal values that got out of the current window.
			for(int i = prev_avg_start; i < cur_avg_start; i++)
			{
				cur_total_win_val -= track_data[i];
			} // i loop.

			// Add the signal values that entered the current window.
			for(int i = prev_avg_end+1; i <= cur_avg_end; i++)
			{
				cur_total_win_val += track_data[i];
			} // i loop.
		}

		// Following does a sanity check for the computed values.
if(__DUMP_FILTER_MSGS__)
{
		double check_val = 0;
		for(int i = cur_avg_start; i <= cur_avg_end; i++)
		{
			check_val += track_data[i];
		} // i loop.

		if(fabs(check_val - cur_total_win_val) > 2)
		{
			fprintf(stderr, "Check failed: %d: %lf, %lf\n", cur_win_mid, check_val, cur_total_win_val);
			exit(0);
		}
}

		cur_filtered_track[cur_win_mid] = cur_total_win_val / (cur_avg_end - cur_avg_start + 1);

		prev_avg_start = cur_avg_start;
		prev_avg_end = cur_avg_end;
	} // main signal filtering loop.

	return(cur_filtered_track);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, %ebp
movl %esi, %ebx
movq %rdi, %r14
movslq %esi, %r15
leaq 0x10(,%r15,8), %rax
cmpl $-0x2, %r15d
movq $-0x1, %rdi
cmovgeq %rax, %rdi
callq 0x2040
testl %r15d, %r15d
jle 0x13216
movl %ebp, %edx
shrl $0x1f, %edx
addl %ebp, %edx
sarl %edx
movb 0x270ca(%rip), %cl      # 0x3a1cd
movslq %edx, %rsi
leal 0x1(%rbx), %edi
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
xorpd %xmm1, %xmm1
movl $0x1, %edx
xorl %r8d, %r8d
movl $0x1, %r9d
movapd 0x1a8b8(%rip), %xmm2    # 0x2d9e0
movsd 0x17f38(%rip), %xmm3    # 0x2b068
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movq $0x0, (%rax,%rdx,8)
movl %edx, %r10d
subl %esi, %r10d
cmpq %rsi, %rdx
cmovlel %r9d, %r10d
leal (%rsi,%rdx), %r11d
cmpl %ebx, %r11d
cmovgel %ebx, %r11d
testb $0x1, %r8b
je 0x13191
cmpl %r10d, %r15d
jge 0x13175
movslq %r15d, %r15
movslq %r10d, %r12
subsd (%r14,%r15,8), %xmm1
incq %r15
cmpq %r15, %r12
jne 0x13167
cmpl %r11d, %ebp
jge 0x131b1
movslq %ebp, %r15
movslq %r11d, %r12
addsd 0x8(%r14,%r15,8), %xmm1
incq %r15
cmpq %r12, %r15
jl 0x13180
jmp 0x131b1
movb $0x1, %r8b
cmpl %r10d, %r11d
jl 0x131b1
movslq %r10d, %r15
movslq %r11d, %r12
decq %r15
addsd 0x8(%r14,%r15,8), %xmm1
incq %r15
cmpq %r12, %r15
jl 0x131a2
testb %cl, %cl
je 0x131e8
xorpd %xmm0, %xmm0
cmpl %r10d, %r11d
jl 0x131d6
movslq %r10d, %r15
movslq %r11d, %r12
decq %r15
addsd 0x8(%r14,%r15,8), %xmm0
incq %r15
cmpq %r12, %r15
jl 0x131c7
movapd %xmm0, %xmm4
subsd %xmm1, %xmm4
andpd %xmm2, %xmm4
ucomisd %xmm3, %xmm4
ja 0x1321f
movl %r11d, %ebp
subl %r10d, %ebp
incl %ebp
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
movapd %xmm1, %xmm4
divsd %xmm0, %xmm4
movsd %xmm4, (%rax,%rdx,8)
incq %rdx
movl %r11d, %ebp
movl %r10d, %r15d
cmpq %rdi, %rdx
jne 0x13136
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x26dba(%rip), %rax     # 0x39fe0
movq (%rax), %rdi
leaq 0x1b407(%rip), %rsi     # 0x2e637
movb $0x2, %al
callq 0x2250
xorl %edi, %edi
callq 0x21e0