// File: /workspace/github_cpp_makefile_star2_O1/IdelCoder[P]PTransE-ag/Train_PTransE-ag.cpp
// Function: Train::train_kb(int, int, bool, double)
void train_kb(int a, int b, bool isEntity, double margin)
    {
	    /*
		 * This method updates the representations of entities/relations when the distance
		 * exceeds the threshold (i.e., margin).
		 * The first two input parameters represent entity pair or relation pair
		 * which are judged by boolean isEntity.
		 */
        double distance = 0;
        for(int ii = 0; ii < n; ii++)
        {
            if(isEntity)
            {
                distance += (entity_vec[a][ii] - entity_vec[b][ii]) * (entity_vec[a][ii] - entity_vec[b][ii]);
            } else
            {
                distance += (relation_vec[a][ii] - relation_vec[b][ii]) * (relation_vec[a][ii] - relation_vec[b][ii]);
            }
        }
        if(sqrt(distance) > margin)
        {
			// Distance exceeds margin, then update embeddings
            positive_margin_count ++;
            for(int ii = 0; ii < n; ii++)
            {
			    // dimension-wise gradient descendant updating
                if(isEntity)
                {
                    entity_tmp[a][ii] -= rate * 2 * (entity_vec[a][ii] - entity_vec[b][ii]);
                    entity_tmp[b][ii] += rate * 2 * (entity_vec[a][ii] - entity_vec[b][ii]);
                } else
                {
                    relation_tmp[a][ii] -= rate * 2 * (relation_vec[a][ii] - relation_vec[b][ii]);
                    relation_tmp[b][ii] += rate * 2 * (relation_vec[a][ii] - relation_vec[b][ii]);
                }
            }
        }

    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movapd %xmm0, %xmm3
movl %ecx, %ebp
movl %edx, %r14d
movl %esi, %r15d
movq %rdi, %rbx
movslq 0x30(%rdi), %rax
xorpd %xmm1, %xmm1
xorpd %xmm0, %xmm0
testq %rax, %rax
jle 0x8027
movslq %r15d, %rcx
shlq $0x3, %rcx
leaq (%rcx,%rcx,2), %rcx
movq 0xe0(%rbx), %rdx
movq 0xf8(%rbx), %rsi
leaq (%rdx,%rcx), %rdi
movslq %r14d, %r8
shlq $0x3, %r8
leaq (%r8,%r8,2), %r8
addq %r8, %rdx
addq %rsi, %rcx
addq %r8, %rsi
testb %bpl, %bpl
cmoveq %rdi, %rcx
cmoveq %rdx, %rsi
movq (%rcx), %rcx
movq (%rsi), %rdx
xorl %esi, %esi
movsd (%rcx,%rsi,8), %xmm2
subsd (%rdx,%rsi,8), %xmm2
mulsd %xmm2, %xmm2
addsd %xmm2, %xmm0
incq %rsi
cmpq %rsi, %rax
jne 0x800d
ucomisd %xmm1, %xmm0
jb 0x8033
sqrtsd %xmm0, %xmm0
jmp 0x8042
movsd %xmm3, (%rsp)
callq 0x2160
movsd (%rsp), %xmm3
ucomisd %xmm3, %xmm0
jbe 0x8125
incl 0x40(%rbx)
movslq 0x30(%rbx), %rax
testq %rax, %rax
jle 0x8125
movslq %r15d, %rcx
shlq $0x3, %rcx
leaq (%rcx,%rcx,2), %rsi
movq 0xe0(%rbx), %rcx
movq 0xf8(%rbx), %rdx
leaq (%rcx,%rsi), %rdi
movslq %r14d, %r8
shlq $0x3, %r8
leaq (%r8,%r8,2), %r8
addq %r8, %rcx
movq 0x110(%rbx), %r9
leaq (%r9,%rsi), %r10
addq %r8, %r9
leaq (%rdx,%rsi), %r11
addq %r8, %rdx
movq 0x128(%rbx), %r14
addq %r14, %rsi
addq %r8, %r14
testb %bpl, %bpl
cmoveq %rdi, %r11
cmoveq %rcx, %rdx
cmoveq %r10, %rsi
cmoveq %r9, %r14
movq (%r11), %rcx
movq (%rdx), %rdx
movq (%rsi), %rsi
movq (%r14), %rdi
xorl %r8d, %r8d
movsd 0x2f85(%rip), %xmm0     # 0xb058
movsd (%rcx,%r8,8), %xmm1
subsd (%rdx,%r8,8), %xmm1
movsd 0x58(%rbx), %xmm2
mulsd %xmm0, %xmm2
mulsd %xmm1, %xmm2
addsd (%rsi,%r8,8), %xmm2
movsd %xmm2, (%rsi,%r8,8)
movsd 0x58(%rbx), %xmm1
movsd (%rcx,%r8,8), %xmm2
subsd (%rdx,%r8,8), %xmm2
addsd %xmm1, %xmm1
mulsd %xmm1, %xmm2
addsd (%rdi,%r8,8), %xmm2
movsd %xmm2, (%rdi,%r8,8)
incq %r8
cmpq %r8, %rax
jne 0x80d3
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq