// File: /workspace/github_cpp_makefile_star2_O2/myudelson[P]hmm-scalable/utils.cpp
// Function: doLog10Scale3DGentle(double***, double***, signed char, signed char, signed char)
NUMBER doLog10Scale3DGentle(NUMBER ***grad, NUMBER ***par, NPAR size1, NPAR size2, NPAR size3) {
    NPAR i,j,k;
    NUMBER max_10_scale = 0, candidate, min_delta = 1, max_grad = 0;
    for(i=0; i<size1; i++)
        for(j=0; j<size2; j++)
            for(k=0; k<size3; k++) {
                if( fabs(grad[i][j][k]) < SAFETY ) // 0 gradient
                    continue;
                // scale
                if(max_grad < fabs(grad[i][j][k]))
                    max_grad = fabs(grad[i][j][k]);
                candidate = ceil( log10( fabs(grad[i][j][k]) ) );
                if(candidate > max_10_scale)
                    max_10_scale = candidate;
                // delta: if grad<0 - distance to 1, if grad>0 - distance to 0
                candidate = (grad[i][j][k]<0)*(1-par[i][j][k]) + (grad[i][j][k]>0)*(par[i][j][k]) +
                ( (fabs(par[i][j][k])< SAFETY) || (fabs(1-par[i][j][k])< SAFETY) ); // these terms are there to avoid already extreme 0, 1 values
                if( candidate < min_delta)
                    min_delta = candidate;
            }
    max_grad = max_grad / pow(10, max_10_scale);
    if(max_10_scale >0 )
        for(i=0; i<size1; i++)
            for(j=0; j<size2; j++)
                for(k=0; k<size3; k++)
                    grad[i][j][k] = ( 0.95 * min_delta / max_grad) * grad[i][j][k] / pow(10, max_10_scale);
    return ( 0.95 * min_delta / max_grad ) / pow(10, max_10_scale);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
xorl %ebp, %ebp
testb %r8b, %r8b
cmovlel %ebp, %r8d
testb %cl, %cl
cmovlel %ebp, %ecx
movq %rsi, %r14
testb %dl, %dl
cmovlel %ebp, %edx
movq %rdi, %rbx
movslq %edx, %rax
movq %rax, 0x18(%rsp)
movslq %ecx, %rax
movq %rax, 0x20(%rsp)
movzbl %r8b, %r13d
movsd 0x25617(%rip), %xmm2    # 0x2c8f0
movapd 0x2564f(%rip), %xmm3    # 0x2c930
movsd 0x2560f(%rip), %xmm6    # 0x2c8f8
xorpd %xmm1, %xmm1
xorpd %xmm4, %xmm4
cmpq 0x18(%rsp), %rbp
je 0x742d
xorl %r15d, %r15d
cmpq 0x20(%rsp), %r15
je 0x7425
xorl %r12d, %r12d
cmpq %r12, %r13
je 0x741d
movq (%rbx,%rbp,8), %rax
movq (%rax,%r15,8), %rax
movsd (%rax,%r12,8), %xmm0
andpd %xmm3, %xmm0
ucomisd %xmm0, %xmm6
jbe 0x733b
movapd %xmm1, %xmm0
movapd %xmm2, %xmm5
jmp 0x740d
movapd %xmm0, %xmm3
maxsd %xmm4, %xmm3
movsd %xmm3, (%rsp)
movsd %xmm2, 0x8(%rsp)
movsd %xmm1, 0x10(%rsp)
callq 0x4100
callq 0x4090
movsd 0x25592(%rip), %xmm6    # 0x2c8f8
maxsd 0x10(%rsp), %xmm0
movq (%rbx,%rbp,8), %rax
movq (%rax,%r15,8), %rax
movsd (%rax,%r12,8), %xmm2
xorpd %xmm3, %xmm3
cmpltsd %xmm2, %xmm3
cmpltsd 0x25574(%rip), %xmm2    # 0x2c900
movsd 0x2555c(%rip), %xmm1    # 0x2c8f0
andpd %xmm1, %xmm2
movq (%r14,%rbp,8), %rax
movq (%rax,%r15,8), %rax
movsd (%rax,%r12,8), %xmm5
movapd %xmm1, %xmm4
subsd %xmm5, %xmm4
andpd %xmm1, %xmm3
mulsd %xmm5, %xmm3
mulsd %xmm4, %xmm2
addsd %xmm3, %xmm2
movapd 0x2556a(%rip), %xmm3    # 0x2c930
andpd %xmm3, %xmm5
andpd %xmm3, %xmm4
cmpltsd %xmm6, %xmm4
andpd %xmm1, %xmm4
cmpltsd %xmm6, %xmm5
movapd %xmm5, %xmm3
andnpd %xmm4, %xmm3
andpd %xmm1, %xmm5
orpd %xmm3, %xmm5
addsd %xmm2, %xmm5
movsd 0x8(%rsp), %xmm2
ucomisd %xmm5, %xmm2
ja 0x7400
movapd %xmm2, %xmm5
movapd 0x25528(%rip), %xmm3    # 0x2c930
movsd (%rsp), %xmm4
incq %r12
movapd %xmm0, %xmm1
movapd %xmm5, %xmm2
jmp 0x730d
incq %r15
jmp 0x72ff
incq %rbp
jmp 0x72f1
movsd 0x254db(%rip), %xmm0    # 0x2c910
movsd %xmm2, 0x8(%rsp)
movsd %xmm1, 0x10(%rsp)
movsd %xmm4, (%rsp)
callq 0x4440
movsd 0x10(%rsp), %xmm1
movsd 0x8(%rsp), %xmm2
xorpd %xmm3, %xmm3
ucomisd %xmm3, %xmm1
movsd (%rsp), %xmm3
divsd %xmm0, %xmm3
mulsd 0x254a8(%rip), %xmm2    # 0x2c918
divsd %xmm3, %xmm2
movsd %xmm2, 0x8(%rsp)
jbe 0x74ee
xorl %r14d, %r14d
cmpq 0x18(%rsp), %r14
je 0x74ee
xorl %r15d, %r15d
cmpq 0x20(%rsp), %r15
je 0x74e9
xorl %r12d, %r12d
cmpq %r12, %r13
je 0x74e4
movq (%rbx,%r14,8), %rax
movq (%rax,%r15,8), %rax
movsd (%rax,%r12,8), %xmm0
mulsd %xmm2, %xmm0
movsd %xmm0, (%rsp)
movsd 0x25459(%rip), %xmm0    # 0x2c910
callq 0x4440
movsd 0x10(%rsp), %xmm1
movsd 0x8(%rsp), %xmm2
movsd (%rsp), %xmm3
divsd %xmm0, %xmm3
movq (%rbx,%r14,8), %rax
movq (%rax,%r15,8), %rax
movsd %xmm3, (%rax,%r12,8)
incq %r12
jmp 0x7493
incq %r15
jmp 0x7489
incq %r14
jmp 0x747f
movsd 0x2541a(%rip), %xmm0    # 0x2c910
callq 0x4440
movsd 0x8(%rsp), %xmm1
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq