// File: /workspace/github_cpp_makefile_star2_O1/abaheti95[P]HMM-LDA/Models/cpp_hmm_lda/model.cpp
// Function: HMMLDA::spl_draw_topic(std::vector<int, std::allocator<int>>&, std::vector<int, std::allocator<int>>&, std::vector<int, std::allocator<int>>&, std::vector<int, std::allocator<int>>&, int, int)
void HMMLDA::spl_draw_topic(vector<int> &document, vector<int> &topic_assignment, vector<int> &class_assignment, vector<int> &num_words_in_document_assigned_to_topic, int word_idx, int doc_size) {
	int old_topic = topic_assignment[word_idx];
	int old_class = class_assignment[word_idx];
	int word = document[word_idx];

	// Exclude current word from topic counts
	if(old_class == 0) {
		num_words_in_document_assigned_to_topic[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_document_assigned_to_topic.begin(), 
		num_words_in_document_assigned_to_topic.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_assignment[word_idx] = new_topic;

	// Correct counts with new topic
	if(old_class == 0) {
		num_words_in_document_assigned_to_topic[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 %r8, %r14
movq %rdx, -0x40(%rbp)
movq %rdi, %rbx
movslq %r9d, %r13
movq (%rcx), %rax
movl (%rax,%r13,4), %r15d
movq (%rsi), %rax
movslq (%rax,%r13,4), %rax
movq %rax, -0x38(%rbp)
testl %r15d, %r15d
jne 0x5858
movq -0x40(%rbp), %rax
movq (%rax), %rax
movslq (%rax,%r13,4), %rax
movq (%r14), %rcx
decl (%rcx,%rax,4)
movq 0x108(%rbx), %rcx
movq -0x38(%rbp), %rdx
leaq (%rdx,%rdx,2), %rdx
movq (%rcx,%rdx,8), %rcx
decl (%rcx,%rax,4)
movq 0x150(%rbx), %rcx
decl (%rcx,%rax,4)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
leaq -0x58(%rbp), %rdi
leaq -0x70(%rbp), %rcx
callq 0x5e14
movslq (%rbx), %rax
testq %rax, %rax
jle 0x5891
movq -0x58(%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 0x587a
testl %r15d, %r15d
jne 0x5960
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 -0x70(%rbp), %rdi
leaq -0xa0(%rbp), %rcx
callq 0x5e14
movq 0x150(%rbx), %rsi
movq 0x158(%rbx), %rdx
leaq -0xa0(%rbp), %rdi
leaq -0x29(%rbp), %rcx
callq 0x5e14
movslq (%rbx), %rax
testq %rax, %rax
jle 0x5941
xorps %xmm0, %xmm0
cvtsi2sdl 0xa0(%rbx), %xmm0
movq -0x70(%rbp), %rcx
movq -0xa0(%rbp), %rdx
movq -0x58(%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 0x5904
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0x5952
callq 0x2210
movq -0x70(%rbp), %rdi
testq %rdi, %rdi
je 0x5960
callq 0x2210
leaq -0x88(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x5e4e
leaq -0x88(%rbp), %rdi
callq 0x261c
movl %eax, %r12d
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x5990
callq 0x2210
movq -0x40(%rbp), %rax
movq (%rax), %rax
movl %r12d, (%rax,%r13,4)
testl %r15d, %r15d
jne 0x59c9
movslq %r12d, %rax
movq (%r14), %rcx
incl (%rcx,%rax,4)
movq 0x108(%rbx), %rcx
movq -0x38(%rbp), %rdx
leaq (%rdx,%rdx,2), %rdx
movq (%rcx,%rdx,8), %rcx
incl (%rcx,%rax,4)
movq 0x150(%rbx), %rcx
incl (%rcx,%rax,4)
movq -0x58(%rbp), %rdi
testq %rdi, %rdi
je 0x59d7
callq 0x2210
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq -0x70(%rbp), %rdi
jmp 0x59fb
jmp 0x5a07
movq %rax, %rbx
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x5a0a
callq 0x2210
jmp 0x5a0a
movq %rax, %rbx
movq -0x58(%rbp), %rdi
testq %rdi, %rdi
je 0x5a18
callq 0x2210
movq %rbx, %rdi
callq 0x2390