// File: /workspace/github_cpp_makefile_star2_O2/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 $0x58, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, (%rdi)
movsd 0x2bb9a(%rip), %xmm1    # 0x30498
movaps %xmm0, 0x30(%rsp)
callq 0x24239
testb %al, %al
je 0x499e
movaps 0x2b899(%rip), %xmm0    # 0x301b0
xorps 0x30(%rsp), %xmm0
movaps %xmm0, 0x10(%rsp)
leaq 0x50(%rsp), %rdi
movq %rbx, %rsi
callq 0x48dc
movsd %xmm0, 0x28(%rsp)
movaps 0x10(%rsp), %xmm0
movq %rbx, %rdi
callq 0x24468
cvtsi2sd %rax, %xmm0
movsd %xmm0, 0x8(%rsp)
movq %rbx, %rdi
callq 0x24453
xorl %ecx, %ecx
testb $0x1, %al
sete %cl
leaq 0x2d2be(%rip), %rax     # 0x31c20
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%r14)
movapd 0x10(%rsp), %xmm0
subsd 0x8(%rsp), %xmm0
movsd 0x2bb08(%rip), %xmm1    # 0x30488
movapd %xmm0, 0x40(%rsp)
callq 0x24279
testb %al, %al
jne 0x4a1c
movapd 0x40(%rsp), %xmm0
jmp 0x4a30
movsd 0x2bafa(%rip), %xmm1    # 0x304a0
movaps 0x30(%rsp), %xmm0
callq 0x24239
testb %al, %al
je 0x4ad3
xorps %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x2b82f(%rip), %xmm0    # 0x301f8
movapd %xmm0, 0x10(%rsp)
movapd 0x30(%rsp), %xmm1
movsd %xmm1, 0x28(%rsp)
movapd %xmm1, %xmm0
movsd 0x2b7f9(%rip), %xmm1    # 0x301e0
callq 0x24295
testb %al, %al
je 0x4a6c
movsd 0x8(%rsp), %xmm1
addsd 0x2b802(%rip), %xmm1    # 0x30200
movsd %xmm1, 0x8(%rsp)
addsd 0x30(%rsp), %xmm1
movapd 0x10(%rsp), %xmm0
mulsd %xmm1, %xmm0
movapd %xmm0, 0x10(%rsp)
jmp 0x49d5
movsd 0x8(%rsp), %xmm0
addsd 0x2b7ce(%rip), %xmm0    # 0x301f8
addsd 0x30(%rsp), %xmm0
mulsd 0x2ba58(%rip), %xmm0    # 0x30490
movq %rbx, %rdi
callq 0x2452d
mulsd 0x10(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2455f
movsd 0x2bb12(%rip), %xmm1    # 0x30568
subsd %xmm0, %xmm1
subsd 0x28(%rsp), %xmm1
movapd %xmm1, %xmm0
addq $0x58, %rsp
popq %rbx
popq %r14
retq
movsd 0x28(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x2b978(%rip), %xmm1    # 0x303f8
callq 0x24239
testb %al, %al
je 0x4ab7
movapd 0x10(%rsp), %xmm0
divsd 0x28(%rsp), %xmm0
movapd %xmm0, 0x10(%rsp)
movsd 0x8(%rsp), %xmm0
addsd 0x2b74f(%rip), %xmm0    # 0x301f8
movsd %xmm0, 0x8(%rsp)
addsd 0x30(%rsp), %xmm0
jmp 0x4a72
xorpd %xmm1, %xmm1
movaps 0x10(%rsp), %xmm0
callq 0x24239
testb %al, %al
jne 0x4b35
movsd 0x2b727(%rip), %xmm0    # 0x301f8
jmp 0x4b4e
movsd 0x2b9cd(%rip), %xmm1    # 0x304a8
movapd 0x30(%rsp), %xmm0
addsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
movq %rbx, %rdi
callq 0x2455f
mulsd 0x10(%rsp), %xmm0
movapd 0x30(%rsp), %xmm2
subsd %xmm2, %xmm0
addsd 0x2b9a5(%rip), %xmm0    # 0x304b0
movsd %xmm0, 0x10(%rsp)
movsd 0x2b99f(%rip), %xmm1    # 0x304b8
movapd %xmm2, %xmm0
callq 0x24279
testb %al, %al
je 0x4c4d
movsd 0x10(%rsp), %xmm1
jmp 0x4a60
movaps 0x10(%rsp), %xmm0
xorps 0x2b66f(%rip), %xmm0    # 0x301b0
movaps %xmm0, 0x10(%rsp)
movsd 0x2b6b2(%rip), %xmm0    # 0x30200
movsd %xmm0, (%r14)
movsd 0x2b89d(%rip), %xmm1    # 0x303f8
movsd 0x28(%rsp), %xmm0
callq 0x241f5
testb %al, %al
je 0x4b7e
movaps 0x10(%rsp), %xmm0
movq %rbx, %rdi
addq $0x58, %rsp
popq %rbx
popq %r14
jmp 0x2455f
movsd 0x8(%rsp), %xmm1
addsd 0x2b874(%rip), %xmm1    # 0x30400
addsd 0x30(%rsp), %xmm1
movsd 0x2b96e(%rip), %xmm0    # 0x30508
mulsd %xmm1, %xmm0
addsd 0x2b96a(%rip), %xmm0    # 0x30510
mulsd %xmm1, %xmm0
addsd 0x2b966(%rip), %xmm0    # 0x30518
mulsd %xmm1, %xmm0
addsd 0x2b962(%rip), %xmm0    # 0x30520
mulsd %xmm1, %xmm0
addsd 0x2b95e(%rip), %xmm0    # 0x30528
mulsd %xmm1, %xmm0
addsd 0x2b95a(%rip), %xmm0    # 0x30530
movapd %xmm0, %xmm2
movsd 0x2b956(%rip), %xmm0    # 0x30538
addsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
addsd 0x2b94e(%rip), %xmm0    # 0x30540
mulsd %xmm1, %xmm0
addsd 0x2b94a(%rip), %xmm0    # 0x30548
mulsd %xmm1, %xmm0
addsd 0x2b946(%rip), %xmm0    # 0x30550
mulsd %xmm1, %xmm0
addsd 0x2b942(%rip), %xmm0    # 0x30558
mulsd %xmm1, %xmm0
addsd 0x2b93e(%rip), %xmm0    # 0x30560
mulsd %xmm1, %xmm2
divsd %xmm0, %xmm2
movsd %xmm2, 0x8(%rsp)
movapd 0x10(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2455f
movapd %xmm0, %xmm1
addsd 0x8(%rsp), %xmm1
jmp 0x4a60
movapd 0x30(%rsp), %xmm0
movapd %xmm0, %xmm1
mulsd %xmm0, %xmm1
movsd 0x2b595(%rip), %xmm2    # 0x301f8
divsd %xmm1, %xmm2
movsd %xmm2, 0x8(%rsp)
movsd 0x2b84b(%rip), %xmm1    # 0x304c0
callq 0x24295
testb %al, %al
je 0x4ca6
movsd 0x2b86a(%rip), %xmm0    # 0x304f0
movsd 0x8(%rsp), %xmm1
mulsd %xmm1, %xmm0
addsd 0x2b860(%rip), %xmm0    # 0x304f8
mulsd %xmm1, %xmm0
addsd 0x2b85c(%rip), %xmm0    # 0x30500
jmp 0x4ce4
movsd 0x2b81a(%rip), %xmm0    # 0x304c8
movsd 0x8(%rsp), %xmm1
mulsd %xmm1, %xmm0
addsd 0x2b810(%rip), %xmm0    # 0x304d0
mulsd %xmm1, %xmm0
addsd 0x2b80c(%rip), %xmm0    # 0x304d8
mulsd %xmm1, %xmm0
addsd 0x2b808(%rip), %xmm0    # 0x304e0
mulsd %xmm1, %xmm0
addsd 0x2b804(%rip), %xmm0    # 0x304e8
movsd 0x10(%rsp), %xmm1
divsd 0x30(%rsp), %xmm0
addsd %xmm0, %xmm1
jmp 0x4a60