// File: /workspace/github_cpp_makefile_star2_O1/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, %r12
movq 0xa8(%rdi), %rdx
movq 0xd8(%rdi), %rsi
leaq (,%rax,8), %rcx
leaq (%rcx,%rcx,2), %rcx
movq (%rsi,%rcx), %rsi
movl (%rsi,%r12,4), %r13d
movq (%rdx,%rcx), %rdx
movslq (%rdx,%r12,4), %rdx
movq %rdx, -0x38(%rbp)
testl %r13d, %r13d
jne 0x4668
movq 0xc0(%rbx), %rdx
movq 0xf0(%rbx), %rsi
movq (%rdx,%rcx), %rdx
movslq (%rdx,%r12,4), %rdx
movq (%rsi,%rcx), %rcx
decl (%rcx,%rdx,4)
movq 0x108(%rbx), %rcx
movq -0x38(%rbp), %rsi
leaq (%rsi,%rsi,2), %rsi
movq (%rcx,%rsi,8), %rcx
decl (%rcx,%rdx,4)
movq 0x150(%rbx), %rcx
decl (%rcx,%rdx,4)
movq 0xf0(%rbx), %rcx
leaq (%rax,%rax,2), %r15
movq (%rcx,%r15,8), %rsi
movq 0x8(%rcx,%r15,8), %rdx
leaq -0x50(%rbp), %rdi
leaq -0x68(%rbp), %rcx
callq 0x5e14
movslq (%rbx), %rax
testq %rax, %rax
jle 0x46ae
movq -0x50(%rbp), %rcx
xorl %edx, %edx
movsd 0x18(%rbx), %xmm0
addsd (%rcx,%rdx,8), %xmm0
movsd %xmm0, (%rcx,%rdx,8)
incq %rdx
cmpq %rdx, %rax
jne 0x4697
testl %r13d, %r13d
jne 0x477d
movq 0x108(%rbx), %rax
movq -0x38(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
movq (%rax,%rcx,8), %rsi
movq 0x8(%rax,%rcx,8), %rdx
leaq -0x68(%rbp), %rdi
leaq -0x98(%rbp), %rcx
callq 0x5e14
movq 0x150(%rbx), %rsi
movq 0x158(%rbx), %rdx
leaq -0x98(%rbp), %rdi
leaq -0x29(%rbp), %rcx
callq 0x5e14
movslq (%rbx), %rax
testq %rax, %rax
jle 0x475e
xorps %xmm0, %xmm0
cvtsi2sdl 0xa0(%rbx), %xmm0
movq -0x68(%rbp), %rcx
movq -0x98(%rbp), %rdx
movq -0x50(%rbp), %rsi
xorl %edi, %edi
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
cmpq %rdi, %rax
jne 0x4721
movq -0x98(%rbp), %rdi
testq %rdi, %rdi
je 0x476f
callq 0x2210
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x477d
callq 0x2210
leaq -0x80(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x5e4e
leaq -0x80(%rbp), %rdi
callq 0x261c
movl %eax, %r14d
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x47a4
callq 0x2210
movq 0xc0(%rbx), %rax
movq (%rax,%r15,8), %rax
movl %r14d, (%rax,%r12,4)
testl %r13d, %r13d
jne 0x47e9
movq 0xf0(%rbx), %rax
movslq %r14d, %rcx
movq (%rax,%r15,8), %rax
incl (%rax,%rcx,4)
movq 0x108(%rbx), %rax
movq -0x38(%rbp), %rdx
leaq (%rdx,%rdx,2), %rdx
movq (%rax,%rdx,8), %rax
incl (%rax,%rcx,4)
movq 0x150(%rbx), %rax
incl (%rax,%rcx,4)
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x47f7
callq 0x2210
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq -0x68(%rbp), %rdi
jmp 0x4818
jmp 0x4824
movq %rax, %rbx
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x4827
callq 0x2210
jmp 0x4827
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x4835
callq 0x2210
movq %rbx, %rdi
callq 0x2390
nop