5회 실험 · 최소상계#

이 실험

짝 서술

5회 · 최소상계 원리

실험 목록

실험 1 (1층) — 상계와 최소상계 / 실험 2 (1층) — 유리수 안에서 상계를 줄인다 / 실험 3 (3층) — 최소상계를 기호로 확인한다

Hide code cell source

# 공통 준비 — 색 규약과 한글 글꼴을 맞춘다
import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from fractions import Fraction

from calc_viz import , 
from calc_style import 한글글꼴설정

글꼴 = 한글글꼴설정()   # 돌려주는 값은 실제로 선택된 글꼴 이름이다

실험 1 (1층) — 상계와 최소상계#

정의 7의 두 조건을 그림으로 확인한다. 아래 집합은

\[ S = \left\{ \tfrac{1}{2},\ \tfrac{3}{4},\ \tfrac{7}{8},\ \tfrac{15}{16},\ \tfrac{31}{32},\ \tfrac{63}{64} \right\} \]

이며, 원소를 더 늘려도 모두 \(1\)보다 작다. 주황 점들은 상계이고, 그중 가장 왼쪽에 있는 것이 최소상계이다.

# [5회] 상계와 최소상계
# 목적 : 상계는 무수히 많고 그중 가장 작은 것이 하나임을 확인한다
# 층  : 1층
# 주의 : 유한개의 원소만 찍는다. 그림이 정의를 대신하지는 않는다

집합 = np.array([1/2, 3/4, 7/8, 15/16, 31/32, 63/64])
최소상계 = 1.0

그림,  = plt.subplots(figsize=(9, 2.6))
.scatter(집합, np.zeros_like(집합), s=45, color=["하합"], label="집합 S 의 원소", zorder=4)
상계후보 = np.linspace(1.0, 1.6, 13)
.scatter(상계후보, np.zeros_like(상계후보) + 0.05, s=28, color=["상합"],
           label="상계들", zorder=3)
.axvline(최소상계, color=["차이"], label="최소상계 sup S = 1")
.set_yticks([]); .set_xlim(0.3, 1.7); .set_ylim(-0.05, 0.12)
.set_xlabel("x"); .legend(loc="upper left")
plt.tight_layout()
plt.show()

print(f"S 의 최대 원소            : {집합.max():.6f}")
print(f"S 의 최소상계             : {최소상계:.6f}")
print(f"최소상계가 S 에 속하는가  : {최소상계 in 집합}")
../_images/1a4102b8f066cc1e13a8832e6fee94e7cca5d9d962305dc571dd8f82d7be469b.png
S 의 최대 원소            : 0.984375
S 의 최소상계             : 1.000000
최소상계가 S 에 속하는가  : False

최소상계 \(1\)이 집합에 속하지 않는다. 그런데도 최소상계이다. 이것이 최댓값과 최소상계의 차이이다.

확인할 것

  1. 주황 점의 개수는 유한하지만 실제 상계는 몇 개인가.

  2. \(1\)보다 조금이라도 작은 수를 하나 고르면, 그것보다 큰 원소가 \(S\) 안에 있는지 확인하자. 이것이 정리 13의 세 번째 조건이다.

  3. \(S\)의 최댓값은 무엇인가. 최소상계와 같은가.

실험 2 (1층) — 유리수 안에서 상계를 줄인다#

정리 15가 말하는 상황을 직접 만들어 본다. 구간을 반씩 줄여 가며 제곱이 \(2\)보다 작은 쪽과 큰 쪽을 유지한다. 왼쪽 끝은 언제나 \(S\)의 원소이고 오른쪽 끝은 언제나 상계이다.

Fraction으로 계산하므로 모든 값이 정확한 유리수이다.

# [5회] 유리수 안에서 최소상계가 존재하지 않는 예
# 목적 : S = { x : x² < 2 } 의 상계를 유리수 안에서 계속 줄여도 최소가 나오지 않음을 확인한다
# 층  : 1층 (Fraction 으로 정확히 계산한다)
# 주의 : 어느 단계에서도 제곱이 정확히 2 가 되지 않는다

왼쪽, 오른쪽 = Fraction(1), Fraction(2)

머리 = ["단계", "S 의 원소 (왼쪽)", "상계 (오른쪽)", "상계의 제곱", "제곱 = 2 인가"]
 = [5, 20, 20, 22, 14]
print(" ".join((, w) for , w in zip(머리, )))

