// File: /workspace/github_cpp_makefile_star2_O2/icemiliang[P]vot/src/vot/diagram.cc
// Function: vot::Diagram::compute_gradient()
double Diagram::compute_gradient() {
        // Reset cell mass
        for (int i = 0; i < mNumDiracs; i++) {
            mDiracs[i].reset_mass();
        }
        
        // Assign cellIndex to every measure and add mass to that cell
        int cellIndex = -1;
        for (int i = 0; i < mNumEmpiricals; i++) {
            cellIndex = mDiagram->cell_index(mEmpiricals[i].x(),
                                             mEmpiricals[i].y(), 
                                             mEmpiricals[i].z());
            mEmpiricals[i].set_cellIndex(cellIndex);
            mDiracs[cellIndex].add_mass(mEmpiricals[i].mass());
        }

        // Multiple-point check
        if (mFlagDebug) {
            double sumMass = 0;
            double sumH = 0;
            for (int i = 0; i < mNumDiracs; i++) {
                sumMass += mDiracs[i].mass();
                sumH += mHs[i];
            }
            std::cout << "[Debug] Total mass of Diracs: " << sumMass << std::endl;
            std::cout << "[Debug] Total h of Diracs: " << sumH << std::endl;
            getchar();
        }


        // Compute gradient and their norm
        double gradNorm = 0;
        mGradient = Eigen::VectorXd::Zero(mNumDiracs);
        for (int i = 0; i < mNumDiracs; i++) {
            mGradient(i) = mDiracs[i].mass() - mDiracs[i].dirac();
        }
        gradNorm = mGradient.norm();
        if (mFlagVerbose) {
            std::cout << "Gradient norm: " << gradNorm << std::endl;
        }

        return gradNorm;
    }

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movl 0x38(%rdi), %edx
movq 0x20(%rdi), %rax
xorl %ecx, %ecx
testl %edx, %edx
cmovlel %ecx, %edx
imulq $0x30, %rdx, %rdx
cmpq %rcx, %rdx
je 0xe679
andq $0x0, 0x20(%rax,%rcx)
addq $0x30, %rcx
jmp 0xe668
xorl %r14d, %r14d
xorl %r15d, %r15d
movslq 0x3c(%rbx), %rax
cmpq %rax, %r15
jge 0xe6d7
movq (%rbx), %rdi
movq 0x8(%rbx), %rax
movsd (%rax,%r14), %xmm0
movsd 0x8(%rax,%r14), %xmm1
movsd 0x10(%rax,%r14), %xmm2
callq 0x21642
movq 0x8(%rbx), %rcx
movl %eax, 0x20(%rcx,%r14)
cltq
movq 0x20(%rbx), %rdx
movsd 0x18(%rcx,%r14), %xmm0
imulq $0x30, %rax, %rax
addsd 0x20(%rdx,%rax), %xmm0
movsd %xmm0, 0x20(%rdx,%rax)
incq %r15
addq $0x28, %r14
jmp 0xe67f
movl 0x38(%rbx), %eax
cmpb $0x1, 0x69(%rbx)
jne 0xe779
movq 0x20(%rbx), %rcx
xorl %edx, %edx
testl %eax, %eax
cmovlel %edx, %eax
movq 0x50(%rbx), %rsi
addq $0x20, %rcx
xorpd %xmm1, %xmm1
xorpd %xmm0, %xmm0
cmpq %rdx, %rax
je 0xe716
addsd (%rcx), %xmm1
addsd (%rsi,%rdx,8), %xmm0
incq %rdx
addq $0x30, %rcx
jmp 0xe6ff
movq 0x4c87b(%rip), %r14     # 0x5af98
leaq 0x30513(%rip), %rsi     # 0x3ec37
movq %r14, %rdi
movsd %xmm0, (%rsp)
movsd %xmm1, 0x8(%rsp)
callq 0x7360
movq %rax, %rdi
movsd 0x8(%rsp), %xmm0
callq 0x7610
movq %rax, %rdi
callq 0x71c0
leaq 0x30502(%rip), %rsi     # 0x3ec56
movq %r14, %rdi
callq 0x7360
movq %rax, %rdi
movsd (%rsp), %xmm0
callq 0x7610
movq %rax, %rdi
callq 0x71c0
callq 0x74f0
movl 0x38(%rbx), %eax
movslq %eax, %rsi
leaq 0x10(%rsp), %r15
movq %r15, %rdi
callq 0xf574
leaq 0x40(%rbx), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x132d9
pushq $0x20
popq %r12
xorl %r15d, %r15d
movslq 0x38(%rbx), %rax
cmpq %rax, %r15
jge 0xe7db
movq 0x20(%rbx), %rax
movsd (%rax,%r12), %xmm0
subsd -0x8(%rax,%r12), %xmm0
movsd %xmm0, (%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0xf594
movsd (%rsp), %xmm0
movsd %xmm0, (%rax)
incq %r15
addq $0x30, %r12
jmp 0xe79f
movq %r14, %rdi
callq 0xf5ca
cmpb $0x0, 0x68(%rbx)
je 0xe81b
movq 0x4c7a8(%rip), %rdi     # 0x5af98
leaq 0x3047b(%rip), %rsi     # 0x3ec72
movsd %xmm0, (%rsp)
callq 0x7360
movq %rax, %rdi
movsd (%rsp), %xmm0
callq 0x7610
movq %rax, %rdi
callq 0x71c0
movsd (%rsp), %xmm0
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
nop