// File: mouda[P]LTE_random_access-simulate/alglibinternal.cpp
// Function: alglib_impl::generatereflection(alglib_impl::ae_vector*, long, double*, alglib_impl::ae_state*)
void generatereflection(/* Real    */ ae_vector* x,
     ae_int_t n,
     double* tau,
     ae_state *_state)
{
    ae_int_t j;
    double alpha;
    double xnorm;
    double v;
    double beta;
    double mx;
    double s;

    *tau = 0;

    if( n<=1 )
    {
        *tau = 0;
        return;
    }
    
    /*
     * Scale if needed (to avoid overflow/underflow during intermediate
     * calculations).
     */
    mx = 0;
    for(j=1; j<=n; j++)
    {
        mx = ae_maxreal(ae_fabs(x->ptr.p_double[j], _state), mx, _state);
    }
    s = 1;
    if( ae_fp_neq(mx,0) )
    {
        if( ae_fp_less_eq(mx,ae_minrealnumber/ae_machineepsilon) )
        {
            s = ae_minrealnumber/ae_machineepsilon;
            v = 1/s;
            ae_v_muld(&x->ptr.p_double[1], 1, ae_v_len(1,n), v);
            mx = mx*v;
        }
        else
        {
            if( ae_fp_greater_eq(mx,ae_maxrealnumber*ae_machineepsilon) )
            {
                s = ae_maxrealnumber*ae_machineepsilon;
                v = 1/s;
                ae_v_muld(&x->ptr.p_double[1], 1, ae_v_len(1,n), v);
                mx = mx*v;
            }
        }
    }
    
    /*
     * XNORM = DNRM2( N-1, X, INCX )
     */
    alpha = x->ptr.p_double[1];
    xnorm = 0;
    if( ae_fp_neq(mx,0) )
    {
        for(j=2; j<=n; j++)
        {
            xnorm = xnorm+ae_sqr(x->ptr.p_double[j]/mx, _state);
        }
        xnorm = ae_sqrt(xnorm, _state)*mx;
    }
    if( ae_fp_eq(xnorm,0) )
    {
        
        /*
         * H  =  I
         */
        *tau = 0;
        x->ptr.p_double[1] = x->ptr.p_double[1]*s;
        return;
    }
    
    /*
     * general case
     */
    mx = ae_maxreal(ae_fabs(alpha, _state), ae_fabs(xnorm, _state), _state);
    beta = -mx*ae_sqrt(ae_sqr(alpha/mx, _state)+ae_sqr(xnorm/mx, _state), _state);
    if( ae_fp_less(alpha,0) )
    {
        beta = -beta;
    }
    *tau = (beta-alpha)/beta;
    v = 1/(alpha-beta);
    ae_v_muld(&x->ptr.p_double[2], 1, ae_v_len(2,n), v);
    x->ptr.p_double[1] = beta;
    
    /*
     * Scale back outputs
     */
    x->ptr.p_double[1] = x->ptr.p_double[1]*s;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x18(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
cmpq $0x1, -0x10(%rbp)
jg 0x2579d
movq -0x18(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
jmp 0x25b70
xorps %xmm0, %xmm0
movsd %xmm0, -0x50(%rbp)
movq $0x1, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x10(%rbp), %rax
jg 0x257f2
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x28(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x20(%rbp), %rdi
callq 0x3c820
movsd -0x50(%rbp), %xmm1
movq -0x20(%rbp), %rdi
callq 0x3ca70
movsd %xmm0, -0x50(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x257ad
movsd 0x2f80e(%rip), %xmm0    # 0x55008
movsd %xmm0, -0x58(%rbp)
movsd -0x50(%rbp), %xmm0
xorps %xmm1, %xmm1
callq 0x3c410
testb $0x1, %al
jne 0x25815
jmp 0x2590f
movsd -0x50(%rbp), %xmm0
movsd 0x32026(%rip), %xmm1    # 0x57848
callq 0x3c480
testb $0x1, %al
jne 0x2582d
jmp 0x25891
movsd 0x32013(%rip), %xmm0    # 0x57848
movsd %xmm0, -0x58(%rbp)
movsd 0x2f7c6(%rip), %xmm0    # 0x55008
divsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
addq $0x8, %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rsi
movl $0x1, %edi
callq 0x42370
movq -0x60(%rbp), %rdi
movq %rax, %rdx
movsd -0x40(%rbp), %xmm0
movl $0x1, %esi
callq 0x422d0
movsd -0x50(%rbp), %xmm0
mulsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
jmp 0x2590d
movsd -0x50(%rbp), %xmm0
movsd 0x31fb2(%rip), %xmm1    # 0x57850
callq 0x3c500
testb $0x1, %al
jne 0x258a9
jmp 0x2590b
movsd 0x31f9f(%rip), %xmm0    # 0x57850
movsd %xmm0, -0x58(%rbp)
movsd 0x2f74a(%rip), %xmm0    # 0x55008
divsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
addq $0x8, %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rsi
movl $0x1, %edi
callq 0x42370
movq -0x68(%rbp), %rdi
movq %rax, %rdx
movsd -0x40(%rbp), %xmm0
movl $0x1, %esi
callq 0x422d0
movsd -0x50(%rbp), %xmm0
mulsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
jmp 0x2590d
jmp 0x2590f
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x50(%rbp), %xmm0
xorps %xmm1, %xmm1
callq 0x3c410
testb $0x1, %al
jne 0x2593c
jmp 0x259ae
movq $0x2, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x10(%rbp), %rax
jg 0x25996
movsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x28(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
divsd -0x50(%rbp), %xmm0
movq -0x20(%rbp), %rdi
callq 0x3c870
movaps %xmm0, %xmm1
movsd -0x70(%rbp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x25944
movsd -0x38(%rbp), %xmm0
movq -0x20(%rbp), %rdi
callq 0x3c890
mulsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x38(%rbp), %xmm0
xorps %xmm1, %xmm1
callq 0x3c3d0
testb $0x1, %al
jne 0x259c1
jmp 0x259f0
movq -0x18(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movsd 0x8(%rax), %xmm0
mulsd -0x58(%rbp), %xmm0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movsd %xmm0, 0x8(%rax)
jmp 0x25b70
movsd -0x30(%rbp), %xmm0
movq -0x20(%rbp), %rdi
callq 0x3c820
movsd %xmm0, -0x88(%rbp)
movsd -0x38(%rbp), %xmm0
movq -0x20(%rbp), %rdi
callq 0x3c820
movaps %xmm0, %xmm1
movsd -0x88(%rbp), %xmm0
movq -0x20(%rbp), %rdi
callq 0x3ca70
movsd %xmm0, -0x50(%rbp)
movsd -0x50(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x78(%rbp)
movsd -0x30(%rbp), %xmm0
divsd -0x50(%rbp), %xmm0
movq -0x20(%rbp), %rdi
callq 0x3c870
movsd %xmm0, -0x80(%rbp)
movsd -0x38(%rbp), %xmm0
divsd -0x50(%rbp), %xmm0
movq -0x20(%rbp), %rdi
callq 0x3c870
movaps %xmm0, %xmm1
movsd -0x80(%rbp), %xmm0
addsd %xmm1, %xmm0
movq -0x20(%rbp), %rdi
callq 0x3c890
movaps %xmm0, %xmm1
movsd -0x78(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
movsd -0x30(%rbp), %xmm0
xorps %xmm1, %xmm1
callq 0x3c440
testb $0x1, %al
jne 0x25ab2
jmp 0x25ad3
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x48(%rbp)
movsd -0x48(%rbp), %xmm0
subsd -0x30(%rbp), %xmm0
divsd -0x48(%rbp), %xmm0
movq -0x18(%rbp), %rax
movsd %xmm0, (%rax)
movsd -0x30(%rbp), %xmm1
subsd -0x48(%rbp), %xmm1
movsd 0x2f50c(%rip), %xmm0    # 0x55008
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
addq $0x10, %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rsi
movl $0x2, %edi
callq 0x42370
movq -0x90(%rbp), %rdi
movq %rax, %rdx
movsd -0x40(%rbp), %xmm0
movl $0x1, %esi
callq 0x422d0
movsd -0x48(%rbp), %xmm0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movsd %xmm0, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movsd 0x8(%rax), %xmm0
mulsd -0x58(%rbp), %xmm0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movsd %xmm0, 0x8(%rax)
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax)