---
jupytext:
  formats: md:myst
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
kernelspec:
  display_name: Python 3
  language: python
  name: python3
---

# 1회 실험 · 아르키메데스의 구적법

```{admonition} 이 실험
:class: seealso

| | |
|---|---|
| **짝 서술** | {doc}`L01` |
| **실험 목록** | 실험 1 (1층) — 안쪽과 바깥쪽 / 실험 2 (3층) — 정확한 식 |
```

## 계산의 세 종류

앞으로 나오는 계산은 세 종류이다.

첫째는 정의를 그대로 옮긴 계산이다. 서술 쪽에서 세운 식을 코드로 다시 쓴 것이며, 이 강의의 주된 계산이다. `numpy`와 직접 구현한 함수를 쓴다. 이것을 **1층**이라 부른다.

둘째는 다른 방법으로 같은 값을 구해 대조하는 계산이다. 직접 구현한 코드에 오류가 있을 수 있으므로 독립적으로 계산한 값과 비교한다. `scipy`를 쓴다. 이것이 **2층**이다.

셋째는 유한한 $n$에 대한 정확한 식을 구하는 계산이다. 부동소수로 계산하면 $0.333328\ldots$ 같은 값이 나오지만, 기호로 계산하면 $\frac{1}{3}-\frac{1}{2n}+\frac{1}{6n^2}$ 같은 식이 나온다. 식의 형태에서 오차가 어디서 오는지 읽을 수 있다. `sympy`를 쓴다. 이것이 **3층**이다.

**언제나 1층을 먼저 제시한다.** 라이브러리를 먼저 부르면 정의가 무엇을 하는지 보이지 않는다. 코드 조각마다 머리말에 어느 층인지 적어 둔다.

```{code-cell} ipython3
:tags: [hide-input]

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

from calc_viz import 함수그리기, 계단함수그리기, 무대, 수치표, 색
from calc_style import 한글글꼴설정

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

## 실험 1 (1층) — 안쪽과 바깥쪽

서술 쪽 (1.3)과 (1.4)를 그대로 옮긴다. 구간 $[0,b]$를 $n$등분하고, 각 부분구간에서 왼쪽 끝값을 높이로 하는 직사각형과 오른쪽 끝값을 높이로 하는 직사각형을 각각 세운다.

바깥쪽을 먼저 그리고 안쪽을 그 위에 겹쳐 그린다. 그러면 **파란 몸통이 안쪽 넓이 $s_n$이고, 그 위에 남는 주황 띠가 두 넓이의 차이 $S_n - s_n$**이 된다. 주황 띠 전체를 포함한 도형이 바깥쪽 넓이 $S_n$이다.

```{code-cell} ipython3
# [1회] 포물선 아래 영역의 안쪽 근사와 바깥쪽 근사
# 목적 : 두 근사값 사이에 참값이 있다는 것과, 차이가 얼마인지 확인한다
# 층  : 1층
# 주의 : 극한을 쓰지 않는다. 유한한 n 에 대한 계산만 한다

f = lambda x: x**2
b = 1.0

for n in (4, 10, 40):
    그림, 축 = plt.subplots(figsize=(4.6, 4.6))
    계단함수그리기(축, f, 0, b, n, 위치="위")     # 바깥쪽 S_n
    계단함수그리기(축, f, 0, b, n, 위치="아래")   # 안쪽 s_n
    함수그리기(축, f, 0, b)
    무대(축, 0, b, f"n = {n}", y범위=(0, 1.1))
    plt.show()

    분할점 = np.linspace(0, b, n + 1)
    안쪽 = float(np.sum(f(분할점[:-1]) * (b / n)))   # 왼쪽 끝값이 최솟값이다
    바깥쪽 = float(np.sum(f(분할점[1:]) * (b / n)))  # 오른쪽 끝값이 최댓값이다
    수치표(f"n = {n}", {
        "안쪽 s_n": 안쪽,
        "바깥쪽 S_n": 바깥쪽,
        "차이 S_n - s_n": 바깥쪽 - 안쪽,
        "b^3 / n": b**3 / n,
        "s_n < 1/3 < S_n": 안쪽 < 1/3 < 바깥쪽,
    })
