// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3MeshProperty.cpp
// Function: gaps::R3MeshProperty::Entropy() const
RNScalar R3MeshProperty::
Entropy(void) const
{
  // Get useful variables
  const int nbins = 50;
  RNScalar minimum = Percentile(1);
  RNScalar maximum = Percentile(99);
  RNScalar width = maximum - minimum;
  RNScalar scale = nbins / width;

  // Check nvalues
  if (nvalues == 0) return 0;

  // Make a histogram of values
  int count = 0;
  RNScalar bins[nbins];
  for (int i = 0; i < nbins; i++) bins[i] = 0;
  for (int i = 0; i < nvalues; i++) {
    if (values[i] == RN_UNKNOWN) continue;
    RNScalar bin = scale * (values[i] - minimum);
    int bin1 = (int) bin;
    if (bin1 < 0) bin1 = 0;
    if (bin1 >= nbins) bin1 = nbins - 1;
    int bin2 = bin1 + 1;
    if (bin2 >= nbins) bin2 = nbins - 1;
    RNScalar t = bin - bin1;
    if (t < 0) t = 0;
    if (t > 1) t = 1;
    bins[bin1] += 1 - t;
    bins[bin2] += t;
    count++;
  }

  // Normalize histogram 
  if (count > 0) {
    for (int i = 0; i < nbins; i++) {
      bins[i] /= count;
    }
  }

  // Compute entropy
  RNScalar entropy = 0;
  for (int i = 0; i < nbins; i++) {
    entropy -= bins[i] * (log(bins[i]) / log(2.0));
  }

  // Return entropy
  return entropy;
}

// Assembly:
subq $0x228, %rsp            # imm = 0x228
movq %rdi, 0x218(%rsp)
movq 0x218(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movl $0x32, 0x214(%rsp)
movsd 0x128b29(%rip), %xmm0   # 0x196068
callq 0x6d860
movq 0x10(%rsp), %rdi
movsd %xmm0, 0x208(%rsp)
movsd 0x128b36(%rip), %xmm0   # 0x196090
callq 0x6d860
movq 0x10(%rsp), %rax
movsd %xmm0, 0x200(%rsp)
movsd 0x200(%rsp), %xmm0
subsd 0x208(%rsp), %xmm0
movsd %xmm0, 0x1f8(%rsp)
movsd 0x12af30(%rip), %xmm0   # 0x1984c0
divsd 0x1f8(%rsp), %xmm0
movsd %xmm0, 0x1f0(%rsp)
cmpl $0x0, 0x408(%rax)
jne 0x6d5bc
xorps %xmm0, %xmm0
movsd %xmm0, 0x220(%rsp)
jmp 0x6d841
movl $0x0, 0x1ec(%rsp)
movl $0x0, 0x4c(%rsp)
cmpl $0x32, 0x4c(%rsp)
jge 0x6d5f1
movslq 0x4c(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x50(%rsp,%rax,8)
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x6d5cf
movl $0x0, 0x48(%rsp)
movq 0x10(%rsp), %rcx
movl 0x48(%rsp), %eax
cmpl 0x408(%rcx), %eax
jge 0x6d750
movq 0x10(%rsp), %rax
movq 0x410(%rax), %rax
movslq 0x48(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd 0x1289f4(%rip), %xmm1   # 0x196020
ucomisd %xmm1, %xmm0
jne 0x6d639
jp 0x6d639
jmp 0x6d740
movq 0x10(%rsp), %rax
movsd 0x1f0(%rsp), %xmm0
movq 0x410(%rax), %rax
movslq 0x48(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
subsd 0x208(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x40(%rsp)
cvttsd2si 0x40(%rsp), %eax
movl %eax, 0x3c(%rsp)
cmpl $0x0, 0x3c(%rsp)
jge 0x6d684
movl $0x0, 0x3c(%rsp)
cmpl $0x32, 0x3c(%rsp)
jl 0x6d693
movl $0x31, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
cmpl $0x32, 0x38(%rsp)
jl 0x6d6ad
movl $0x31, 0x38(%rsp)
movsd 0x40(%rsp), %xmm0
cvtsi2sdl 0x3c(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x30(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x30(%rsp), %xmm0
jbe 0x6d6d7
xorps %xmm0, %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x30(%rsp), %xmm0
movsd 0x128983(%rip), %xmm1   # 0x196068
ucomisd %xmm1, %xmm0
jbe 0x6d6f9
movsd 0x128975(%rip), %xmm0   # 0x196068
movsd %xmm0, 0x30(%rsp)
movsd 0x128967(%rip), %xmm0   # 0x196068
subsd 0x30(%rsp), %xmm0
movslq 0x3c(%rsp), %rax
addsd 0x50(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x50(%rsp,%rax,8)
movsd 0x30(%rsp), %xmm0
movslq 0x38(%rsp), %rax
addsd 0x50(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x50(%rsp,%rax,8)
movl 0x1ec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1ec(%rsp)
movl 0x48(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x48(%rsp)
jmp 0x6d5f9
cmpl $0x0, 0x1ec(%rsp)
jle 0x6d796
movl $0x0, 0x2c(%rsp)
cmpl $0x32, 0x2c(%rsp)
jge 0x6d794
cvtsi2sdl 0x1ec(%rsp), %xmm1
movslq 0x2c(%rsp), %rax
movsd 0x50(%rsp,%rax,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x50(%rsp,%rax,8)
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x6d762
jmp 0x6d796
xorps %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
cmpl $0x32, 0x1c(%rsp)
jge 0x6d832
movslq 0x1c(%rsp), %rax
movsd 0x50(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x8(%rsp)
movslq 0x1c(%rsp), %rax
movsd 0x50(%rsp,%rax,8), %xmm0
callq 0x22790
movsd %xmm0, (%rsp)
movsd 0x128890(%rip), %xmm0   # 0x196070
callq 0x22790
movsd (%rsp), %xmm2
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
divsd %xmm1, %xmm2
movsd 0x20(%rsp), %xmm1
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x6d7a7
movsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x220(%rsp)
movsd 0x220(%rsp), %xmm0
addq $0x228, %rsp            # imm = 0x228
retq
nopw %cs:(%rax,%rax)