barcode

감마 함수+팩토리얼 코드에서 유리수 처리

Coding/Python

아, 정확히는 정수가 아닌 유리수 말하는거다. 


감마 함수? 

일단 팩토리얼(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")

일단 어제 심파이랑 mpmath 올리고 해 본 결과 expr에 저 식 때려박고 음수로 입력하면 에러가 뜬다. 즉, 예외처리가 가능하다. 근데 예외 처리에는 문제가 몇 개 있는데 

1) 원래 감마 함수는 0에서도 정의가 안 된다. (정의역이 0보다 크다) 
2) 그리고 try except는 if랑 같이 못 쓴다. 

대충 이런 문제가 있다. 

 

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")

그래서 0도 계산 못 하는걸로 처리하느라 if 줬다. 

참고로 복소수의 경우 실수부가 음수여도 알파신 때려박으면 계산은 해 준다. 결과가 복소수긴 한데... 근데 왜 저기서는 실수부가 양수일 때만 처리했느냐... Sympy는 복소수 실수부가 음수일 때 적분 객체만 띡 생성하고 끝난다. 

 

팩토리얼 코드 수정

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을 더해줘야 한다. (1.5!을 구할거면 2.5를 넣어야 한다) 복소수도 마찬가지로 실수부에 1을 더해야 하지만 저 코드에서는 복소수 지원 안 한다. 


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)

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")
    # 음수는 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)

While

'Coding > Python' 카테고리의 다른 글

Python으로 JSON파일 읽기  (0) 2022.08.22
재귀함수가 돌아가는 방식을 알아보자  (0) 2022.08.22
이중계승 추가  (0) 2022.08.22
팩토리얼 로직 또 수정  (0) 2022.08.22
팩토리얼 로직 수정+계승 소수  (0) 2022.08.22