// File: /workspace/github_c_makefile_star2_O2/olcaytaner[P]Isell/hmm.c
// Function: check_hmm
int check_hmm(char* name, Hmmptr hmm)
{
 /*!Last Changed 11.04.2007*/
 int i, j;
 double sum;
 Gaussianptr g;
 Gaussianmixtureptr gm;
 int numrealfeatures = current_dataset->multifeaturecount - 1;
 printf("Checking %s. ", name);
 if (!between(hmm->hmmtype, 0, 2))
  {
   printf("Hmm type %d wrong\n", hmm->hmmtype);
   return 0;
  }
 if (!between(hmm->statetype, 0, 4))
  {
   printf("Hmm state type %d wrong\n", hmm->statetype);
   return 0;
  }
 if (hmm->statecount <= 1)
  {
   printf("Hmm state count %d must be larger than 1\n", hmm->statecount);
   return 0;
  }
 if (!(hmm->states))
  {
   printf("Hmm states not allocated\n");
   return 0;
  }
 sum = 0.0;
 for (i = 0; i < hmm->statecount; i++)
   sum += hmm->states[i].pi;
 if (!dequal(sum - 1, 0))
  {
   printf("Sum of pi %.6f is not equal to 1\n", sum);
   return 0;
  }
 for (i = 0; i < hmm->statecount; i++)
  {
   for (j = 0; j < hmm->statecount; j++)
     if (hmm->states[i].a_i_dot[j] != hmm->states[j].a_dot_j[i])
      {
       printf("Outgoing probability %.6f and incoming probability %.6f from state %d to state %d do not match\n", hmm->states[i].a_i_dot[j], hmm->states[j].a_dot_j[i], i, j);
       return 0;
      }
   sum = sum_of_list_double(hmm->states[i].a_i_dot, hmm->statecount);
   if (!dequal(sum - 1, 0))
    {
     printf("Sum of a_i_dot %.6f of state %d is not equal to 1\n", sum, i);
     return 0;
    }
   switch (hmm->statetype)
    {
     case         STATE_GAUSSIAN:g = (Gaussianptr) hmm->states[i].b;
                                 if (!(g->mean))
                                  {
                                   printf("Gaussian mean of state %d not allocated\n", i);
                                   return 0;
                                  }
                                 if (g->covariance.row != numrealfeatures || g->covariance.col != numrealfeatures)
                                  {
                                   printf("Covariance matrix dimensions %d %d of state %d is not true\n", g->covariance.row, g->covariance.col, i);
                                   return 0;
                                  }
                                 break;
     case STATE_GAUSSIAN_MIXTURE:gm = (Gaussianmixtureptr) hmm->states[i].b;
                                 if (gm->componentcount <= 0)
                                  {
                                   printf("Number of components %d must be larger than 0\n", gm->componentcount);
                                   return 0;
                                  }
                                 sum = sum_of_list_double(gm->weights, gm->componentcount);
                                 if (!dequal(sum - 1, 0))
                                  {
                                   printf("Sum of component weights %.6f must be equal to 1.0", sum);
                                   return 0;
                                  }
                                 if (!(gm->components))
                                  {
                                   printf("Gaussian components not allocated\n");
                                   return 0;
                                  }
                                 for (j = 0; i < gm->componentcount; i++)
                                  {
                                   if (!(gm->components[i].mean))
                                    {
                                     printf("Gaussian mean of mixture component %d of state %d not allocated\n", j, i);
                                     return 0;
                                    }
                                   if (gm->components[i].covariance.row != numrealfeatures || gm->components[i].covariance.col != numrealfeatures)
                                    {
                                     printf("Covariance matrix dimensions %d %d of mixture component %d of state %d is not true\n", g->covariance.row, g->covariance.col, j, i);
                                     return 0;
                                    }
                                  }
                                 break;
     default                    :break;
    }
  }
 printf("Ok...\n");
 return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %rsi
leaq 0xa7f0c(%rip), %rax     # 0xcd870
movq (%rax), %rax
movl 0x1c0(%rax), %r12d
leaq 0x7295d(%rip), %rdi     # 0x982d2
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x4030
movl 0x10(%rbx), %edi
pushq $0x2
popq %rdx
xorl %esi, %esi
callq 0x34c00
testl %eax, %eax
je 0x259b7
movl 0xc(%rbx), %edi
xorl %ebp, %ebp
pushq $0x4
popq %rdx
xorl %esi, %esi
callq 0x34c00
testl %eax, %eax
je 0x259c3
movslq 0x8(%rbx), %rsi
cmpq $0x1, %rsi
jg 0x259e5
leaq 0x72959(%rip), %rdi     # 0x9830c
xorl %ebp, %ebp
jmp 0x259cd
movl 0x10(%rbx), %esi
leaq 0x7291f(%rip), %rdi     # 0x982e0
jmp 0x259cd
movl 0xc(%rbx), %esi
leaq 0x72926(%rip), %rdi     # 0x982f3
xorl %eax, %eax
callq 0x4030
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rbx), %rax
testq %rax, %rax
je 0x25b6b
decl %r12d
shlq $0x5, %rsi
xorpd %xmm1, %xmm1
xorl %ecx, %ecx
cmpq %rcx, %rsi
je 0x25a0f
addsd 0x10(%rax,%rcx), %xmm1
addq $0x20, %rcx
jmp 0x259fe
movsd 0x70399(%rip), %xmm0    # 0x95db0
addsd %xmm1, %xmm0
movsd %xmm1, (%rsp)
xorpd %xmm1, %xmm1
callq 0x34c3a
testl %eax, %eax
je 0x25b8c
xorl %r15d, %r15d
movl 0x8(%rbx), %esi
cmpl %esi, %r15d
jge 0x25be2
movslq %r15d, %r14
testl %esi, %esi
movl $0x0, %eax
cmovgl %esi, %eax
movq (%rbx), %rcx
movq %r14, %rbp
shlq $0x5, %rbp
movq 0x8(%rcx,%rbp), %rdi
xorl %edx, %edx
cmpq %rdx, %rax
je 0x25a8a
movsd (%rdi,%rdx,8), %xmm0
movq (%rcx), %r8
movsd (%r8,%r14,8), %xmm1
ucomisd %xmm1, %xmm0
jne 0x25b79
jp 0x25b79
incq %rdx
addq $0x20, %rcx
jmp 0x25a5e
callq 0x33c3e
movsd %xmm0, (%rsp)
addsd 0x70314(%rip), %xmm0    # 0x95db0
xorpd %xmm1, %xmm1
callq 0x34c3a
testl %eax, %eax
je 0x25bf6
movl 0xc(%rbx), %eax
cmpl $0x2, %eax
je 0x25af5
cmpl $0x1, %eax
jne 0x25ae7
movq (%rbx), %rax
movq 0x18(%rax,%rbp), %r13
cmpq $0x0, (%r13)
je 0x25c0e
movl 0x8(%r13), %esi
movl 0xc(%r13), %edx
cmpl %r12d, %esi
jne 0x25c3c
cmpl %r12d, %edx
jne 0x25c39
movl %r15d, %r14d
incl %r14d
movl %r14d, %r15d
jmp 0x25a34
movq (%rbx), %rax
movq 0x18(%rax,%rbp), %r15
movl 0x8(%r15), %esi
testl %esi, %esi
jle 0x25c1f
movq 0x10(%r15), %rdi
callq 0x33c3e
movsd %xmm0, (%rsp)
addsd 0x70291(%rip), %xmm0    # 0x95db0
xorpd %xmm1, %xmm1
callq 0x34c3a
testl %eax, %eax
je 0x25c2d
movq (%r15), %rcx
testq %rcx, %rcx
je 0x25c54
movslq 0x8(%r15), %rax
imulq $0x18, %r14, %rdx
addq %rdx, %rcx
addq $0xc, %rcx
cmpq %rax, %r14
jge 0x25aea
cmpq $0x0, -0xc(%rcx)
je 0x25bc8
cmpl %r12d, -0x4(%rcx)
jne 0x25ba6
cmpl %r12d, (%rcx)
jne 0x25ba6
incq %r14
addq $0x18, %rcx
jmp 0x25b4b
leaq 0x72c13(%rip), %rdi     # 0x98785
callq 0x4090
jmp 0x25b9f
leaq 0x727d8(%rip), %rdi     # 0x98358
movl %r15d, %esi
movb $0x2, %al
callq 0x4030
jmp 0x25b9f
leaq 0x727a3(%rip), %rdi     # 0x98336
movsd (%rsp), %xmm0
movb $0x1, %al
callq 0x4030
xorl %ebp, %ebp
jmp 0x259d4
movl 0x8(%r13), %esi
movl 0xc(%r13), %edx
leaq 0x7293e(%rip), %rdi     # 0x984f3
xorl %ebp, %ebp
xorl %ecx, %ecx
movl %r14d, %r8d
xorl %eax, %eax
callq 0x4030
jmp 0x259d4
leaq 0x728e3(%rip), %rdi     # 0x984b2
xorl %ebp, %ebp
xorl %esi, %esi
movl %r14d, %edx
xorl %eax, %eax
callq 0x4030
jmp 0x259d4
leaq 0x72bb5(%rip), %rdi     # 0x9879e
callq 0x4090
pushq $0x1
popq %rbp
jmp 0x259d4
leaq 0x727bb(%rip), %rdi     # 0x983b8
movsd (%rsp), %xmm0
movl %r15d, %esi
movb $0x1, %al
callq 0x4030
jmp 0x25b9f
leaq 0x727d6(%rip), %rdi     # 0x983eb
xorl %ebp, %ebp
movl %r15d, %esi
jmp 0x259cd
leaq 0x7282a(%rip), %rdi     # 0x98450
xorl %ebp, %ebp
jmp 0x259cd
leaq 0x7284b(%rip), %rdi     # 0x9847f
jmp 0x25b93
movl %r12d, %esi
leaq 0x727d1(%rip), %rdi     # 0x98414
xorl %ebp, %ebp
movl %r15d, %ecx
xorl %eax, %eax
callq 0x4030
jmp 0x259d4
leaq 0x72b49(%rip), %rdi     # 0x987a4
jmp 0x25b72