감마 함수+팩토리얼 코드 수정

감마 함수?

팩토리얼, n!은 n부터 시작해서 1씩 쫙 곱하는건데 얘는 자연수한테만 먹힌다. 자연수 말고 다른거 나오면 미쳤습니까 휴먼? 한다. 그래서 이전에 팩토리얼 코드에 유리수 처리하는 로직 설명하면서 소수점 붙은 놈들(정수가 아닌 유리수)이나 복소수는 감마 함수에 때려박아야 한다고 했었다.

그리고 이게 감마함수다. 저거 말고도 식 세갠가 더 있는데 다 파이(곱의 기호) 뜨고 난리났다.

감마 함수 코드

from sympy import *
from mpmath import mp
import sys
a = complex(sys.stdin.readline())
# 복소수는 complex로 입력해야 합니다. (int: 정수, float: 소수라고 생각하면 됨)
t = symbols("t")
expr = t ** (a - 1) * exp(-t)
try: 
    print(Integral((expr),(t,0,oo)).doit())
except: 
    print("Cannot calculate Gamma function")

일단… 저 식 만들고 음수 때려박은 결과 에러 떴다. 참고로 그게 정상인 게, 감마함수의 정의역은 0보다 큰 수다. 그럼 저대로 하면 되겠네요? ㄴㄴ 그게 그렇게 쉬웠으면 내가 썰을 풀겠소… 저 코드에는 몇가지 문제가 있는데

  1. 원래 감마함수의 정의역은 0보다 큰 수다. 즉, 0에서도 정의가 안된다.
  2. Try Except는 if랑 같이 못 쓴다.

1번이 왜 문제냐… 0도 예외처리가 되어야 하는데, 0에서 뭔 오일러 감마 뭐시기가 반긴다.

from sympy import *
from mpmath import mp
import sys
a = complex(sys.stdin.readline())
# 복소수는 complex로 입력해야 합니다. (int: 정수, float: 소수라고 생각하면 됨)
t = symbols("t")
expr = t ** (a - 1) * exp(-t)
gamma_function = integrate((expr),(t,0,oo))
if a.real > 0:
    if gamma_function % 1 == 0:
        print(round(gamma_function))
    else: 
        print(round(gamma_function,3))
else: 
    print("Cannot calculate Gamma function")

참고로 울프램알파에 돌려본 결과 복소수는 실수부가 음수여도 감마함수 계산은 해 준다. (결과가 허수다) 근데 Sympy에서는 실수부가 음수인 복소수 저 식에 때려박으면 적분 객체만 띡 생성해주고 끝난다. 계산은 니가 해라 뭐 이런건가 그래서 이 코드는 실수부가 0보다 큰 복소수에 대해서만 계산한다.

팩토리얼 이식 버전

def gamma_function(a):
    t = symbols("t")
    expr = t ** (a - 1) * exp(-t)
    if a.real > 0:
        return integrate((expr),(t,0,oo))
    else: 
        return False

함수는 이렇게 짜면 된다. 근데 문제가 하나 있다… 감마 함수의 성질은

이래서 저기다가 1.5를 넣고 함수 걍 돌리면 0.5!이 나온다.

elif a % 1 != 0:
    print(round(gamma_function(a+1),3))

그래서 1.5!을 구할거면 감마함수에는 1을 더한 2.5를 넣어줘야 한다. 즉, 입력값에 1을 더한 다음 때려박아야 한다. 복소수도 마찬가지긴 한데 어차피 저 코드에서는 지원 안 한다.

최종 코드

For

from sympy import *
from mpmath import mp
import sys

def gamma_function(a):
    t = symbols("t")
    expr = t ** (a - 1) * exp(-t)
    if a.real > 0:
        return integrate((expr),(t,0,oo))
    else: 
        return False

a = float(sys.stdin.readline().strip())
# Factorial(계승): 일반적으로 n! = 1*2*3*...*n-1*n이다. (5!=1*2*3*4*5)
factorial = 1
if a < 0:
    print("Can't calculate factorial")
    # 음수는 factorlal이 없음
elif a == 0:
    print(factorial)
    # 0! = 1
elif a % 1 != 0:
    print(round(gamma_function(a+1),3))
else:
    for i in range(int(a),0,-1):
        factorial *= i
    print(factorial)

While

from sympy import *
from mpmath import mp
import sys

def gamma_function(a):
    t = symbols("t")
    expr = t ** (a - 1) * exp(-t)
    if a.real > 0:
        return integrate((expr),(t,0,oo))
    else: 
        return False

a = float(sys.stdin.readline().strip())
# 와 팩토리얼이 생각보다 빡센거였구나... 
# Factorial(계승): 일반적으로 n! = 1*2*3*...*n-1*n이다. (5!=1*2*3*4*5)
factorial = 1
if a < 0: 
    print("Can't calculate factorial")
    # 음수는 factorial이 없음
elif a == 0: 
    factorial = 1
    # 0! = 1
elif a % 1 != 0:
    print(round(gamma_function(a+1),3))
else: 
    while a >= 1:
        factorial *= a
        a -= 1
    print(factorial)