```

```{admonition} 확인할 것
:class: tip
1. 세 그림에서 파랑 도형이 곡선 아래에, 주황 도형이 곡선 위에 놓이는지 확인하자. 두 도형이 겹치는 부분과 겹치지 않는 부분을 구분해 보자.
2. $n$을 4에서 10으로, 10에서 40으로 늘렸을 때 `차이 S_n - s_n`이 어떻게 변하는지 확인하자. 그 값이 `b^3 / n`과 일치하는가.
3. 세 경우 모두에서 `s_n < 1/3 < S_n`이 참인지 확인하자. 이것이 서술 쪽 (1.10)이 말하는 내용이다.
```

## 실험 2 (3층) — 정확한 식

실험 1은 부동소수로 계산한 값을 준다. $n = 40$일 때 안쪽이 $0.3209375$라는 것은 알 수 있지만, 그 값이 $1/3$에서 정확히 얼마나 떨어져 있는지는 수치만으로는 확정할 수 없다.

기호로 계산하면 $n$에 대한 식이 나온다. 식의 형태에서 오차의 정체가 읽힌다.

```{code-cell} ipython3
# [1회] 안쪽과 바깥쪽 넓이의 정확한 식
# 목적 : n 에 대한 식으로 두 넓이를 쓰고, 차이가 정확히 b³/n 임을 확인한다
# 층  : 3층
# 주의 : 극한을 취하지 않는다. n 은 유한한 값으로 둔다

from calc_sym import 균등분할_상합하합, 보이기, x, n, b

하합, 상합 = 균등분할_상합하합(x**2, x, 0, b, 증가함수=True)

보이기("안쪽 s_n", 하합)
보이기("바깥쪽 S_n", 상합)
보이기("차이 S_n - s_n", 상합 - 하합)
```

$b^3/3$과의 거리도 식으로 얻을 수 있다.

```{code-cell} ipython3
# [1회] 참값과의 거리
# 목적 : b³/3 이 두 값 사이에 있음을 식으로 확인한다
# 층  : 3층
# 주의 : 두 식이 모두 양수임을 분자와 분모의 부호로 판단한다

보이기("b³/3 − s_n", sp.simplify(b**3 / 3 - 하합))
보이기("S_n − b³/3", sp.simplify(상합 - b**3 / 3))
```

두 식의 분모는 $6n^2$으로 양수이고, 분자는 각각 $b^3(3n-1)$과 $b^3(3n+1)$이다. $n \ge 1$이고 $b > 0$이면 둘 다 양수이다. 이것이 서술 쪽 (1.11)에서 손으로 확인한 것과 같다.

이제 실험 1의 수치와 대조한다.

```{code-cell} ipython3
# [1회] 1층과 3층의 대조
# 목적 : 정확한 식에 n 을 대입한 값이 실험 1 의 수치와 일치하는지 확인한다
# 층  : 1층 + 3층
# 주의 : 두 계산은 서로 독립이다. 일치해야 정의를 옳게 옮긴 것이다

from calc_viz import 칸   # 한글이 섞인 표의 열을 맞춘다

머리 = ["n", "1층 안쪽", "3층 s_n", "1층 바깥쪽", "3층 S_n", "일치"]
폭 = [4, 15, 15, 15, 15, 6]
print(" ".join(칸(글, w) for 글, w in zip(머리, 폭)))

for 값 in (4, 10, 40):
    분할점 = np.linspace(0, 1, 값 + 1)
    안 = float(np.sum(분할점[:-1]**2 * (1 / 값)))
    밖 = float(np.sum(분할점[1:]**2 * (1 / 값)))
    L = float(하합.subs({b: 1, n: 값}))
    U = float(상합.subs({b: 1, n: 값}))
    같음 = abs(안 - L) < 1e-12 and abs(밖 - U) < 1e-12
    줄 = [값, f"{안:.8f}", f"{L:.8f}", f"{밖:.8f}", f"{U:.8f}", 같음]
    print(" ".join(칸(값하나, w) for 값하나, w in zip(줄, 폭)))
```

```{admonition} 확인할 것
:class: tip
1. 실험 2의 $s_n$과 $S_n$에 $n=10$, $b=1$을 대입한 값이 실험 1의 수치와 일치하는지 확인하자.
2. $b^3/3 - s_n$의 식이 항상 양수인지 확인하자. $n$이 자연수일 때 분자와 분모의 부호를 각각 살펴보자.
3. $S_n - s_n$이 정확히 $b^3/n$인지 확인하자. 근사가 아니라 정확한 등식인가.
```

```{admonition} 이 계산이 무엇에 의존하는가
:class: warning

`균등분할_상합하합`은 내부에서 $\sum k^2$의 합을 구한다. 서술 쪽 (1.5)에서 결과만 인용하고 넘어간 그 공식이다. 즉 실험 2는 아직 유도하지 않은 공식에 기대고 있다.

기호 계산이 답을 준다고 해서 그 답의 근거까지 확보된 것은 아니다. 공식의 유도는 뒤에서 따로 다룬다.
```

```{admonition} 짝이 되는 서술
:class: note
{doc}`L01`
```