for 단계 in range(1, 13):
    가운데 = (왼쪽 + 오른쪽) / 2
    if 가운데 * 가운데 < 2:
        왼쪽 = 가운데        # 아직 S 의 원소이다
    else:
        오른쪽 = 가운데      # 상계이다
     = [단계, 왼쪽, 오른쪽, f"{float(오른쪽**2):.15f}", 오른쪽**2 == 2]
    print(" ".join((항목, w) for 항목, w in zip(, )))
 단계     S 의 원소 (왼쪽)        상계 (오른쪽)            상계의 제곱  제곱 = 2 인가
    1                    1                  3/2      2.250000000000000          False
    2                  5/4                  3/2      2.250000000000000          False
    3                 11/8                  3/2      2.250000000000000          False
    4                 11/8                23/16      2.066406250000000          False
    5                45/32                23/16      2.066406250000000          False
    6                45/32                91/64      2.021728515625000          False
    7              181/128                91/64      2.021728515625000          False
    8              181/128              363/256      2.010635375976562          False
    9              181/128              725/512      2.005100250244141          False
   10              181/128            1449/1024      2.002335548400879          False
   11              181/128            2897/2048      2.000953912734985          False
   12              181/128            5793/4096      2.000263273715973          False

오른쪽 값은 계속 작아지지만 어느 단계에서도 멈추지 않는다. 제곱이 정확히 \(2\)가 되는 단계도 없다. 3회 정리 7에 의하여 그런 유리수가 없기 때문이다.

이 표는 최소상계가 없음을 증명하지 못한다. 열두 단계를 보였을 뿐이다. 증명은 정리 15의 (5.3)이 하며, 그 논증은 어떤 유리수 상계를 가져와도 더 작은 상계를 만들어 낸다.

확인할 것

  1. 왼쪽 값과 오른쪽 값의 분모가 단계마다 어떻게 변하는지 확인하자.

  2. 제곱 = 2 인가 열에 True가 나오는 단계가 있는가.

  3. 단계를 100까지 늘리면 True가 나올 수 있는가. 답의 근거는 이 표인가 아니면 3회의 정리인가.

실험 3 (3층) — 최소상계를 기호로 확인한다#

실험 2의 이분법이 좁혀 간 값이 무엇이었는지를 기호로 확인한다.

# [5회] 집합의 최소상계를 sympy 로 구한다
# 목적 : 이분법으로 좁혀 간 값이 무엇이었는지 기호로 확인한다
# 층  : 3층
# 주의 : sup 은 집합의 성질이다. 원소가 아닐 수 있다

x = sp.Symbol("x", real=True)

S = sp.solveset(x**2 < 2, x, domain=sp.S.Reals)
print("S = { x : x² < 2 } 의 실수 범위 해집합")
sp.pprint(S)

print(f"\n이 집합의 최소상계        : {S.sup}")
print(f"최소상계가 S 에 속하는가  : {S.sup in S}")
print(f"최소상계가 유리수인가     : {S.sup.is_rational}")
S = { x : x² < 2 } 의 실수 범위 해집합
(-√2, √2)

이 집합의 최소상계        : sqrt(2)
최소상계가 S 에 속하는가  : False
최소상계가 유리수인가     : False

최소상계는 존재하지만 집합에 속하지 않고, 유리수도 아니다. 세 결과가 각각 서술 쪽의 세 가지에 대응한다.

  • 존재한다 → 공리 1

  • 집합에 속하지 않는다 → 최댓값과 최소상계의 차이

  • 유리수가 아니다 → 3회 정리 7, 그리고 정리 15

유리수 범위에서 상계를 찾아보면 사정이 다르다.

# [5회] 유리수 상계 후보를 분모를 키워 가며 시험한다
# 목적 : 상계가 되는 유리수는 있지만 그중 최소인 것이 없음을 살펴본다
# 층  : 3층
# 주의 : 상계인 후보를 찾았다고 해서 그것이 최소상계인 것은 아니다

머리 = ["분모", "후보 q", "q 의 제곱", "상계인가"]
 = [10, 20, 20, 10]
print(" ".join((, w) for , w in zip(머리, )))

for 분모 in (10, 100, 1000, 10**6):
    q = sp.Rational(round(float(sp.sqrt(2)) * 분모), 분모)
     = [분모, q, f"{float(q**2):.12f}", bool(q**2 >= 2)]
    print(" ".join((항목, w) for 항목, w in zip(, )))
      분모               후보 q            q 의 제곱   상계인가
        10                  7/5       1.960000000000      False
       100              141/100       1.988100000000      False
      1000              707/500       1.999396000000      False
   1000000        707107/500000       2.000001237796       True

상계인 후보가 나오더라도, 정리 15의 (5.3)에 그 값을 넣으면 더 작은 유리수 상계가 언제나 만들어진다.

확인할 것

  1. 실험 3에서 최소상계가 무엇으로 나오는지 확인하자. 실험 2의 이분법이 좁혀 간 값과 같은가.

  2. 최소상계가 집합 \(S\)에 속하는지 확인하자.

  3. 최소상계가 유리수인지 확인하자. 이 결과가 3회의 정리와 어떻게 연결되는가.

짝이 되는 서술

5회 · 최소상계 원리