// File: /workspace/github_cpp_makefile_star2_O3/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), %rcx
movq 0xd8(%rdi), %rsi
leaq (,%rax,8), %rdx
leaq (%rdx,%rdx,2), %rdx
movq (%rsi,%rdx), %rsi
movl (%rsi,%r12,4), %r13d
movq (%rcx,%rdx), %rcx
movslq (%rcx,%r12,4), %rdi
testl %r13d, %r13d
movq %rdi, -0x38(%rbp)
je 0x4632
movq 0xf0(%rbx), %rcx
jmp 0x466b
movq 0xc0(%rbx), %rsi
movq 0xf0(%rbx), %rcx
movq (%rsi,%rdx), %rsi
movslq (%rsi,%r12,4), %rsi
movq (%rcx,%rdx), %rdx
decl (%rdx,%rsi,4)
movq 0x108(%rbx), %rdx
leaq (%rdi,%rdi,2), %rdi
movq (%rdx,%rdi,8), %rdx
decl (%rdx,%rsi,4)
movq 0x150(%rbx), %rdx
decl (%rdx,%rsi,4)
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 0x5e18
movslq (%rbx), %rax
testq %rax, %rax
jle 0x46aa
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 0x4693
testl %r13d, %r13d
jne 0x4774
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 0x5e18
movq 0x150(%rbx), %rsi
movq 0x158(%rbx), %rdx
leaq -0x98(%rbp), %rdi
leaq -0x29(%rbp), %rcx
callq 0x5e18
movslq (%rbx), %rax
movq -0x98(%rbp), %rdi
testq %rax, %rax
jle 0x475c
movq -0x68(%rbp), %rcx
xorps %xmm0, %xmm0
cvtsi2sdl 0xa0(%rbx), %xmm0
movq -0x50(%rbp), %rdx
xorl %esi, %esi
movsd 0x20(%rbx), %xmm1
addsd (%rcx,%rsi,8), %xmm1
movsd %xmm1, (%rcx,%rsi,8)
movsd 0x20(%rbx), %xmm1
mulsd %xmm0, %xmm1
addsd (%rdi,%rsi,8), %xmm1
movsd %xmm1, (%rdi,%rsi,8)
movsd (%rdx,%rsi,8), %xmm2
mulsd (%rcx,%rsi,8), %xmm2
divsd %xmm1, %xmm2
movsd %xmm2, (%rdx,%rsi,8)
incq %rsi
cmpq %rsi, %rax
jne 0x471d
jmp 0x4761
testq %rdi, %rdi
je 0x4766
callq 0x2210
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x4774
callq 0x2210
leaq -0x80(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x5e52
leaq -0x80(%rbp), %rdi
callq 0x261c
movl %eax, %r14d
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x479b
callq 0x2210
movq 0xc0(%rbx), %rax
movq (%rax,%r15,8), %rax
movl %r14d, (%rax,%r12,4)
testl %r13d, %r13d
jne 0x47e0
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 0x47ee
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 0x480f
jmp 0x481b
movq %rax, %rbx
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x481e
callq 0x2210
jmp 0x481e
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x482c
callq 0x2210
movq %rbx, %rdi
callq 0x2390