// File: /workspace/github_c_makefile_star2_O3/asford[P]tmalign/./NW.h
// Function: NWDP_TM(double**, double**, int, int, double*, double (*) [3], double, double, int*)
void NWDP_TM(double **x, double **y, int len1, int len2, double t[3], double u[3][3], double d02, double gap_open, int j2i[])
{
	//NW dynamic programming for alignment
	//not a standard implementation of NW algorithm
    //Input: vectors x, y, rotation matrix t, u, scale factor d02, and gap_open
    //Output: j2i[1:len2] \in {1:len1} U {-1}
	//path[0:len1, 0:len2]=1,2,3, from diagonal, horizontal, vertical

	int i, j;
	double h, v, d;

	//initialization
	val[0][0]=0;
	for(i=0; i<=len1; i++)
	{
		val[i][0]=0;
		path[i][0]=false; //not from diagonal
	}

	for(j=0; j<=len2; j++)
	{
		val[0][j]=0;
		path[0][j]=false; //not from diagonal
		j2i[j]=-1;	//all are not aligned, only use j2i[1:len2]
	}      
	double xx[3], dij;

	
	//decide matrix and path
	for(i=1; i<=len1; i++)	
	{	
		transform(t, u, &x[i-1][0], xx);
		for(j=1; j<=len2; j++)
		{
			//d=val[i-1][j-1]+score[i][j]; //diagonal
			dij=dist(xx, &y[j-1][0]);    					
			d=val[i-1][j-1] +  1.0/(1+dij/d02);

			//symbol insertion in horizontal (= a gap in vertical)
			h=val[i-1][j];
			if(path[i-1][j]) //aligned in last position
				h += gap_open;				

			//symbol insertion in vertical
			v=val[i][j-1];
			if(path[i][j-1]) //aligned in last position
				v += gap_open;


			if(d>=h && d>=v)
			{
				path[i][j]=true; //from diagonal
				val[i][j]=d;
			}
			else 
			{
				path[i][j]=false; //from horizontal
				if(v>=h)
					val[i][j]=v;
				else					
					val[i][j]=h;
			}
		} //for i
	} //for j

	//trace back to extract the alignment
	i=len1;
    j=len2;
	while(i>0 && j>0)
	{
		if(path[i][j]) //from diagonal
		{
			j2i[j-1]=i-1;		
			i--;
			j--;
		}
		else 			
		{
			h=val[i-1][j];
			if(path[i-1][j]) h +=gap_open;

			v=val[i][j-1];
			if(path[i][j-1]) v +=gap_open;

			if(v>=h)
				j--;
			else
				i--;
		}
	}	
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r9, 0x38(%rsp)
movq %r8, 0x30(%rsp)
movl %ecx, %r14d
movl %edx, %ebx
movq %rsi, %r13
movq %rdi, 0x28(%rsp)
movq 0x1fc885(%rip), %r15    # 0x6025a8
movq (%r15), %rax
movq $0x0, (%rax)
testl %edx, %edx
js 0x405d57
movq 0x1fc868(%rip), %rcx    # 0x6025a0
leal 0x1(%rbx), %edx
xorl %esi, %esi
movq (%r15,%rsi,8), %rdi
movq $0x0, (%rdi)
movq (%rcx,%rsi,8), %rdi
movb $0x0, (%rdi)
incq %rsi
cmpq %rsi, %rdx
jne 0x405d3d
movq 0x90(%rsp), %rdi
testl %r14d, %r14d
js 0x405d8f
movq 0x1fc835(%rip), %rcx    # 0x6025a0
movq (%rcx), %rcx
leal 0x1(%r14), %edx
xorl %esi, %esi
movq $0x0, (%rax,%rsi,8)
movb $0x0, (%rcx,%rsi)
movl $0xffffffff, (%rdi,%rsi,4) # imm = 0xFFFFFFFF
incq %rsi
cmpq %rsi, %rdx
jne 0x405d74
testl %ebx, %ebx
jle 0x405f62
movq 0x1fc802(%rip), %rax    # 0x6025a0
movq %rax, 0x8(%rsp)
leal 0x1(%r14), %ebp
leal 0x1(%rbx), %eax
movq %rax, 0x18(%rsp)
movsd 0x17e250(%rip), %xmm9   # 0x584008
divsd %xmm0, %xmm9
decq %rbp
movl $0x1, %r12d
movsd %xmm1, 0x20(%rsp)
movsd %xmm9, 0x10(%rsp)
movq 0x28(%rsp), %rax
movq -0x8(%rax,%r12,8), %rdx
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rsi
leaq 0x40(%rsp), %rcx
callq 0x4058ff
movsd 0x10(%rsp), %xmm9
movsd 0x17e207(%rip), %xmm8   # 0x584008
movsd 0x20(%rsp), %xmm1
testl %r14d, %r14d
jle 0x405edb
movsd 0x40(%rsp), %xmm0
movupd 0x48(%rsp), %xmm7
movq -0x8(%r15,%r12,8), %rax
movq (%r15,%r12,8), %rcx
movq 0x8(%rsp), %rsi
movq -0x8(%rsi,%r12,8), %rdx
movq (%rsi,%r12,8), %rsi
xorl %edi, %edi
movsd 0x8(%rax,%rdi,8), %xmm2
cmpb $0x0, 0x1(%rdx,%rdi)
je 0x405e46
addsd %xmm1, %xmm2
movsd (%rcx,%rdi,8), %xmm3
cmpb $0x0, (%rsi,%rdi)
je 0x405e55
addsd %xmm1, %xmm3
movq (%r13,%rdi,8), %r8
movapd %xmm0, %xmm4
subsd (%r8), %xmm4
mulsd %xmm4, %xmm4
movupd 0x8(%r8), %xmm5
movapd %xmm7, %xmm6
subpd %xmm5, %xmm6
mulpd %xmm6, %xmm6
addsd %xmm6, %xmm4
unpckhpd %xmm6, %xmm6            # xmm6 = xmm6[1,1]
addsd %xmm4, %xmm6
mulsd %xmm9, %xmm6
addsd %xmm8, %xmm6
movapd %xmm8, %xmm4
divsd %xmm6, %xmm4
addsd (%rax,%rdi,8), %xmm4
ucomisd %xmm2, %xmm4
jb 0x405eb6
ucomisd %xmm3, %xmm4
jb 0x405eb6
movb $0x1, 0x1(%rsi,%rdi)
movsd %xmm4, 0x8(%rcx,%rdi,8)
jmp 0x405ecf
movb $0x0, 0x1(%rsi,%rdi)
ucomisd %xmm2, %xmm3
jae 0x405ec9
movsd %xmm2, 0x8(%rcx,%rdi,8)
jmp 0x405ecf
movsd %xmm3, 0x8(%rcx,%rdi,8)
incq %rdi
cmpq %rdi, %rbp
jne 0x405e35
incq %r12
cmpq 0x18(%rsp), %r12
jne 0x405dd3
testl %r14d, %r14d
movq 0x90(%rsp), %r10
jle 0x405f62
movq 0x1fc6a3(%rip), %rax    # 0x6025a0
movl %ebx, %edx
movq (%rax,%rdx,8), %rsi
movl %r14d, %edi
leal -0x1(%rbx), %ecx
cmpb $0x1, (%rsi,%rdi)
jne 0x405f19
movl %ecx, -0x4(%r10,%rdi,4)
decl %r14d
jmp 0x405f52
movl %ecx, %r8d
movq (%r15,%r8,8), %r9
movsd (%r9,%rdi,8), %xmm0
movq (%rax,%r8,8), %r8
cmpb $0x0, (%r8,%rdi)
je 0x405f35
addsd %xmm1, %xmm0
movq (%r15,%rdx,8), %rdi
leal -0x1(%r14), %edx
movsd (%rdi,%rdx,8), %xmm2
cmpb $0x0, (%rsi,%rdx)
je 0x405f4c
addsd %xmm1, %xmm2
ucomisd %xmm0, %xmm2
jae 0x405f57
movl %r14d, %edx
movl %ecx, %ebx
testl %ebx, %ebx
jle 0x405f62
movl %edx, %r14d
testl %edx, %edx
jg 0x405efd
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq