// File: /workspace/github_cpp_makefile_star2_O2/abaheti95[P]HMM-LDA/Models/cpp_hmm_lda/model.cpp
// Function: HMMLDA::draw_topic(int, int, int)
void HMMLDA::draw_topic(int document_idx, int word_idx, int doc_size) {
	int old_topic = topic_assignments[document_idx][word_idx];
	int old_class = class_assignments[document_idx][word_idx];
	int word = documents[document_idx][word_idx];

	// Exclude current word from topic counts
	if(old_class == 0) {
		num_words_in_doc_assigned_to_topic[document_idx][old_topic]--;
		num_same_words_assigned_to_topic[word][old_topic]--;
		num_words_assigned_to_topic[old_topic]--;
	}


	// Initialize probability proportions with document topic counts
	vector<double> proportions(num_words_in_doc_assigned_to_topic[document_idx].begin(), 
		num_words_in_doc_assigned_to_topic[document_idx].end());

	// Smoothing
	for(int i = 0; i < num_topics; i++)
		proportions[i] += alpha;

	// If the current word is assigned to the semantic class
	// TODO: I have commented next line. Remove it later
	if(old_class == 0) {
		// Initialize numerator with same word topic counts
		vector<double> numerator(num_same_words_assigned_to_topic[word].begin(),
			num_same_words_assigned_to_topic[word].end());
		
		// Initialize denominator with global topic counts
		vector<double> denominator(num_words_assigned_to_topic.begin(), num_words_assigned_to_topic.end());

		for(int i = 0; i < num_topics; i++) {
			// Smoothing
			numerator[i] += beta;
			denominator[i] += vocab_size * beta;
			// Apply multiplier
			proportions[i] = proportions[i] * numerator[i] / denominator[i];
		}
	// TODO: I have commented next line. Remove it later
	}
	
	// Draw topic
	// logging.info('proportions = %s', proportions)
	int new_topic = categorical(proportions);
	// logging.info('drew topic %d', new_topic)
	topic_assignments[document_idx][word_idx] = new_topic;

	// Correct counts with new topic
	if(old_class == 0) {
		num_words_in_doc_assigned_to_topic[document_idx][new_topic] += 1;
		num_same_words_assigned_to_topic[word][new_topic] += 1;
		num_words_assigned_to_topic[new_topic] += 1;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rdi, %rbx
movslq %esi, %rax
movslq %edx, %r13
movq 0xa8(%rdi), %rcx
movq 0xd8(%rdi), %rdx
imulq $0x18, %rax, %r15
movq (%rdx,%r15), %rax
movl (%rax,%r13,4), %r12d
movq (%rcx,%r15), %rax
movslq (%rax,%r13,4), %rsi
testl %r12d, %r12d
movq %rsi, -0x38(%rbp)
je 0x3e1e
movq 0xf0(%rbx), %rax
jmp 0x3e57
movq 0xc0(%rbx), %rcx
movq 0xf0(%rbx), %rax
movq (%rcx,%r15), %rcx
movslq (%rcx,%r13,4), %rcx
movq (%rax,%r15), %rdx
decl (%rdx,%rcx,4)
movq 0x108(%rbx), %rdx
imulq $0x18, %rsi, %rsi
movq (%rdx,%rsi), %rdx
decl (%rdx,%rcx,4)
movq 0x150(%rbx), %rdx
decl (%rdx,%rcx,4)
movq (%rax,%r15), %rsi
movq 0x8(%rax,%r15), %rdx
leaq -0x68(%rbp), %r14
leaq -0x50(%rbp), %rcx
movq %r14, %rdi
callq 0x5094
movslq (%rbx), %rax
movq (%r14), %rcx
xorl %edx, %edx
cmpq %rax, %rdx
jge 0x3e91
movsd 0x18(%rbx), %xmm0
addsd (%rcx,%rdx,8), %xmm0
movsd %xmm0, (%rcx,%rdx,8)
incq %rdx
jmp 0x3e78
testl %r12d, %r12d
jne 0x3f4d
movq 0x108(%rbx), %rax
imulq $0x18, -0x38(%rbp), %rcx
movq (%rax,%rcx), %rsi
movq 0x8(%rax,%rcx), %rdx
leaq -0x50(%rbp), %rdi
leaq -0x98(%rbp), %rcx
callq 0x5094
movq 0x150(%rbx), %rsi
movq 0x158(%rbx), %rdx
leaq -0x98(%rbp), %rdi
leaq -0x29(%rbp), %rcx
callq 0x5094
movslq (%rbx), %rax
cvtsi2sdl 0xa0(%rbx), %xmm0
movq -0x50(%rbp), %rcx
movq -0x98(%rbp), %rdx
movq -0x68(%rbp), %rsi
xorl %edi, %edi
cmpq %rax, %rdi
jge 0x3f38
movsd 0x20(%rbx), %xmm1
addsd (%rcx,%rdi,8), %xmm1
movsd %xmm1, (%rcx,%rdi,8)
movsd 0x20(%rbx), %xmm1
mulsd %xmm0, %xmm1
addsd (%rdx,%rdi,8), %xmm1
movsd %xmm1, (%rdx,%rdi,8)
movsd (%rsi,%rdi,8), %xmm2
mulsd (%rcx,%rdi,8), %xmm2
divsd %xmm1, %xmm2
movsd %xmm2, (%rsi,%rdi,8)
incq %rdi
jmp 0x3ef9
leaq -0x98(%rbp), %rdi
callq 0x69c8
leaq -0x50(%rbp), %rdi
callq 0x69c8
leaq -0x80(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x50c6
leaq -0x80(%rbp), %rdi
callq 0x257c
movl %eax, %r14d
leaq -0x80(%rbp), %rdi
callq 0x69c8
movq 0xc0(%rbx), %rax
movq (%rax,%r15), %rax
movl %r14d, (%rax,%r13,4)
testl %r12d, %r12d
jne 0x3fb1
movq 0xf0(%rbx), %rax
movslq %r14d, %rcx
movq (%rax,%r15), %rax
incl (%rax,%rcx,4)
movq 0x108(%rbx), %rax
imulq $0x18, -0x38(%rbp), %rdx
movq (%rax,%rdx), %rax
incl (%rax,%rcx,4)
movq 0x150(%rbx), %rax
incl (%rax,%rcx,4)
leaq -0x68(%rbp), %rdi
callq 0x69c8
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
jmp 0x3fdb
jmp 0x3fe2
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x69c8
jmp 0x3fe5
movq %rax, %rbx
leaq -0x68(%rbp), %rdi
callq 0x69c8
movq %rbx, %rdi
callq 0x2380