Python을 사용하여 n!의 시너지 평균 구하기

소개



현재 독학으로 Rails를 공부하고 있는 초학자입니다. 취미로 수치 계산 등에 Python을 이용하고 있습니다.
이번 $n$이 무한대일 때의 $n!$의 시너지 평균, 즉
\lim_{n \to \infty} \frac{\sqrt[n]{n!}}{n}\\

파이썬에서 어떻게 든 찾고 싶습니다.

시너지 평균은?



평균이라고 하면, 어느 $n$개의 데이터 $x_1, x_2, ..., x_n$를 모두 더해 $n$로 나눈 값을 구하는 상가 평균을 떠올린다고 생각합니다. 반면 시너지 평균 $\mu$는
\mu = \sqrt[n]{x_1x_2...x_n}\\

에서 요청할 수 있습니다. 성장률이나 이율 계산 등에 자주 사용됩니다.

주제



그런데, 전술에서 나타낸 n!의 시너지 평균을 구해 나가려고 생각합니다. 위 방정식을 사용하면 $\sqrt[n]{n!}$에서 구할 수 있지만 무한대로 날 때 수렴하지 않을 것 같아서 $n$로 나눈 것을 무한대로 날 때를 생각합니다. . 즉, $\mu$가 전체의 몇 % 위치에 있는지 확인합니다. 따라서
\lim_{n \to \infty} \frac{\sqrt[n]{n!}}{n}\\

를 찾아갑니다.

풀어봐



우선 임의의 수를 $n$에 대입해 어느 값에 수렴할 것인가, matplotlib를 사용해 그래프를 플롯 해 나가고 싶습니다.
sympy를 사용하면 $2000!$에서도 손쉽게 계산할 수 있습니다. 표준 모듈의 math를 사용하면 자릿수가 너무 크면 오류가 반환됩니다.

plot.py
import matplotlib.pyplot as plt
import sympy

def fun(n):
    n1 = sympy.factorial(n)
    n2 = n1 ** (1/n)
    n3 = n2/n
    return n3

x = list(range(1,2000,10))
y = []
for i in x:
    y.append(fun(i))

print(x)
print(y)
plt.plot(x,y)
plt.ylim([0.36,0.4])



그래프를 보면 0.37당 수렴할 것 같은 느낌이 듭니다.
여기서 위 식이 있는 값 $a$에 수렴한다고 가정합니다. 또 위 식 그대로는 풀기 어렵기 때문에 로그를 취하면,
\log \lim_{n \to \infty} \frac{\sqrt[n]{n!}}{n} = \log a\\
\lim_{n \to \infty} \log \frac{\sqrt[n]{n!}}{n} = \log a\\

정리하면
\begin{align}
\lim_{n \to \infty} \log \frac{\sqrt[n]{n!}}{n} &= \lim_{n \to \infty} (\log {\sqrt[n]{n!}}-\log {n})\\
&= \lim_{n \to \infty} \Bigl( \frac{1}{n}\log {n!}-\log {n}\Bigr)\\
&= \lim_{n \to \infty} \Bigl( \frac{1}{n}\sum_{k=1}^{n} \log k-\log {n}\Bigr)
\end{align}\\

여기에서
\sum_{k=1}^{n} \log k

에 대해 생각합니다.
구분 급수의 극한이 나오면 가위의 정리를 이용할 수 있을 것으로 예상할 수 있습니다. 여기에서
\begin{align}
f(x) &= \log({x-1})\\
g(x) &= \log {x}
\end{align}

소개합니다. 이유는 이제부터 나타납니다. 이상 3개의 식을 다시 matplotlib를 사용해 플롯합니다.

