// File: 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
movq %rsp, %rbp
subq $0x90, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb %al, -0x11(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x20(%rbp)
movsd 0x45450(%rip), %xmm0    # 0x4fa08
movsd %xmm0, -0x30(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x38(%rbp)
movb $0x0, -0x12(%rbp)
movsbl -0x12(%rbp), %eax
movsbl -0x11(%rbp), %ecx
cmpl %ecx, %eax
jge 0xa796
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
movaps 0x454a2(%rip), %xmm0    # 0x4fa90
pand %xmm0, %xmm1
movsd 0x45416(%rip), %xmm0    # 0x4fa10
ucomisd %xmm1, %xmm0
jbe 0xa605
jmp 0xa789
movsd -0x38(%rbp), %xmm1
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movaps 0x45471(%rip), %xmm2    # 0x4fa90
pand %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jbe 0xa647
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movaps 0x45452(%rip), %xmm1    # 0x4fa90
pand %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movaps 0x45434(%rip), %xmm1    # 0x4fa90
pand %xmm1, %xmm0
callq 0x5140
callq 0x50a0
movsd %xmm0, -0x28(%rbp)
movsd -0x28(%rbp), %xmm0
ucomisd -0x20(%rbp), %xmm0
jbe 0xa685
movsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x20(%rbp)
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
xorps %xmm0, %xmm0
ucomisd (%rax,%rcx,8), %xmm0
seta %al
andb $0x1, %al
movzbl %al, %eax
cvtsi2sd %eax, %xmm0
movq -0x10(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd 0x45355(%rip), %xmm2    # 0x4fa08
subsd (%rax,%rcx,8), %xmm2
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
xorps %xmm3, %xmm3
ucomisd %xmm3, %xmm1
seta %al
andb $0x1, %al
movzbl %al, %eax
cvtsi2sd %eax, %xmm1
movq -0x10(%rbp), %rax
movsbq -0x12(%rbp), %rcx
mulsd (%rax,%rcx,8), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movq -0x10(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
movaps 0x45387(%rip), %xmm0    # 0x4fa90
pand %xmm0, %xmm1
movb $0x1, %al
movsd 0x452f9(%rip), %xmm0    # 0x4fa10
ucomisd %xmm1, %xmm0
movb %al, -0x49(%rbp)
ja 0xa753
movq -0x10(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd 0x452d7(%rip), %xmm1    # 0x4fa08
subsd (%rax,%rcx,8), %xmm1
movaps 0x45353(%rip), %xmm0    # 0x4fa90
pand %xmm0, %xmm1
movsd 0x452c7(%rip), %xmm0    # 0x4fa10
ucomisd %xmm1, %xmm0
seta %al
movb %al, -0x49(%rbp)
movsd -0x58(%rbp), %xmm0
movb -0x49(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cvtsi2sd %eax, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x28(%rbp), %xmm1
movsd -0x30(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xa787
movsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
jmp 0xa789
movb -0x12(%rbp), %al
addb $0x1, %al
movb %al, -0x12(%rbp)
jmp 0xa5c9
movsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x60(%rbp)
movsd -0x20(%rbp), %xmm0
movl $0xa, %edi
callq 0xc7b0
movaps %xmm0, %xmm1
movsd -0x60(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x38(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xa7d2
jp 0xa7d2
jmp 0xa80b
movsd 0x45256(%rip), %xmm0    # 0x4fa30
mulsd -0x30(%rbp), %xmm0
divsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
movsd -0x20(%rbp), %xmm0
movl $0xa, %edi
callq 0xc7b0
movaps %xmm0, %xmm1
movsd -0x70(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
jmp 0xa81a
movsd 0x451f5(%rip), %xmm0    # 0x4fa08
movsd %xmm0, -0x68(%rbp)
jmp 0xa81a
movsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x40(%rbp)
movsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x78(%rbp)
callq 0xc7e0
movaps %xmm0, %xmm1
movsd -0x78(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jne 0xa845
jp 0xa845
jmp 0xa870
movsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
callq 0xc7e0
movaps %xmm0, %xmm2
movsd -0x80(%rbp), %xmm0
movsd 0x451b4(%rip), %xmm1    # 0x4fa18
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jne 0xa888
jp 0xa888
movq 0x50761(%rip), %rax     # 0x5afd8
movq (%rax), %rdi
leaq 0x45320(%rip), %rsi     # 0x4fba1
movb $0x0, %al
callq 0x5440
movsd -0x20(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa984
movb $0x0, -0x12(%rbp)
movsbl -0x12(%rbp), %eax
movsbl -0x11(%rbp), %ecx
cmpl %ecx, %eax
jge 0xa982
movsd 0x4517a(%rip), %xmm0    # 0x4fa30
mulsd -0x30(%rbp), %xmm0
divsd -0x38(%rbp), %xmm0
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0x20(%rbp), %xmm0
movl $0xa, %edi
callq 0xc7b0
movaps %xmm0, %xmm1
movsd -0x88(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
movsd -0x48(%rbp), %xmm0
ucomisd -0x48(%rbp), %xmm0
jne 0xa909
jp 0xa909
jmp 0xa921
movq 0x506c8(%rip), %rax     # 0x5afd8
movq (%rax), %rdi
leaq 0x45229(%rip), %rsi     # 0x4fb43
movb $0x0, %al
callq 0x5440
movsd 0x45107(%rip), %xmm0    # 0x4fa30
mulsd -0x30(%rbp), %xmm0
divsd -0x38(%rbp), %xmm0
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x20(%rbp), %xmm0
movl $0xa, %edi
callq 0xc7b0
movaps %xmm0, %xmm1
movsd -0x90(%rbp), %xmm0
divsd %xmm1, %xmm0
movq -0x8(%rbp), %rax
movsbq -0x12(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movb -0x12(%rbp), %al
addb $0x1, %al
movb %al, -0x12(%rbp)
jmp 0xa89e
jmp 0xa984
movsd -0x40(%rbp), %xmm0
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)