// File: /workspace/github_cpp_makefile_star2_O1/myudelson[P]hmm-scalable/FitBit.cpp
// Function: FitBit::addL2Penalty(FIT_BIT_VAR, param*, double)
void FitBit::addL2Penalty(enum FIT_BIT_VAR fbv, param* param, NUMBER factor) {
    NPAR i, j, m;
    int matrixOff, rowOff;
    if(param->Cslices==0) return;
    NUMBER C = param->Cw[this->Cslice];
    int nCenters = (param->nS + param->nS*param->nS + param->nS*param->nO); // centers per slice
    switch (fbv) {
        case FBV_PI:
            for(i=0; i<this->nS; i++) {
                // single center of gravity per matrix
//                this->gradPI[i] += factor * L2penalty(C, this->pi[i], param->Ccenters[ this->Cslice * 3 + 0] );
                // center of gravity per parameter of matrix
                this->gradPI[i] += factor * L2penalty(C, this->pi[i], param->Ccenters[ this->Cslice * nCenters + i] );
            }
            break;
        case FBV_A:
            for(i=0; i<this->nS; i++)
                for(j=0; j<this->nS; j++) {
                    // single center of gravity per matrix
//                    this->gradA[i][j] += factor * L2penalty(C, this->A[i][j], param->Ccenters[ this->Cslice * 3 + 1] );
                    // center of gravity per parameter of matrix
                    matrixOff = this->nS;
                    rowOff = i*this->nS;
                    this->gradA[i][j] += factor * L2penalty(C, this->A[i][j], param->Ccenters[ this->Cslice * nCenters + matrixOff + rowOff + j] );
                }
            break;
        case FBV_B:
            for(i=0; i<this->nS; i++)
                for(m=0; m<this->nO; m++) {
                    // single center of gravity per matrix
//                    this->gradB[i][m] += factor * L2penalty(C, this->B[i][m], param->Ccenters[ this->Cslice * 3 + 2] );
                    // center of gravity per parameter of matrix
                    matrixOff = this->nS + this->nS*this->nS;
                    rowOff = i*this->nS;
                    this->gradB[i][m] += factor * L2penalty(C, this->B[i][m], param->Ccenters[ this->Cslice * nCenters + matrixOff + rowOff + m] );
                }
            break;
            
        default:
            fprintf(stderr,"Error, there is no such FitBit variable\n");
            break;
    }
}

// Assembly:
cmpb $0x0, 0x42(%rdx)
je 0xbb54
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rbx
movq %rdi, %r14
movq 0x48(%rdx), %rax
movsbq 0xfa(%rdi), %rcx
movsd (%rax,%rcx,8), %xmm3
movsbl 0x8b8(%rdx), %eax
movsbl 0x8b9(%rdx), %ecx
leal (%rax,%rcx), %ebp
incl %ebp
imull %eax, %ebp
cmpl $0x1, %esi
movsd %xmm0, 0x10(%rsp)
movsd %xmm3, 0x8(%rsp)
je 0xba43
cmpl $0x2, %esi
je 0xbaad
cmpl $0x3, %esi
jne 0xbb55
cmpb $0x0, 0x1(%r14)
jle 0xbb46
movl $0x1, %r15d
xorl %r12d, %r12d
cmpb $0x0, (%r14)
jle 0xba2a
xorl %r13d, %r13d
movsbl 0x1(%r14), %eax
movq 0x20(%r14), %rcx
movq (%rcx,%r12,8), %rcx
movsd (%rcx,%r13,8), %xmm1
movq 0x50(%rbx), %rcx
movsbl 0xfa(%r14), %edx
imull %ebp, %edx
leal (%r15,%rax), %esi
imull %eax, %esi
addl %r13d, %edx
addl %esi, %edx
movslq %edx, %rax
movsd (%rcx,%rax,8), %xmm2
movapd %xmm3, %xmm0
callq 0xa57f
movsd 0x8(%rsp), %xmm3
movq 0x68(%r14), %rax
movq (%rax,%r12,8), %rax
mulsd 0x10(%rsp), %xmm0
addsd (%rax,%r13,8), %xmm0
movsd %xmm0, (%rax,%r13,8)
incq %r13
movsbq (%r14), %rax
cmpq %rax, %r13
jl 0xb9bf
incq %r12
movsbq 0x1(%r14), %rax
incl %r15d
cmpq %rax, %r12
jl 0xb9b6
jmp 0xbb46
cmpb $0x0, 0x1(%r14)
jle 0xbb46
xorl %r15d, %r15d
movslq %ebp, %r12
movq 0x10(%r14), %rax
movsd (%rax,%r15,8), %xmm1
movq 0x50(%rbx), %rax
movsbq 0xfa(%r14), %rcx
imulq %r12, %rcx
addq %r15, %rcx
movsd (%rax,%rcx,8), %xmm2
movapd %xmm3, %xmm0
callq 0xa57f
movsd 0x8(%rsp), %xmm3
movq 0x58(%r14), %rax
mulsd 0x10(%rsp), %xmm0
addsd (%rax,%r15,8), %xmm0
movsd %xmm0, (%rax,%r15,8)
incq %r15
movsbq 0x1(%r14), %rax
cmpq %rax, %r15
jl 0xba54
jmp 0xbb46
cmpb $0x0, 0x1(%r14)
jle 0xbb46
movl $0x1, %r15d
xorl %r12d, %r12d
movb 0x1(%r14), %al
testb %al, %al
jle 0xbb32
xorl %r13d, %r13d
movsbl %al, %eax
movq 0x18(%r14), %rcx
movq (%rcx,%r12,8), %rcx
movsd (%rcx,%r13,8), %xmm1
movq 0x50(%rbx), %rcx
movsbl 0xfa(%r14), %edx
imull %ebp, %edx
imull %r15d, %eax
addl %r13d, %eax
addl %edx, %eax
cltq
movsd (%rcx,%rax,8), %xmm2
movapd %xmm3, %xmm0
callq 0xa57f
movsd 0x8(%rsp), %xmm3
movq 0x60(%r14), %rax
movq (%rax,%r12,8), %rax
mulsd 0x10(%rsp), %xmm0
addsd (%rax,%r13,8), %xmm0
movsd %xmm0, (%rax,%r13,8)
incq %r13
movsbq 0x1(%r14), %rax
cmpq %rax, %r13
jl 0xbacc
incq %r12
movsbq 0x1(%r14), %rax
incl %r15d
cmpq %rax, %r12
jl 0xbac1
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x47ff
jmp 0xbb46