// File: /workspace/github_cpp_makefile_star2_O2/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 %r13
pushq %r12
pushq %rbx
pushq %rax
movapd %xmm0, %xmm2
movl %ecx, %ebp
movq %rdi, %rbx
movl 0x30(%rdi), %eax
movslq %esi, %rsi
movslq %edx, %rdi
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
leaq 0xf8(%rbx), %r12
leaq 0xe0(%rbx), %r13
testl %ebp, %ebp
movq %r13, %rdx
cmovneq %r12, %rdx
movq (%rdx), %rdx
imulq $0x18, %rsi, %r14
leaq (%rdx,%r14), %rsi
imulq $0x18, %rdi, %r15
addq %r15, %rdx
xorpd %xmm0, %xmm0
cmpq %rcx, %rax
je 0x6065
movq (%rsi), %rdi
movsd (%rdi,%rcx,8), %xmm1
movq (%rdx), %rdi
subsd (%rdi,%rcx,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %rcx
jmp 0x6043
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x6075
sqrtsd %xmm0, %xmm0
jmp 0x6084
movsd %xmm2, (%rsp)
callq 0x2130
movsd (%rsp), %xmm2
ucomisd %xmm2, %xmm0
jbe 0x6130
incl 0x40(%rbx)
movl 0x30(%rbx), %eax
leaq 0x110(%rbx), %rdi
leaq 0x128(%rbx), %rsi
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
testb %bpl, %bpl
cmovneq %r12, %r13
movq (%r13), %rdx
cmovneq %rsi, %rdi
leaq (%rdx,%r14), %rsi
addq %r15, %rdx
movq (%rdi), %rdi
addq %rdi, %r14
addq %r15, %rdi
movsd 0x2f88(%rip), %xmm0     # 0x9058
cmpq %rcx, %rax
je 0x6130
movsd 0x58(%rbx), %xmm1
mulsd %xmm0, %xmm1
movq (%rsi), %r8
movsd (%r8,%rcx,8), %xmm2
movq (%rdx), %r9
subsd (%r9,%rcx,8), %xmm2
mulsd %xmm1, %xmm2
movq (%r14), %r10
addsd (%r10,%rcx,8), %xmm2
movsd %xmm2, (%r10,%rcx,8)
movsd 0x58(%rbx), %xmm1
addsd %xmm1, %xmm1
movsd (%r8,%rcx,8), %xmm2
subsd (%r9,%rcx,8), %xmm2
mulsd %xmm1, %xmm2
movq (%rdi), %r8
addsd (%r8,%rcx,8), %xmm2
movsd %xmm2, (%r8,%rcx,8)
incq %rcx
jmp 0x60d0
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop