// File: /workspace/github_cpp_makefile_star2_O3/mouda[P]LTE_random_access-simulate/specialfunctions.cpp
// Function: alglib_impl::lngamma(double, double*, alglib_impl::ae_state*)
double lngamma(double x, double* sgngam, ae_state *_state)
{
#ifndef ALGLIB_INTERCEPTS_SPECFUNCS
    double a;
    double b;
    double c;
    double p;
    double q;
    double u;
    double w;
    double z;
    ae_int_t i;
    double logpi;
    double ls2pi;
    double tmp;
    double result;

    *sgngam = 0;

    *sgngam = 1;
    logpi = 1.14472988584940017414;
    ls2pi = 0.91893853320467274178;
    if( ae_fp_less(x,-34.0) )
    {
        q = -x;
        w = lngamma(q, &tmp, _state);
        p = ae_ifloor(q, _state);
        i = ae_round(p, _state);
        if( i%2==0 )
        {
            *sgngam = -1;
        }
        else
        {
            *sgngam = 1;
        }
        z = q-p;
        if( ae_fp_greater(z,0.5) )
        {
            p = p+1;
            z = p-q;
        }
        z = q*ae_sin(ae_pi*z, _state);
        result = logpi-ae_log(z, _state)-w;
        return result;
    }
    if( ae_fp_less(x,13) )
    {
        z = 1;
        p = 0;
        u = x;
        while(ae_fp_greater_eq(u,3))
        {
            p = p-1;
            u = x+p;
            z = z*u;
        }
        while(ae_fp_less(u,2))
        {
            z = z/u;
            p = p+1;
            u = x+p;
        }
        if( ae_fp_less(z,0) )
        {
            *sgngam = -1;
            z = -z;
        }
        else
        {
            *sgngam = 1;
        }
        if( ae_fp_eq(u,2) )
        {
            result = ae_log(z, _state);
            return result;
        }
        p = p-2;
        x = x+p;
        b = -1378.25152569120859100;
        b = -38801.6315134637840924+x*b;
        b = -331612.992738871184744+x*b;
        b = -1162370.97492762307383+x*b;
        b = -1721737.00820839662146+x*b;
        b = -853555.664245765465627+x*b;
        c = 1;
        c = -351.815701436523470549+x*c;
        c = -17064.2106651881159223+x*c;
        c = -220528.590553854454839+x*c;
        c = -1139334.44367982507207+x*c;
        c = -2532523.07177582951285+x*c;
        c = -2018891.41433532773231+x*c;
        p = x*b/c;
        result = ae_log(z, _state)+p;
        return result;
    }
    q = (x-0.5)*ae_log(x, _state)-x+ls2pi;
    if( ae_fp_greater(x,100000000) )
    {
        result = q;
        return result;
    }
    p = 1/(x*x);
    if( ae_fp_greater_eq(x,1000.0) )
    {
        q = q+((7.9365079365079365079365*0.0001*p-2.7777777777777777777778*0.001)*p+0.0833333333333333333333)/x;
    }
    else
    {
        a = 8.11614167470508450300*0.0001;
        a = -5.95061904284301438324*0.0001+p*a;
        a = 7.93650340457716943945*0.0001+p*a;
        a = -2.77777777730099687205*0.001+p*a;
        a = 8.33333333333331927722*0.01+p*a;
        q = q+a/x;
    }
    result = q;
    return result;
#else
    return _ialglib_i_lngamma(x, sgngam);
#endif
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x48, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, (%rdi)
movsd 0x2e5f6(%rip), %xmm1    # 0x33498
movaps %xmm0, 0x20(%rsp)
callq 0x25bb9
testb %al, %al
je 0x4f43
movaps 0x2e2f5(%rip), %xmm0    # 0x331b0
xorps 0x20(%rsp), %xmm0
movaps %xmm0, 0x10(%rsp)
leaq 0x40(%rsp), %rdi
movq %rbx, %rsi
callq 0x4e80
movsd %xmm0, 0x8(%rsp)
movaps 0x10(%rsp), %xmm0
movq %rbx, %rdi
callq 0x25e8e
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movsd %xmm0, (%rsp)
movq %rbx, %rdi
callq 0x25e79
xorl %ecx, %ecx
testb $0x1, %al
sete %cl
leaq 0x2fd18(%rip), %rax     # 0x34c20
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%r14)
movapd 0x10(%rsp), %xmm0
subsd (%rsp), %xmm0
movsd 0x2e563(%rip), %xmm1    # 0x33488
movapd %xmm0, 0x30(%rsp)
callq 0x25bf9
testb %al, %al
jne 0x4fcc
movapd 0x30(%rsp), %xmm0
jmp 0x4fdf
movsd 0x2e555(%rip), %xmm1    # 0x334a0
movaps 0x20(%rsp), %xmm0
callq 0x25bb9
testb %al, %al
movapd 0x20(%rsp), %xmm0
je 0x501b
movsd 0x2e27d(%rip), %xmm1    # 0x331e8
callq 0x25c15
testb %al, %al
je 0x5074
movsd 0x2e260(%rip), %xmm1    # 0x331e0
xorpd %xmm2, %xmm2
addsd 0x2e27c(%rip), %xmm2    # 0x33208
movsd %xmm2, (%rsp)
movapd %xmm2, %xmm0
addsd 0x20(%rsp), %xmm0
mulsd %xmm0, %xmm1
movapd %xmm1, 0x10(%rsp)
movsd %xmm0, 0x8(%rsp)
movsd 0x2e235(%rip), %xmm1    # 0x331e8
callq 0x25c15
movsd (%rsp), %xmm2
movapd 0x10(%rsp), %xmm1
testb %al, %al
jne 0x4f84
jmp 0x508c
movsd (%rsp), %xmm0
addsd 0x2e207(%rip), %xmm0    # 0x331e0
addsd 0x20(%rsp), %xmm0
mulsd 0x2e4a9(%rip), %xmm0    # 0x33490
movq %rbx, %rdi
callq 0x25f5f
mulsd 0x10(%rsp), %xmm0
movq %rbx, %rdi
callq 0x25f91
movsd 0x2e563(%rip), %xmm1    # 0x33568
subsd %xmm0, %xmm1
subsd 0x8(%rsp), %xmm1
movapd %xmm1, %xmm0
addq $0x48, %rsp
popq %rbx
popq %r14
retq
movsd 0x2e485(%rip), %xmm1    # 0x334a8
addsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
movq %rbx, %rdi
callq 0x25f91
mulsd 0x10(%rsp), %xmm0
movapd 0x20(%rsp), %xmm2
subsd %xmm2, %xmm0
addsd 0x2e463(%rip), %xmm0    # 0x334b0
movsd %xmm0, 0x10(%rsp)
movsd 0x2e45d(%rip), %xmm1    # 0x334b8
movapd %xmm2, %xmm0
callq 0x25bf9
testb %al, %al
je 0x510e
movsd 0x10(%rsp), %xmm1
jmp 0x500f
xorpd %xmm2, %xmm2
movsd 0x2e160(%rip), %xmm1    # 0x331e0
movapd 0x20(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd %xmm2, (%rsp)
movapd %xmm1, 0x10(%rsp)
movsd 0x2e361(%rip), %xmm1    # 0x33400
movsd 0x8(%rsp), %xmm0
callq 0x25bb9
testb %al, %al
je 0x516c
movapd 0x10(%rsp), %xmm0
movsd (%rsp), %xmm1
movsd 0x8(%rsp), %xmm2
divsd %xmm2, %xmm0
movapd %xmm0, 0x10(%rsp)
addsd 0x2e10b(%rip), %xmm1    # 0x331e0
movsd %xmm1, (%rsp)
movapd %xmm1, %xmm0
addsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x2e30e(%rip), %xmm1    # 0x33400
callq 0x25bb9
movsd 0x8(%rsp), %xmm2
movsd (%rsp), %xmm1
movapd 0x10(%rsp), %xmm0
testb %al, %al
jne 0x50c3
jmp 0x517d
movapd 0x20(%rsp), %xmm0
movapd %xmm0, %xmm2
mulsd %xmm0, %xmm2
movsd 0x2e0bc(%rip), %xmm1    # 0x331e0
divsd %xmm2, %xmm1
movsd %xmm1, (%rsp)
movsd 0x2e38b(%rip), %xmm1    # 0x334c0
callq 0x25c15
testb %al, %al
je 0x52bd
movsd 0x2e3a6(%rip), %xmm0    # 0x334f0
movsd (%rsp), %xmm1
mulsd %xmm1, %xmm0
addsd 0x2e39d(%rip), %xmm0    # 0x334f8
mulsd %xmm1, %xmm0
addsd 0x2e399(%rip), %xmm0    # 0x33500
jmp 0x52fa
movapd 0x10(%rsp), %xmm0
movsd (%rsp), %xmm1
movsd 0x8(%rsp), %xmm2
movsd %xmm2, 0x8(%rsp)
movsd %xmm1, (%rsp)
xorpd %xmm1, %xmm1
movapd %xmm0, 0x10(%rsp)
callq 0x25bb9
testb %al, %al
jne 0x51a5
movsd 0x2e03d(%rip), %xmm1    # 0x331e0
jmp 0x51c1
movapd 0x10(%rsp), %xmm0
xorpd 0x2dffd(%rip), %xmm0    # 0x331b0
movapd %xmm0, 0x10(%rsp)
movsd 0x2e047(%rip), %xmm1    # 0x33208
movsd 0x8(%rsp), %xmm0
movsd %xmm1, (%r14)
movsd 0x2e22c(%rip), %xmm1    # 0x33400
callq 0x25b75
testb %al, %al
je 0x51f1
movaps 0x10(%rsp), %xmm0
movq %rbx, %rdi
addq $0x48, %rsp
popq %rbx
popq %r14
jmp 0x25f91
movsd (%rsp), %xmm1
addsd 0x2e212(%rip), %xmm1    # 0x33410
addsd 0x20(%rsp), %xmm1
movsd 0x2e2fc(%rip), %xmm0    # 0x33508
mulsd %xmm1, %xmm0
addsd 0x2e2f8(%rip), %xmm0    # 0x33510
mulsd %xmm1, %xmm0
addsd 0x2e2f4(%rip), %xmm0    # 0x33518
mulsd %xmm1, %xmm0
addsd 0x2e2f0(%rip), %xmm0    # 0x33520
mulsd %xmm1, %xmm0
addsd 0x2e2ec(%rip), %xmm0    # 0x33528
mulsd %xmm1, %xmm0
addsd 0x2e2e8(%rip), %xmm0    # 0x33530
movapd %xmm0, %xmm2
movsd 0x2e2e4(%rip), %xmm0    # 0x33538
addsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
addsd 0x2e2dc(%rip), %xmm0    # 0x33540
mulsd %xmm1, %xmm0
addsd 0x2e2d8(%rip), %xmm0    # 0x33548
mulsd %xmm1, %xmm0
addsd 0x2e2d4(%rip), %xmm0    # 0x33550
mulsd %xmm1, %xmm0
addsd 0x2e2d0(%rip), %xmm0    # 0x33558
mulsd %xmm1, %xmm0
addsd 0x2e2cc(%rip), %xmm0    # 0x33560
mulsd %xmm1, %xmm2
divsd %xmm0, %xmm2
movsd %xmm2, (%rsp)
movapd 0x10(%rsp), %xmm0
movq %rbx, %rdi
callq 0x25f91
movapd %xmm0, %xmm1
addsd (%rsp), %xmm1
jmp 0x500f
movsd 0x2e203(%rip), %xmm0    # 0x334c8
movsd (%rsp), %xmm1
mulsd %xmm1, %xmm0
addsd 0x2e1fa(%rip), %xmm0    # 0x334d0
mulsd %xmm1, %xmm0
addsd 0x2e1f6(%rip), %xmm0    # 0x334d8
mulsd %xmm1, %xmm0
addsd 0x2e1f2(%rip), %xmm0    # 0x334e0
mulsd %xmm1, %xmm0
addsd 0x2e1ee(%rip), %xmm0    # 0x334e8
movsd 0x10(%rsp), %xmm1
divsd 0x20(%rsp), %xmm0
addsd %xmm0, %xmm1
jmp 0x500f