12회 실험 · 부호 보존#
이 실험
짝 서술 |
|
확인하는 것 |
\(\epsilon\)을 \(A/2\)로 택하면 허용 띠의 아래 끝이 \(0\) 위에 놓인다는 것 |
서술 파트 2절의 정리 35은 증명이 짧다. \(\epsilon = A/2\)로 택하는 한 줄이 전부이다. 그 한 줄이 왜 통하는지를 그림으로 보는 것이 이 노트북의 목적이다.
(11.3)에 의하여 \(\epsilon\)은 \(A\)를 가운데 둔 띠 \((A-\epsilon,\ A+\epsilon)\)을 그린다. 우리가 원하는 것은 그 띠의 아래 끝이 \(0\)보다 위에 있는 것이며, \(\epsilon = A/2\)가 그것을 만든다. 아래 끝이 정확히 \(A/2\)가 되기 때문이다.
여기서는 \(f(t) = t^3 - 2t + \tfrac{6}{5}\)를 \(p = 0\)에서 본다. 서술 파트 2절이 \(A = 0.6\)으로 예를 들었는데 이 함수는 \(A = 6/5\)이므로 수치가 다르다. 같은 계산의 서로 다른 값이며, 다항함수를 쓰는 이유는 sympy가 정확한 유리수로 다룰 수 있기 때문이다.
먼저 \(A\)와 \(\epsilon\)을 정확한 분수로 구하고 띠의 아래 끝이 양수인지 확인한다. 그다음 곡선과 두 개의 띠를 겹쳐 그려 \(\delta\) 범위 안에서 곡선이 띠를 벗어나지 않는 것을 본다.
서술 파트의 내용 |
여기서 확인하는 방법 |
|---|---|
(12.7) — \(\epsilon = A/2\)의 선택 |
\(A\)를 유리수로 정확히 구하고 \(A-\epsilon\)을 출력한다 |
근방에서 \(f > 0\)이라는 결론 |
작은 구간에서 \(f\)의 최솟값을 구해 부호를 본다 |
허용 띠라는 말의 뜻 |
가로 띠와 세로 띠를 겹쳐 그린다 |
\(\epsilon\)이 \(A\)보다 작아야 한다는 것 |
\(\epsilon\)을 바꾸어 가며 띠의 아래 끝 부호를 본다 |
0. 준비#
이 회차에서 쓸 것만 불러온다. 검정이 곡선, 회색이 가로 허용 띠, 파랑이 세로 \(\delta\) 띠, 빨강이 띠의 아래 끝이다.
1. ε을 A/2로 택한다#
\(f(t) = t^3 - 2t + \tfrac{6}{5}\)와 \(p = 0\)을 잡는다. 이 함수는 다항함수이므로 서술 파트 정리 38에 의하여 모든 점에서 연속이고, 따라서 \(A = \lim_{t\to 0} f(t) = f(0)\)이다.
\(A\)와 \(\epsilon\)을 부동소수가 아니라 정확한 유리수로 다룬다. 띠의 아래 끝이 \(0\)보다 큰지가 결론을 가르므로, 경계에서 반올림이 끼어들면 안 된다.
# A and eps as exact rationals, and the bottom of the band
t = sp.symbols("t", real=True)
f = t ** 3 - 2 * t + sp.Rational(6, 5)
A = f.subs(t, 0)
eps = A / 2
print("A =", A, "=", float(A))
print("eps = A / 2 =", eps, "=", float(eps))
print("band = (", A - eps, ",", A + eps, ")")
print("band bottom =", A - eps, "=", float(A - eps))
print("bottom > 0 :", (A - eps) > 0)
A = 6/5 = 1.2
eps = A / 2 = 3/5 = 0.6
band = ( 3/5 , 9/5 )
band bottom = 3/5 = 0.6
bottom > 0 : True
띠는 \((3/5,\ 9/5)\)이고 아래 끝이 \(3/5 = 0.6\)이다. \(0\)보다 크다. 이것이 정리 35이 요구하는 전부이다.
띠의 아래 끝이 \(A/2\)가 되는 것은 우연이 아니다. \(A - \epsilon = A - A/2 = A/2\)이므로 \(\epsilon\)을 \(A\)의 절반으로 택하는 순간 아래 끝이 \(A\)의 절반에 놓인다.
이제 이 띠에 대응하는 \(t\)의 범위를 찾는다. \(|f(t) - A| < \epsilon\)이 깨지는 곳은 \(f\)가 띠의 위 끝이나 아래 끝에 닿는 지점이다.
# Where does the curve touch the two edges of the band?
lower_roots = sp.real_roots(f - (A - eps))
upper_roots = sp.real_roots(f - (A + eps))
print("f = A - eps at :", [float(r) for r in lower_roots])
print("f = A + eps at :", [float(r) for r in upper_roots])
f = A - eps at : [-1.545396360597597, 0.31573804364705926, 1.2296583169505377]
f = A + eps at : [-1.2296583169505377, -0.31573804364705926, 1.545396360597597]
\(p = 0\)을 감싸는 구간은 \(-0.31573804\)부터 \(0.31573804\)까지이다. 이 안에서는 곡선이 띠 안에 머문다.
\(\delta\)를 그보다 작게 잡으면 안전하다. \(\delta = 1/4\)로 두고 그 구간에서 \(f\)의 최솟값을 구한다. \(f' = 3t^2 - 2\)의 영점은 \(\pm\sqrt{2/3} \approx \pm 0.8165\)로 구간 밖이므로, 이 구간에서 \(f\)는 단조이고 최솟값이 끝점에서 나온다.
# The minimum on a small interval around p, exactly
left_value = f.subs(t, sp.Rational(-1, 4))
right_value = f.subs(t, sp.Rational(1, 4))
min_value = sp.Min(left_value, right_value)
print("f(-1/4) =", left_value, "=", float(left_value))
print("f( 1/4) =", right_value, "=", float(right_value))
print("minimum =", min_value, "=", float(min_value))
print("minimum > 0 :", min_value > 0)
f(-1/4) = 539/320 = 1.684375
f( 1/4) = 229/320 = 0.715625
minimum = 229/320 = 0.715625
minimum > 0 : True
최솟값이 \(229/320 = 0.715625\)로 양수이다. 한 점의 정보 \(A = 6/5 > 0\)에서 구간 전체의 부등식이 나왔다.
이 값이 띠의 아래 끝 \(3/5 = 0.6\)보다 크다는 점에도 유의한다. 정리가 보장하는 것은 \(f > A/2\)이고, 실제 최솟값은 그보다 여유가 있다. 정리는 하한 하나를 보장할 뿐 가장 좋은 하한을 주지 않는다.
2. 두 개의 띠를 겹쳐 그린다#
말로 적은 것을 그림으로 옮긴다. 가로 띠가 \(\epsilon\)이 그리는 허용 범위이고, 세로 띠가 \(\delta\)가 그리는 \(t\)의 범위이다. 곡선이 세로 띠 안에서 가로 띠를 벗어나지 않으면 정의가 충족된다.
# The horizontal band is eps, the vertical band is delta
fn = sp.lambdify(t, f, "numpy")
ts = np.linspace(-0.6, 0.6, 401)
d = 0.25
fig, ax = plt.subplots()
ax.axhspan(float(A - eps), float(A + eps), color=C_BAND, alpha=0.25,
label="eps band around A")
ax.axvspan(-d, d, color=C_LOWER, alpha=0.25, label=f"delta band, delta = {d}")
ax.axhline(float(A - eps), color=C_DIFF, linestyle="--", linewidth=1.2,
label="band bottom = A - eps")
ax.axhline(0.0, color=C_FUNC, linewidth=0.8)
ax.plot(ts, fn(ts), color=C_FUNC, linewidth=1.8, label="f(t) = t**3 - 2t + 6/5")
ax.set_xlabel("t")
ax.set_ylabel("f(t)")
ax.set_title("eps = A/2 puts the band bottom at 0.6, above zero")
ax.legend(loc="lower left", fontsize=9)
fig.tight_layout()
plt.show()
print("f( 0.25) =", float(f.subs(t, sp.Rational(1, 4))))
print("f(-0.25) =", float(f.subs(t, sp.Rational(-1, 4))))
f( 0.25) = 0.715625
f(-0.25) = 1.684375
세로 띠 안에서 곡선이 가로 띠를 뚫고 나가지 않는다. 오른쪽 끝 \(t = 0.25\)에서 \(f = 0.715625\)이고 왼쪽 끝에서 \(f = 1.684375\)이므로, 두 값 모두 \((0.6,\ 1.8)\) 안에 있다.
빨간 점선이 이 그림의 요점이다. 그 선이 가로 띠의 아래 끝이고, 곡선이 세로 띠 안에서 그 선 위에 머문다. 그런데 그 선 자체가 \(y=0\)인 검은 선보다 위에 있으므로 곡선도 \(0\)보다 위에 있다. \(\epsilon = A/2\)가 하는 일이 그 선을 \(0\) 위로 올려놓는 것이다.
\(\epsilon\)을 \(A\)보다 크게 잡으면 이 논증이 무너진다. 확인해 본다.
# If eps is larger than A the band bottom drops below zero
header = f"{'eps':>10} {'band bottom':>14} {'bottom > 0':>12}"
print(header)
print("-" * len(header))
for candidate in (A / 3, A / 2, A, sp.Rational(3, 2)):
bottom = A - candidate
print(f"{str(candidate):>10} {str(bottom):>14} {str(bottom > 0):>12}")
eps band bottom bottom > 0
--------------------------------------
2/5 4/5 True
3/5 3/5 True
6/5 0 False
3/2 -3/10 False
\(\epsilon = A/3\)과 \(A/2\)에서는 아래 끝이 양수이고, \(\epsilon = A\)에서는 정확히 \(0\)이 되어 부등식이 엄격하지 않게 되며, \(\epsilon = 3/2 > A\)에서는 음수가 된다.
\(A\)보다 작은 \(\epsilon\)이면 무엇이든 통한다. \(A/2\)는 그중 계산이 편한 값일 뿐이며, 서술 파트가 \(A/3\)도 된다고 적은 것이 이 표의 첫 줄이다.
마치며#
\(\epsilon = A/2\)라는 선택이 무엇을 하는지 보았다. \(A\)를 가운데 둔 허용 띠의 아래 끝을 \(A/2\)에 놓아 \(0\) 위로 올린다. 그러면 그 띠 안에 있는 함숫값은 모두 \(0\)보다 크다.
\(f(t) = t^3 - 2t + \tfrac{6}{5}\)에서 \(A = 6/5\)이고 \(\epsilon = 3/5\)이며 띠는 \((3/5,\ 9/5)\)였다. \(\delta = 1/4\)인 구간에서 \(f\)의 최솟값이 \(229/320 = 0.715625\)로 양수였다. 한 점의 정보에서 구간 전체의 부등식이 나왔다.
\(\epsilon\)을 바꾸어 가며 띠의 아래 끝을 보면 \(A\)보다 작은 값이면 무엇이든 통한다. \(A/2\)는 유일한 선택이 아니라 편한 선택이다.
서술 파트의 내용 |
이 노트북의 코드 |
|---|---|
(12.7)의 \(\epsilon = A/2\) |
1절 |
띠의 아래 끝이 \(A/2\)가 된다는 것 |
1절 |
근방에서 \(f > 0\)이라는 결론 |
1절 |
허용 띠와 \(\delta\) 범위 |
2절 |
\(A/3\)도 된다는 것 |
2절 마지막 셀의 네 줄짜리 표 |
더 해 볼 것#
1절의
eps를A / 2대신sp.Rational(3, 2)로 바꾸어 보자. 띠의 아래 끝이 얼마가 되며, 그때 \(|f(t)-A| < \epsilon\)을 만족하는 \(t\)의 범위 안에 \(f\)가 음수인 점이 들어오는지sp.real_roots로 확인해 보자.상수항을 없애
f = t**3 - 2*t로 두면 \(A = 0\)이 된다. 이때 \(\epsilon = A/2\)는 무엇이 되는가. 정의 18이 요구하는 \(\epsilon > 0\) 조건과 견주어 이 방법이 통하지 않는 이유를 적어 보자.2절의
d를 \(0.25\)에서 \(0.35\)로 키워 보자. 곡선이 가로 띠를 벗어나는가. 1절이 구한 경계 \(\pm 0.31573804\)와 비교해 보자.
짝이 되는 서술