plot2.py
with np.errstate(invalid='ignore'):
    x = np.arange(-1, 11, 0.01)
    y1 = np.log(x)
    y2 = np.log(x-1)
    fig = plt.figure()
    plt.xlim([-1, 11])
    plt.ylim([-2, 4])
    plt.xlabel('x')
    plt.ylabel('y', rotation=0)
    plt.gca().set_aspect('equal')
    plt.grid()
    plt.plot(x, y1, label="g(x)")
    plt.plot(x, y2, label="f(x)", color="green")

    x = list(range(1,11,1))
    y3 = []
    for i in x:
        y3.append(np.log(i))

    print(y3)
    plt.bar(x, y3, width = 1.0, align="edge",color="orange", edgecolor="black", label="Σlogk")
    plt.legend(bbox_to_anchor=(1, 1), loc='upper right', borderaxespad=0, fontsize=8)
    plt.show()
    fig.savefig("log.jpg")



플롯을 보면 알 수 있듯이 $\sum_{k=1}^{n}\log k$가 $f(x)$와 $g(x)$의 적분 값 사이에 있음을 알 수 있습니다. 따라서,
 \int_{2}^{n}\log({x-1})dx< \sum_{k=1}^{n} \log k < \int_{2}^{n}\log {x} dx\\

위의 로그 함수의 정적분은 부분적분을 사용하면 풀 수 있습니다. 그러나 여기에서는 파이썬을 사용하는 것이 목적이므로,

integral.py
import sympy as sym
from sympy.plotting import plot
sym.init_printing(use_unicode=True)
from sympy import log

n, x, y = sym.symbols("n x y")
logx1  = log(x)
logx2  = log(x-1)
q1 = sym.integrate(logx1, (x, 2, n+1))
q2 = sym.integrate(logx2, (x, 2, n+1))
print(q1)
print(q2)
-n + (n + 1)*log(n + 1) - 2*log(2) + 1 #log(x)定積分の解
-n + (n + 1)*log(n) - log(n) + 1 #log(x-1)定積分の解

또한 각각 $n$로 나누고 $\log {n}$를 뺍니다. 즉, 첫 번째 수식으로 수정합니다.
 \frac{1}{n}-1< \frac{1}{n}\sum_{k=1}^{n} \log k-\log {n} < \log \Bigl(1+\frac{1}{n}\Bigr)+\frac{1}{n}\log(n+1)+\frac{1}{n}-\frac{2}{n}\log2-1\\

극한도 sympy를 사용하여 구합니다.

integral.py
import sympy as sym
from sympy.plotting import plot
sym.init_printing(use_unicode=True)
from sympy import log

n, x, y = sym.symbols("n x y")
logx1  = log(x)
logx2  = log(x-1)
q1 = sym.integrate(logx1, (x, 2, n+1))
q2 = sym.integrate(logx2, (x, 2, n+1))
q11 = q1/n-log(n)
q22 = q2/n-log(n)

oo = sympy.oo
lim_q11 = sym.limit(q11, n, oo)
lim_q22 = sym.limit(q22, n, oo)
print(lim_q11)
print(lim_q22)
-1
-1

따라서 가위의 정리보다,
\lim_{n \to \infty} \Bigl( \frac{1}{n}\sum_{k=1}^{n} \log k-\log {n}\Bigr)=\lim_{n \to \infty} \log \frac{\sqrt[n]{n!}}{n} = -1
\\

그런데 수렴 값을 $ a $로 설정했습니다.
\lim_{n \to \infty} \log \frac{\sqrt[n]{n!}}{n} = \log a\\
\begin{align}
a&= \lim_{n \to \infty} \frac{\sqrt[n]{n!}}{n}\\
&= \frac{1}{e}\\
&= 0.367...
\end{align}\\

수고하셨습니다. 마침내 수렴이 나왔습니다. 최초로 적당한 숫자를 대입해 예측한 수렴치와 맞추고 있습니다.
자연 로그 $e$가 나오는 아름다운 해입니다.

마지막으로



어땠어? 파이썬의 수치 계산용의 모듈을 이용해 풀었습니다만, 보다 스마트한 풀기 방법도 있다고 생각합니다. 또한이 문제는 고등학교 수학 범위 내에서 해결할 수 있습니다.
별해를 생각해 보는 것도 즐거울지도 모릅니다.

참고



적분을 파이썬으로 이해
고등학교 수학의 '극한값' 관련 문제를 파이썬으로 해결

좋은 웹페이지 즐겨찾기