// File: /workspace/github_cpp_makefile_star2_O3/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 0x7fad
movslq %r15d, %rcx
leaq 0xf8(%rbx), %rdx
leaq 0xe0(%rbx), %rsi
testb %bpl, %bpl
cmovneq %rdx, %rsi
movslq %r14d, %rdx
movq (%rsi), %rsi
leaq (%rcx,%rcx,2), %rcx
leaq (%rdx,%rdx,2), %rdx
movq (%rsi,%rcx,8), %rcx
movq (%rsi,%rdx,8), %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 0x7f93
ucomisd %xmm1, %xmm0
jb 0x7fb9
sqrtsd %xmm0, %xmm0
jmp 0x7fc8
movsd %xmm3, (%rsp)
callq 0x2160
movsd (%rsp), %xmm3
ucomisd %xmm3, %xmm0
jbe 0x8092
incl 0x40(%rbx)
movslq 0x30(%rbx), %rax
testq %rax, %rax
jle 0x8092
leaq 0xe0(%rbx), %rcx
movslq %r15d, %rdx
movslq %r14d, %rsi
leaq 0x110(%rbx), %rdi
leaq 0xf8(%rbx), %r8
leaq 0x128(%rbx), %r9
shlq $0x3, %rdx
shlq $0x3, %rsi
testb %bpl, %bpl
cmoveq %rcx, %r8
movq (%r8), %r8
leaq (%rdx,%rdx,2), %r10
cmoveq %rdi, %r9
leaq (%rsi,%rsi,2), %rdi
movq (%r9), %r9
movq (%r8,%r10), %rcx
movq (%r8,%rdi), %rdx
movq (%r9,%r10), %rsi
movq (%r9,%rdi), %rdi
xorl %r8d, %r8d
movsd 0x2018(%rip), %xmm0     # 0xa058
movsd 0x58(%rbx), %xmm1
mulsd %xmm0, %xmm1
movsd (%rcx,%r8,8), %xmm2
subsd (%rdx,%r8,8), %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 0x8040
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop