// File: /workspace/github_cpp_makefile_star2_O3/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
leal 0x2(%rbx), %eax
shlq $0x3, %rax
cmpl $-0x2, %esi
movq $-0x1, %rdi
cmovgeq %rax, %rdi
callq 0x2040
testl %ebx, %ebx
jle 0x12f04
movl %ebp, %edx
shrl $0x1f, %edx
addl %ebp, %edx
sarl %edx
movb 0x263d6(%rip), %cl      # 0x391cd
movslq %edx, %rsi
leal 0x1(%rbx), %edi
movl $0xffffffff, %r11d      # imm = 0xFFFFFFFF
xorpd %xmm1, %xmm1
movl $0x1, %edx
xorl %ebp, %ebp
movl $0x1, %r8d
movapd 0x19bc4(%rip), %xmm2    # 0x2c9e0
movsd 0x17244(%rip), %xmm3    # 0x2a068
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movl %edx, %r9d
subl %esi, %r9d
cmpq %rsi, %rdx
cmovlel %r8d, %r9d
leal (%rsi,%rdx), %r10d
cmpl %ebx, %r10d
cmovgel %ebx, %r10d
testb $0x1, %bpl
je 0x12e7d
cmpl %r9d, %r15d
jge 0x12e61
movslq %r15d, %r15
movslq %r9d, %r12
subsd (%r14,%r15,8), %xmm1
incq %r15
cmpq %r15, %r12
jne 0x12e53
cmpl %r10d, %r11d
jge 0x12e9a
movslq %r11d, %r11
movslq %r10d, %r15
addsd 0x8(%r14,%r11,8), %xmm1
incq %r11
cmpq %r15, %r11
jl 0x12e6c
jmp 0x12e9a
cmpl %r9d, %r10d
jl 0x12e9a
movslq %r9d, %r11
movslq %r10d, %r15
decq %r11
addsd 0x8(%r14,%r11,8), %xmm1
incq %r11
cmpq %r15, %r11
jl 0x12e8b
testb %cl, %cl
je 0x12ed1
xorpd %xmm0, %xmm0
cmpl %r9d, %r10d
jl 0x12ebf
movslq %r9d, %r11
movslq %r10d, %r15
decq %r11
addsd 0x8(%r14,%r11,8), %xmm0
incq %r11
cmpq %r15, %r11
jl 0x12eb0
movapd %xmm0, %xmm4
subsd %xmm1, %xmm4
andpd %xmm2, %xmm4
ucomisd %xmm3, %xmm4
ja 0x12f0d
movl %r10d, %r11d
subl %r9d, %r11d
incl %r11d
xorps %xmm0, %xmm0
cvtsi2sd %r11d, %xmm0
movapd %xmm1, %xmm4
divsd %xmm0, %xmm4
movsd %xmm4, (%rax,%rdx,8)
incq %rdx
movb $0x1, %bpl
movl %r10d, %r11d
movl %r9d, %r15d
cmpq %rdi, %rdx
jne 0x12e2a
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x260cc(%rip), %rax     # 0x38fe0
movq (%rax), %rdi
leaq 0x1a719(%rip), %rsi     # 0x2d637
movb $0x2, %al
callq 0x2250
xorl %edi, %edi
callq 0x21e0