// File: /workspace/github_c_makefile_star2_O3/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 0xac7cf(%rip), %rax     # 0xd5870
movq (%rax), %rax
movl 0x1c0(%rax), %r15d
leaq 0x7f2a0(%rip), %rdi     # 0xa8352
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x4030
movl 0x10(%rbx), %edi
xorl %esi, %esi
movl $0x2, %edx
callq 0x39a78
testl %eax, %eax
je 0x290f8
movl 0xc(%rbx), %edi
xorl %ebp, %ebp
xorl %esi, %esi
movl $0x4, %edx
callq 0x39a78
testl %eax, %eax
je 0x29104
movslq 0x8(%rbx), %rsi
cmpq $0x1, %rsi
jg 0x29126
leaq 0x7f298(%rip), %rdi     # 0xa838c
xorl %ebp, %ebp
jmp 0x2910e
movl 0x10(%rbx), %esi
leaq 0x7f25e(%rip), %rdi     # 0xa8360
jmp 0x2910e
movl 0xc(%rbx), %esi
leaq 0x7f265(%rip), %rdi     # 0xa8373
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 0x292de
decl %r15d
shlq $0x5, %rsi
xorpd %xmm1, %xmm1
xorl %ecx, %ecx
addsd 0x10(%rax,%rcx), %xmm1
addq $0x20, %rcx
cmpq %rcx, %rsi
jne 0x2913f
movsd 0x7cc52(%rip), %xmm0    # 0xa5da8
movsd %xmm1, (%rsp)
addsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
callq 0x39ab2
testl %eax, %eax
je 0x292ec
movl 0x8(%rbx), %esi
testl %esi, %esi
jle 0x292c8
xorl %r14d, %r14d
movslq %r14d, %r13
movq %r13, %rbp
shlq $0x5, %rbp
movq (%rbx), %rax
movq 0x8(%rax,%rbp), %rdi
testl %esi, %esi
jle 0x291c2
movl %esi, %ecx
xorl %edx, %edx
movsd (%rdi,%rdx,8), %xmm0
movq (%rax), %r8
movsd (%r8,%r13,8), %xmm1
ucomisd %xmm1, %xmm0
jne 0x29301
jp 0x29301
incq %rdx
addq $0x20, %rax
cmpq %rdx, %rcx
jne 0x29198
callq 0x38677
movsd %xmm0, (%rsp)
addsd 0x7cbd4(%rip), %xmm0    # 0xa5da8
xorpd %xmm1, %xmm1
callq 0x39ab2
testl %eax, %eax
je 0x2935d
movl 0xc(%rbx), %eax
cmpl $0x2, %eax
je 0x2922a
cmpl $0x1, %eax
jne 0x292b9
movq (%rbx), %rax
movq 0x18(%rax,%rbp), %r12
cmpq $0x0, (%r12)
je 0x29383
movl 0x8(%r12), %esi
movl 0xc(%r12), %edx
cmpl %r15d, %esi
jne 0x293a3
cmpl %r15d, %edx
je 0x292b9
jmp 0x293a0
movq (%rbx), %rax
movq 0x18(%rax,%rbp), %rbp
movl 0x8(%rbp), %esi
testl %esi, %esi
jle 0x29375
movq 0x10(%rbp), %rdi
callq 0x38677
movsd %xmm0, (%rsp)
addsd 0x7cb55(%rip), %xmm0    # 0xa5da8
xorpd %xmm1, %xmm1
callq 0x39ab2
testl %eax, %eax
je 0x29394
movq (%rbp), %rcx
testq %rcx, %rcx
je 0x293bb
movl 0x8(%rbp), %eax
cmpl %eax, %r14d
jge 0x292b9
movslq %eax, %rsi
leaq (,%r13,2), %rdx
addq %r13, %rdx
leaq (%rcx,%rdx,8), %rdx
addq $0xc, %rdx
subq %rsi, %r13
xorl %ecx, %ecx
cmpq $0x0, -0xc(%rdx)
je 0x29340
cmpl %r15d, -0x4(%rdx)
jne 0x29319
cmpl %r15d, (%rdx)
jne 0x29319
decq %rcx
addq $0x18, %rdx
cmpq %rcx, %r13
jne 0x29294
movl %eax, %r14d
incl %r14d
movl 0x8(%rbx), %esi
cmpl %esi, %r14d
jl 0x2917e
leaq 0x7f54f(%rip), %rdi     # 0xa881e
callq 0x4090
movl $0x1, %ebp
jmp 0x29115
leaq 0x7f520(%rip), %rdi     # 0xa8805
callq 0x4090
jmp 0x29312
leaq 0x7f0c3(%rip), %rdi     # 0xa83b6
movsd (%rsp), %xmm0
movb $0x1, %al
callq 0x4030
jmp 0x29312
leaq 0x7f0d0(%rip), %rdi     # 0xa83d8
movl %r14d, %esi
movb $0x2, %al
callq 0x4030
xorl %ebp, %ebp
jmp 0x29115
subl %ecx, %r14d
movl 0x8(%r12), %esi
movl 0xc(%r12), %edx
leaq 0x7f246(%rip), %rdi     # 0xa8573
xorl %ebp, %ebp
xorl %ecx, %ecx
movl %r14d, %r8d
xorl %eax, %eax
callq 0x4030
jmp 0x29115
subl %ecx, %r14d
leaq 0x7f1e8(%rip), %rdi     # 0xa8532
xorl %ebp, %ebp
xorl %esi, %esi
movl %r14d, %edx
xorl %eax, %eax
callq 0x4030
jmp 0x29115
leaq 0x7f0d4(%rip), %rdi     # 0xa8438
movsd (%rsp), %xmm0
movl %r14d, %esi
movb $0x1, %al
callq 0x4030
jmp 0x29312
leaq 0x7f154(%rip), %rdi     # 0xa84d0
xorl %ebp, %ebp
jmp 0x2910e
leaq 0x7f0e1(%rip), %rdi     # 0xa846b
xorl %ebp, %ebp
movl %r14d, %esi
jmp 0x2910e
leaq 0x7f164(%rip), %rdi     # 0xa84ff
jmp 0x292f3
movl %r15d, %esi
leaq 0x7f0ea(%rip), %rdi     # 0xa8494
xorl %ebp, %ebp
movl %r14d, %ecx
xorl %eax, %eax
callq 0x4030
jmp 0x29115
leaq 0x7f462(%rip), %rdi     # 0xa8824
jmp 0x292e5