함수의 변환과 합성 문서의 검증 코드다. if __name__ == "__main__": 아래가 자체 테스트다.
"""함수의 변환과 합성 검증.
문서: 02.함수의 변환과 합성 (정의의 점 대응, 예제, 카드 C1·C3)
주장 1: g(x) = a·f(b(x - h)) + k이면 f 위의 점 (x0, y0)은 g 위의 점 (x0/b + h, a·y0 + k)로 간다.
주장 2: 합성은 순서를 바꾸면 결과가 달라진다. f(x) = x + 1, g(x) = x^2이면 f(g(2)) = 5, g(f(2)) = 9.
주장 3: 변환을 적용하는 순서가 바뀌면 결과 식이 달라진다 (카드 C1).
방법: 유리수(Fraction)로 정확히 계산하고, 무작위 계수 2,000세트에 대해 대입해 본다.
"""
import random
from fractions import Fraction as F
BASE = {
"x^2": lambda x: x * x,
"x^3 - x": lambda x: x ** 3 - x,
"1/(1+x^2)": lambda x: 1 / (1 + x * x),
}
def transform(f, a, b, h, k):
return lambda x: a * f(b * (x - h)) + k
def main():
rng = random.Random(1)
for name, f in BASE.items():
for _ in range(2000):
a, b, h, k = (F(rng.randint(-9, 9) or 1, rng.randint(1, 5)) for _ in range(4))
x0 = F(rng.randint(-20, 20), rng.randint(1, 7))
g = transform(f, a, b, h, k)
assert g(x0 / b + h) == a * f(x0) + k
print("[OK] 점 대응 (x0, y0) -> (x0/b + h, a·y0 + k): 함수 3개 × 무작위 2,000세트")
# 예시: f(x - 3)은 x = 3에서 f(0)을 낸다 -> 오른쪽 이동
f = BASE["x^2"]
assert transform(f, 1, 1, 3, 0)(3) == f(0)
# 예제: y = -2(x - 1)^2 + 3의 꼭짓점은 (1, 3), 아래로 열림
g = transform(f, -2, 1, 1, 3)
assert g(1) == 3 and g(0) < 3 and g(2) < 3 and g(0) == g(2) == 1
print("[OK] 예제: -2(x-1)^2 + 3의 꼭짓점 (1, 3), g(0) = g(2) = 1")
# 카드 C1: 왼쪽 2 -> 세로 3배 -> 아래로 1 = 3(x+2)^2 - 1
step1 = lambda x: f(x + 2)
step2 = lambda x: 3 * step1(x)
step3 = lambda x: step2(x) - 1
other = lambda x: 3 * (step1(x) - 1) # 아래로 1을 먼저, 세로 3배를 나중에
for x in range(-10, 11):
assert step3(x) == 3 * (x + 2) ** 2 - 1
assert other(x) == 3 * (x + 2) ** 2 - 3
print("[OK] 카드 C1: 3(x+2)^2 - 1, 순서를 바꾸면 3(x+2)^2 - 3")
# 카드 C3 / 주장 2
p = lambda x: x + 1
q = lambda x: x * x
assert p(q(2)) == 5 and q(p(2)) == 9
for x in range(-5, 6):
assert p(q(x)) == x * x + 1 and q(p(x)) == (x + 1) ** 2
print("[OK] 카드 C3: f∘g(2) = 5, g∘f(2) = 9")
# 합성의 정의역: u(x) = x - 1, v(x) = sqrt(x)이면 v∘u는 u(x)가 v의 정의역 [0, ∞)에 드는 x >= 1에서만 정의된다
import math
u = lambda x: x - 1
def works(x):
try:
math.sqrt(u(x))
return True
except ValueError:
return False
assert [x for x in range(-3, 4) if works(x)] == [1, 2, 3]
print("[OK] 합성의 정의역: sqrt(x - 1)은 x >= 1에서만 계산된다")
print("ALL CHECKS PASSED")
if __name__ == "__main__":
main()