// File: gcollet[P]MstatX/src/wentropy.cpp
// Function: WEntStat::calculate(Msa&)
void
WEntStat :: calculate(Msa & msa)
{
	string alphabet = msa.getAlphabet();
	
	/* Init sizes */
	int L = msa.getNcol();
	int N = msa.getNseq();
	int K = (int) alphabet.size();
	
	/* Allocate probabilities array */
	float ** p = (float **) calloc (L, sizeof(float*));
	if (p == NULL){
		fprintf(stderr,"Cannot Allocate probability matrix\n");
		exit(0);
	}
	for (int i(0); i < L; i++){
		p[i] = (float *) calloc (K, sizeof(float));
		if (p[i] == NULL){
			fprintf(stderr,"Cannot Allocate probability submatrix\n");
			exit(0);
		}
	}
	
	/* Calculate Sequence Weights */
	vector<float> w;
	for (int seq(0); seq < N; ++seq){
		w.push_back(calcSeqWeight(msa,seq));
	}
	
	/* Calculate aa proba and conservation score by columns */
	float lambda = 1.0 / log(MIN(K,N));
	
	for (int x(0); x < L; ++x){
		col_stat.push_back(0.0);
		for (int a(0); a < K; ++a){
			for (int j(0); j < N; ++j){
				if(msa.getSymbol(j, x) == alphabet[a]){
					p[x][a] += w[j];
				}
			}
			if (p[x][a] != 0.0){
				col_stat[x] -= p[x][a] * log(p[x][a]);
			}
		}
		col_stat[x] *= lambda;
	}
	
	for (int i(0); i < L; ++i) {
		free (p[i]);
	}
	free(p);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x71e0
movq -0x10(%rbp), %rdi
callq 0x4ae0
movl %eax, -0x9c(%rbp)
jmp 0x1a29c
movl -0x9c(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4b00
movl %eax, -0xac(%rbp)
jmp 0x1a2b6
movl -0xac(%rbp), %eax
movl %eax, -0x48(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x4260
movl %eax, -0x4c(%rbp)
movslq -0x34(%rbp), %rdi
movl $0x8, %esi
callq 0x4220
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jne 0x1a314
movq 0xbcdd(%rip), %rax      # 0x25fc8
movq (%rax), %rdi
leaq 0xd83(%rip), %rsi       # 0x1b078
movb $0x0, %al
callq 0x44d0
xorl %edi, %edi
callq 0x4400
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x1a6b7
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x1a37b
movslq -0x4c(%rbp), %rdi
movl $0x4, %esi
callq 0x4220
movq %rax, %rdx
movq -0x58(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x58(%rbp), %rax
movslq -0x5c(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x1a36e
movq 0xbc72(%rip), %rax      # 0x25fc8
movq (%rax), %rdi
leaq 0xd3c(%rip), %rsi       # 0x1b09c
movb $0x0, %al
callq 0x44d0
xorl %edi, %edi
callq 0x4400
jmp 0x1a370
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x1a31b
leaq -0x78(%rbp), %rdi
callq 0x7210
movl $0x0, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x48(%rbp), %eax
jge 0x1a3f3
movq -0xa8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x7c(%rbp), %edx
callq 0x1a160
movss %xmm0, -0xb0(%rbp)
jmp 0x1a3b0
movss -0xb0(%rbp), %xmm0
movss %xmm0, -0x80(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x4b20
jmp 0x1a3cc
jmp 0x1a3ce
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x1a38b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x4ea0
jmp 0x1a6b7
movl -0x4c(%rbp), %eax
cmpl -0x48(%rbp), %eax
jge 0x1a406
movl -0x4c(%rbp), %eax
movl %eax, -0xb4(%rbp)
jmp 0x1a40f
movl -0x48(%rbp), %eax
movl %eax, -0xb4(%rbp)
movl -0xb4(%rbp), %edi
callq 0x19cc0
movsd %xmm0, -0xc0(%rbp)
jmp 0x1a424
movsd -0xc0(%rbp), %xmm1
movsd 0xc2c(%rip), %xmm0      # 0x1b060
divsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x84(%rbp)
movl $0x0, -0x88(%rbp)
movl -0x88(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x1a659
movq -0xa8(%rbp), %rdi
addq $0x8, %rdi
movl $0x0, -0x8c(%rbp)
leaq -0x8c(%rbp), %rsi
callq 0x4b20
jmp 0x1a480
movl $0x0, -0x90(%rbp)
movl -0x90(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jge 0x1a60e
movl $0x0, -0x94(%rbp)
movl -0x94(%rbp), %eax
cmpl -0x48(%rbp), %eax
jge 0x1a555
movq -0x10(%rbp), %rdi
movl -0x94(%rbp), %esi
movl -0x88(%rbp), %edx
callq 0x71a0
movb %al, -0xc1(%rbp)
jmp 0x1a4cf
movb -0xc1(%rbp), %al
movsbl %al, %eax
movl %eax, -0xd4(%rbp)
movslq -0x90(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x46c0
movq %rax, -0xd0(%rbp)
jmp 0x1a4f7
movl -0xd4(%rbp), %eax
movq -0xd0(%rbp), %rcx
movsbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x1a53f
movslq -0x94(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x5180
movss (%rax), %xmm0
movq -0x58(%rbp), %rax
movslq -0x88(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x90(%rbp), %rcx
addss (%rax,%rcx,4), %xmm0
movss %xmm0, (%rax,%rcx,4)
jmp 0x1a541
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x1a4a3
movq -0x58(%rbp), %rax
movslq -0x88(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x90(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
cvtss2sd %xmm0, %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x1a581
jp 0x1a581
jmp 0x1a5f8
movq -0x58(%rbp), %rax
movslq -0x88(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x90(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0xdc(%rbp)
callq 0x13900
movss %xmm0, -0xd8(%rbp)
jmp 0x1a5b3
movq -0xa8(%rbp), %rdi
addq $0x8, %rdi
movslq -0x88(%rbp), %rsi
callq 0x5180
movss -0xdc(%rbp), %xmm0
movss -0xd8(%rbp), %xmm2
movss (%rax), %xmm1
movd %xmm0, %ecx
xorl $0x80000000, %ecx       # imm = 0x80000000
movd %ecx, %xmm0
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, (%rax)
jmp 0x1a5fa
movl -0x90(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x90(%rbp)
jmp 0x1a48a
movq -0xa8(%rbp), %rdi
movss -0x84(%rbp), %xmm0
movss %xmm0, -0xe0(%rbp)
addq $0x8, %rdi
movslq -0x88(%rbp), %rsi
callq 0x5180
movss -0xe0(%rbp), %xmm0
mulss (%rax), %xmm0
movss %xmm0, (%rax)
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0x1a44e
movl $0x0, -0x98(%rbp)
movl -0x98(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x1a693
movq -0x58(%rbp), %rax
movslq -0x98(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x43f0
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
jmp 0x1a663
movq -0x58(%rbp), %rdi
callq 0x43f0
leaq -0x78(%rbp), %rdi
callq 0x4ea0
leaq -0x30(%rbp), %rdi
callq 0x41e0
addq $0xe0, %rsp
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x41e0
movq -0x40(%rbp), %rdi
callq 0x45e0
nopl (%rax)