// File: /workspace/github_cpp_makefile_star2_O1/myudelson[P]hmm-scalable/utils.cpp
// Function: doLog10Scale1DGentle(double*, double*, signed char)
NUMBER doLog10Scale1DGentle(NUMBER *grad, NUMBER *par, NPAR size) {
	NPAR i;
	NUMBER max_10_scale = 0, candidate, min_delta = 1, max_grad = 0, scale;
	for(i=0; i<size; i++) {
		if( fabs(grad[i]) < SAFETY ) // 0 gradient
			continue;
        // scale
        if(max_grad < fabs(grad[i]))
            max_grad = fabs(grad[i]);
		candidate = ceil( log10( fabs(grad[i]) ) );
		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]<0)*(1-par[i]) + (grad[i]>0)*(par[i]) +
        ( (fabs(par[i])< SAFETY) || (fabs(1-par[i])< 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);
    
    scale = (max_grad!=0) ? ( 0.95 * min_delta / max_grad ) / pow(10, max_10_scale) : 1;
    if(scale==std::numeric_limits<double>::infinity() || scale==(-1*std::numeric_limits<double>::infinity()) ) {
        fprintf(stderr,"WARNING! scale is Infinite\n");
    }
    
    NUMBER v;
    if(max_10_scale > 0) {
        for(i=0; i<size; i++) {
            
            v = ( 0.95 * min_delta / max_grad) * grad[i] / pow(10, max_10_scale);
            if(v!=v) {
                fprintf(stderr,"WARNING! NaN to be set!\n");
            }
            
            grad[i] = ( 0.95 * min_delta / max_grad) * grad[i] / pow(10, max_10_scale);
        }
    }
    return scale; //( 0.95 * min_delta / max_grad ) / pow(10, max_10_scale);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x20, %rsp
movl %edx, %ebp
movq %rdi, %rbx
movzbl %bpl, %r15d
testb %bpl, %bpl
jle 0x94f9
movq %rsi, %r14
movsd 0x2b511(%rip), %xmm2    # 0x348f0
xorl %r12d, %r12d
movapd 0x2b546(%rip), %xmm3    # 0x34930
movsd 0x2b506(%rip), %xmm6    # 0x348f8
xorpd %xmm1, %xmm1
xorpd %xmm4, %xmm4
movsd (%rbx,%r12,8), %xmm0
andpd %xmm3, %xmm0
ucomisd %xmm0, %xmm6
ja 0x94d8
movapd %xmm0, %xmm3
maxsd %xmm4, %xmm3
movsd %xmm3, (%rsp)
movsd %xmm2, 0x8(%rsp)
movsd %xmm1, 0x10(%rsp)
callq 0x4110
callq 0x4090
movsd 0x2b4bf(%rip), %xmm6    # 0x348f8
maxsd 0x10(%rsp), %xmm0
movsd (%rbx,%r12,8), %xmm1
xorpd %xmm2, %xmm2
cmpltsd %xmm1, %xmm2
movapd %xmm1, %xmm3
cmpltsd 0x2b4a5(%rip), %xmm3    # 0x34900
movsd 0x2b48d(%rip), %xmm5    # 0x348f0
andpd %xmm5, %xmm3
movsd (%r14,%r12,8), %xmm1
movapd %xmm5, %xmm4
subsd %xmm1, %xmm4
andpd %xmm5, %xmm2
mulsd %xmm1, %xmm2
mulsd %xmm4, %xmm3
addsd %xmm2, %xmm3
movapd 0x2b4a3(%rip), %xmm2    # 0x34930
andpd %xmm2, %xmm1
andpd %xmm2, %xmm4
cmpltsd %xmm6, %xmm4
andpd %xmm5, %xmm4
cmpltsd %xmm6, %xmm1
movapd %xmm1, %xmm2
andnpd %xmm4, %xmm2
andpd %xmm5, %xmm1
orpd %xmm2, %xmm1
movsd 0x8(%rsp), %xmm2
addsd %xmm3, %xmm1
ucomisd %xmm1, %xmm2
jbe 0x94c7
movapd %xmm1, %xmm2
movsd (%rsp), %xmm4
movapd %xmm0, %xmm1
movapd 0x2b458(%rip), %xmm3    # 0x34930
incq %r12
cmpq %r12, %r15
jne 0x93fa
mulsd 0x2b42c(%rip), %xmm2    # 0x34918
movsd %xmm2, 0x8(%rsp)
movsd %xmm4, (%rsp)
jmp 0x9514
movsd 0x2b417(%rip), %xmm0    # 0x34918
movsd %xmm0, 0x8(%rsp)
xorpd %xmm0, %xmm0
movsd %xmm0, (%rsp)
xorpd %xmm1, %xmm1
movsd 0x2b3f4(%rip), %xmm0    # 0x34910
movsd %xmm1, 0x10(%rsp)
callq 0x4420
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
ucomisd 0x2b3c8(%rip), %xmm1    # 0x34900
movsd 0x8(%rsp), %xmm2
divsd %xmm1, %xmm2
movsd %xmm2, 0x8(%rsp)
jne 0x954c
jnp 0x956f
movsd 0x2b3bc(%rip), %xmm0    # 0x34910
movsd 0x10(%rsp), %xmm1
callq 0x4420
movsd 0x8(%rsp), %xmm2
movapd %xmm2, %xmm1
divsd %xmm0, %xmm1
jmp 0x9577
movsd 0x2b379(%rip), %xmm1    # 0x348f0
movsd %xmm1, 0x18(%rsp)
movq %xmm1, %rax
btrq $0x3f, %rax
movabsq $0x7ff0000000000000, %rcx # imm = 0x7FF0000000000000
cmpq %rcx, %rax
je 0x9652
xorpd %xmm0, %xmm0
movsd 0x10(%rsp), %xmm1
ucomisd %xmm0, %xmm1
setbe %al
testb %bpl, %bpl
setle %cl
orb %al, %cl
jne 0x963f
xorl %r14d, %r14d
movsd 0x2b34c(%rip), %xmm0    # 0x34910
movsd (%rbx,%r14,8), %xmm3
mulsd %xmm2, %xmm3
movsd %xmm3, (%rsp)
callq 0x4420
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
ucomisd %xmm1, %xmm1
jp 0x9638
movsd (%rbx,%r14,8), %xmm0
mulsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rsp)
movsd 0x2b310(%rip), %xmm0    # 0x34910
movsd 0x10(%rsp), %xmm1
callq 0x4420
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rbx,%r14,8)
incq %r14
cmpq %r14, %r15
movsd 0x8(%rsp), %xmm2
movsd 0x10(%rsp), %xmm1
movsd 0x2b2dc(%rip), %xmm0    # 0x34910
jne 0x95c4
jmp 0x963f
callq 0x47c7
jmp 0x95e7
movsd 0x18(%rsp), %xmm0
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
callq 0x47ab
movsd 0x8(%rsp), %xmm2
jmp 0x959a