// File: 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:
subq $0xc8, %rsp
movb %cl, %al
movq %rdi, 0xc0(%rsp)
movl %esi, 0xbc(%rsp)
movl %edx, 0xb8(%rsp)
andb $0x1, %al
movb %al, 0xb7(%rsp)
movsd %xmm0, 0xa8(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0x90(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0xa0(%rsp)
movl $0x0, 0x9c(%rsp)
movq 0x90(%rsp), %rcx
movl 0x9c(%rsp), %eax
cmpl 0x30(%rcx), %eax
jge 0xeec3
testb $0x1, 0xb7(%rsp)
je 0xedad
movq 0x90(%rsp), %rdi
addq $0xf8, %rdi
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x9c(%rsp), %rsi
callq 0x4440
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x78(%rsp)
addq $0xf8, %rdi
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x9c(%rsp), %rsi
callq 0x4440
movsd 0x78(%rsp), %xmm0
movq 0x90(%rsp), %rdi
subsd (%rax), %xmm0
movsd %xmm0, 0x88(%rsp)
addq $0xf8, %rdi
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x9c(%rsp), %rsi
callq 0x4440
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x80(%rsp)
addq $0xf8, %rdi
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x9c(%rsp), %rsi
callq 0x4440
movsd 0x80(%rsp), %xmm2
movsd 0x88(%rsp), %xmm0
subsd (%rax), %xmm2
movsd 0xa0(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0xa0(%rsp)
jmp 0xeeab
movq 0x90(%rsp), %rdi
addq $0xe0, %rdi
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x9c(%rsp), %rsi
callq 0x4440
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x60(%rsp)
addq $0xe0, %rdi
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x9c(%rsp), %rsi
callq 0x4440
movsd 0x60(%rsp), %xmm0
movq 0x90(%rsp), %rdi
subsd (%rax), %xmm0
movsd %xmm0, 0x70(%rsp)
addq $0xe0, %rdi
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x9c(%rsp), %rsi
callq 0x4440
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x68(%rsp)
addq $0xe0, %rdi
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x9c(%rsp), %rsi
callq 0x4440
movsd 0x68(%rsp), %xmm2
movsd 0x70(%rsp), %xmm0
subsd (%rax), %xmm2
movsd 0xa0(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0xa0(%rsp)
jmp 0xeead
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0xec78
movsd 0xa0(%rsp), %xmm0
callq 0x2190
ucomisd 0xa8(%rsp), %xmm0
jbe 0xf2a1
movq 0x90(%rsp), %rax
movl 0x40(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x40(%rax)
movl $0x0, 0x98(%rsp)
movq 0x90(%rsp), %rcx
movl 0x98(%rsp), %eax
cmpl 0x30(%rcx), %eax
jge 0xf29f
testb $0x1, 0xb7(%rsp)
je 0xf0d8
movq 0x90(%rsp), %rdi
movsd 0xb0de(%rip), %xmm0     # 0x1a010
mulsd 0x58(%rdi), %xmm0
movsd %xmm0, 0x38(%rsp)
addq $0xf8, %rdi
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
addq $0xf8, %rdi
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movsd 0x30(%rsp), %xmm0
movq 0x90(%rsp), %rdi
subsd (%rax), %xmm0
movsd %xmm0, 0x40(%rsp)
addq $0x128, %rdi            # imm = 0x128
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movsd 0x38(%rsp), %xmm0
movsd 0x40(%rsp), %xmm2
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm1
movq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movsd 0xaffa(%rip), %xmm0     # 0x1a010
mulsd 0x58(%rdi), %xmm0
movsd %xmm0, 0x50(%rsp)
addq $0xf8, %rdi
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x48(%rsp)
addq $0xf8, %rdi
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movsd 0x48(%rsp), %xmm0
movq 0x90(%rsp), %rdi
subsd (%rax), %xmm0
movsd %xmm0, 0x58(%rsp)
addq $0x128, %rdi            # imm = 0x128
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movsd 0x50(%rsp), %xmm0
movsd 0x58(%rsp), %xmm2
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
jmp 0xf287
movq 0x90(%rsp), %rdi
movsd 0xaf28(%rip), %xmm0     # 0x1a010
mulsd 0x58(%rdi), %xmm0
movsd %xmm0, 0x8(%rsp)
addq $0xe0, %rdi
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, (%rsp)
addq $0xe0, %rdi
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movsd (%rsp), %xmm0
movq 0x90(%rsp), %rdi
subsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
addq $0x110, %rdi            # imm = 0x110
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movsd 0x8(%rsp), %xmm0
movsd 0x10(%rsp), %xmm2
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm1
movq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movsd 0xae46(%rip), %xmm0     # 0x1a010
mulsd 0x58(%rdi), %xmm0
movsd %xmm0, 0x20(%rsp)
addq $0xe0, %rdi
movslq 0xbc(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
addq $0xe0, %rdi
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movsd 0x18(%rsp), %xmm0
movq 0x90(%rsp), %rdi
subsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
addq $0x110, %rdi            # imm = 0x110
movslq 0xb8(%rsp), %rsi
callq 0xb6b0
movq %rax, %rdi
movslq 0x98(%rsp), %rsi
callq 0x4440
movsd 0x20(%rsp), %xmm0
movsd 0x28(%rsp), %xmm2
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
jmp 0xf289
movl 0x98(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0xeefc
jmp 0xf2a1
addq $0xc8, %rsp
retq
nopl (%rax)