// File: /workspace/github_cpp_makefile_star2_O3/myudelson[P]hmm-scalable/utils.cpp
// Function: doLog10Scale2DGentle(double**, double**, signed char, signed char)
NUMBER doLog10Scale2DGentle(NUMBER **grad, NUMBER **par, NPAR size1, NPAR size2) {
	NPAR i,j;
	NUMBER max_10_scale = 0, candidate, min_delta = 1, max_grad = 0;
	for(i=0; i<size1; i++)
		for(j=0; j<size2; j++) {
			if( fabs(grad[i][j]) < SAFETY ) // 0 gradient
				continue;
            // scale
            if(max_grad < fabs(grad[i][j]))
                max_grad = fabs(grad[i][j]);
			candidate = ceil( log10( fabs(grad[i][j]) ) );
			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]<0)*(1-par[i][j]) + (grad[i][j]>0)*(par[i][j]) +
            ( (fabs(par[i][j])< SAFETY) || (fabs(1-par[i][j])< 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++)
				grad[i][j] = ( 0.95 * min_delta / max_grad) * grad[i][j] / 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 $0x38, %rsp
movl %ecx, %ebx
movq %rdi, %r14
movzbl %dl, %eax
movq %rax, 0x30(%rsp)
movzbl %bl, %r13d
testb %dl, %dl
jle 0x9857
movq %rsi, %r15
movl %edx, 0x2c(%rsp)
movsd 0x2a1f9(%rip), %xmm4    # 0x338f0
xorl %ebp, %ebp
movapd 0x2a22f(%rip), %xmm2    # 0x33930
movsd 0x2a1ef(%rip), %xmm6    # 0x338f8
xorpd %xmm0, %xmm0
xorpd %xmm3, %xmm3
testb %bl, %bl
jle 0x9835
movq (%r14,%rbp,8), %rax
xorl %r12d, %r12d
movapd %xmm0, %xmm1
movapd %xmm4, %xmm5
movapd %xmm3, %xmm7
movsd (%rax,%r12,8), %xmm0
andpd %xmm2, %xmm0
ucomisd %xmm0, %xmm6
jbe 0x974d
movapd %xmm7, %xmm3
movapd %xmm5, %xmm4
movapd %xmm1, %xmm0
jmp 0x981d
movapd %xmm0, %xmm2
maxsd %xmm1, %xmm2
movsd %xmm2, 0x8(%rsp)
movsd %xmm5, 0x10(%rsp)
movsd %xmm7, 0x20(%rsp)
callq 0x4110
callq 0x4090
movsd 0x2a17f(%rip), %xmm6    # 0x338f8
movapd %xmm0, %xmm3
maxsd 0x20(%rsp), %xmm3
movq (%r14,%rbp,8), %rax
movsd (%rax,%r12,8), %xmm0
xorpd %xmm1, %xmm1
cmpltsd %xmm0, %xmm1
cmpltsd 0x2a161(%rip), %xmm0    # 0x33900
movsd 0x2a149(%rip), %xmm5    # 0x338f0
andpd %xmm5, %xmm0
movq (%r15,%rbp,8), %rcx
movsd (%rcx,%r12,8), %xmm4
movapd %xmm5, %xmm2
subsd %xmm4, %xmm2
andpd %xmm5, %xmm1
mulsd %xmm4, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movapd 0x2a15b(%rip), %xmm1    # 0x33930
andpd %xmm1, %xmm4
andpd %xmm1, %xmm2
cmpltsd %xmm6, %xmm2
andpd %xmm5, %xmm2
cmpltsd %xmm6, %xmm4
movapd %xmm4, %xmm1
andnpd %xmm2, %xmm1
andpd %xmm5, %xmm4
movsd 0x10(%rsp), %xmm2
orpd %xmm1, %xmm4
addsd %xmm0, %xmm4
ucomisd %xmm4, %xmm2
ja 0x980f
movapd %xmm2, %xmm4
movsd 0x8(%rsp), %xmm0
movapd 0x2a113(%rip), %xmm2    # 0x33930
incq %r12
movapd %xmm0, %xmm1
movapd %xmm4, %xmm5
movapd %xmm3, %xmm7
cmpq %r12, %r13
jne 0x972c
incq %rbp
cmpq 0x30(%rsp), %rbp
jne 0x9711
mulsd 0x2a0cd(%rip), %xmm4    # 0x33918
movapd %xmm4, 0x10(%rsp)
movl 0x2c(%rsp), %edx
jmp 0x986d
movsd 0x2a0b9(%rip), %xmm0    # 0x33918
movapd %xmm0, 0x10(%rsp)
xorpd %xmm3, %xmm3
xorpd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd %xmm3, 0x20(%rsp)
testb %dl, %dl
setg %bpl
movsd 0x2a089(%rip), %xmm0    # 0x33910
movapd %xmm3, %xmm1
callq 0x4420
movsd 0x20(%rsp), %xmm1
ucomisd 0x2a062(%rip), %xmm1    # 0x33900
movsd 0x8(%rsp), %xmm2
divsd %xmm0, %xmm2
seta %al
testb %bpl, %al
movapd %xmm2, %xmm0
je 0x9923
movapd 0x10(%rsp), %xmm2
divsd %xmm0, %xmm2
xorl %r15d, %r15d
movapd %xmm2, 0x10(%rsp)
testb %bl, %bl
jle 0x9917
movq (%r14,%r15,8), %rax
xorl %r12d, %r12d
movsd (%rax,%r12,8), %xmm0
mulsd %xmm2, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x2a026(%rip), %xmm0    # 0x33910
callq 0x4420
movapd 0x10(%rsp), %xmm2
movsd 0x20(%rsp), %xmm1
movsd 0x8(%rsp), %xmm3
divsd %xmm0, %xmm3
movq (%r14,%r15,8), %rax
movsd %xmm3, (%rax,%r12,8)
incq %r12
cmpq %r12, %r13
jne 0x98d2
incq %r15
cmpq 0x30(%rsp), %r15
jne 0x98c7
jmp 0x9933
movapd 0x10(%rsp), %xmm2
divsd %xmm0, %xmm2
movapd %xmm2, 0x10(%rsp)
movsd 0x29fd5(%rip), %xmm0    # 0x33910
callq 0x4420
movapd 0x10(%rsp), %xmm1
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq