概要
2次関数(放物線)のグラフに関する問題(高校数学)を Python で解いていきます。練習問題と解答例の作成支援を目的としています(教員向けものです)。
- 高校数学の「ベクトルの内積」関連の問題をPythonで解く
- 高校数学の「高次方程式・恒等式」関連の問題をPythonで解く
- 高校数学の「2次関数グラフ」関連の問題をPythonで解く
- 高校数学の「極限値」関連の問題をPythonで解く
- 高校数学の「微分」関連の問題をPythonで解く
問1
2次関数 $y=-2x^2+4x+1$ の頂点を求め、グラフをかけ。
問1の解答を与えるPythonプログラム
sympy と matplotlib で解決していきます。
頂点は、2次関数 $a(x-p)^2+q$ の頂点座標が $(p, q)$ となることを利用して求めています(平方完成)。
具体的には、
solve( a*(x-p)**2+q - fx, [p, q, a])
により、$a(x-p)^2+q-(-2x^2+4x+1)=0$ を $p$、$q$、$a$ について解いて、その結果から頂点座標 $(p, q)$ を求めています。
import numpy as np
import matplotlib.pyplot as plt
import sympy
# 頂点 (p,q) の座標を求める
x,a,p,q = sympy.symbols('x a p q')
fx = -2*x**2 + 4*x + 1
v = sympy.solve( a*(x-p)**2+q - fx, [p, q, a])
p = v[0][0]
q = v[0][1]
print(f'頂点は ({p},{q}) で、グラフは以下の通りである。')
# グラフを描く
xRange=(-4,4) # グラフ描画範囲
f = lambda x : -2*x**2 + 4*x + 1 # 関数
x = np.linspace(xRange[0], xRange[1], 100)
y = f(x)
plt.figure(dpi=120)
plt.plot(x, y, color='0.0')
plt.plot(p, q, marker='o')
plt.grid(color='0.8')
plt.show()
実行結果
頂点は (1,3) で、グラフは以下の通りである。
問2
2次関数 $y=x^2+x-6$ について以下の問いに答えよ。
(1) $y=x^2+x-6$ のグラフをかけ。
(2) 2次不等式を $y=x^2+x-6 < 0$ を満たす $x$ の範囲を求めよ。
問2の解答を与えるPythonプログラム
この問題では、$x$ 軸との交点、つまり、$y=0$ となるような $x$ を求める必要があります。これは、sympy.solve( fx )
で求めることができます。なお、実数解のみを対象とするために、sympy.symbols('x a p q', real=True)
のようなオプションをつけています。このオプションをつけないと、虚数を含んだ解がでてきてしまいます。
また、$y<0$ の範囲領域を図示するために、plt.fill_between(x, y, 0, where=y<0, facecolor='b', alpha=0.2)
を行なってます。
import numpy as np
import matplotlib.pyplot as plt
import sympy
# 頂点 (p,q) の座標を求める
x,a,p,q = sympy.symbols('x a p q', real=True)
fx = x**2 + x - 6 # 関数
v = sympy.solve( a*(x-p)**2+q - fx, [p, q, a])
p = v[0][0]
q = v[0][1]
print(f'(1) 頂点は ({p},{q}) で、', end='' )
# x軸との交点を求める
sol = sympy.solve( fx )
if len(sol) == 0 : # 実数解が存在しない
print('x軸とは交わらない。', end='' )
else :
tx = ' と '.join(list(map(lambda x: '({0},0)'.format(x), sol)))
print(f'x軸との交点は {tx} となる。', end='' )
print('グラフは以下の通りである')
# グラフを描く
xRange=(-4,4) # グラフ描画範囲
f = lambda x : x**2 + x - 6 # 関数
x = np.linspace(xRange[0], xRange[1], 100)
y = f(x)
plt.figure(dpi=120)
plt.plot(x, y, color='0.0')
plt.plot(p, q, marker='o')
if len(sol) != 0 :
plt.hlines([0], xRange[0], xRange[1], linewidth=0.75 )
for s in sol :
plt.plot(s, 0, marker='o', color='0.0')
plt.fill_between(x, y, 0, where=y<0, facecolor='b', alpha=0.2)
plt.grid(color='0.8')
plt.show()
print('(2) 不等式を満たす xの範囲は、',end='')
if len(sol) == 2 :
if sol[0]>sol[1] :
print(f'{sol[1]} < x < {sol[0]} である。')
else :
print(f'{sol[0]} < x < {sol[1]} である。')
else:
print('存在しない')
実行結果
(1) 頂点は (-1/2,-25/4) で、x軸との交点は (-3,0) と (2,0) となる。グラフは以下の通りである
(2) 不等式を満たす xの範囲は、-3 < x < 2 である。
問3
2次関数 $y=x^2+x+1$ について以下の問いに答えよ。
(1) $y=x^2+x+1$ のグラフをかけ。
(2) 2次不等式を $y=x^2+x+1 < 0$ を満たす $x$ の範囲を求めよ。
問3の解答を与えるPythonプログラム
問2のプログラムがそのまま利用できます(#関数
のコメントが付いている2行については書き換えてください)。
実行結果
(1) 頂点は (-1/2,3/4) で、x軸とは交わらない。グラフは以下の通りである
(2) 不等式を満たす xの範囲は、存在しない
グラフをきれいに描画
印刷物などでも使えるような整形したグラフ(SVG)を出力するように手を加えたものです。ただし、問題毎に範囲などを細かく微調整する必要があります。
import numpy as np
import matplotlib.pyplot as plt
import sympy
# 頂点 (p,q) の座標を求める
x,a,p,q = sympy.symbols('x a p q', real=True)
fx = x**2 + x - 6 # 関数
v = sympy.solve( a*(x-p)**2+q - fx, [p, q, a])
p = v[0][0]
q = v[0][1]
print(f'(1) 頂点は ({p},{q}) で、', end='' )
# x軸との交点を求める
sol = sympy.solve( fx )
if len(sol) == 0 : # 実数解が存在しない
print('x軸とは交わらない。', end='' )
else :
tx = ' と '.join(list(map(lambda x: '({0},0)'.format(x), sol)))
print(f'x軸との交点は {tx} となる。', end='' )
print('グラフは以下の通りである')
# グラフを描く
xRange=(-5,5) # グラフ描画範囲 x
yRange=(-8,2) # グラフ描画範囲 y
f = lambda x : x**2 + x - 6 # 関数
x = np.linspace(xRange[0], xRange[1], 100)
y = f(x)
plt.figure(figsize=(5,5), dpi=120)
plt.plot(x, y, color='0.0')
plt.plot(p, q, marker='o')
plt.hlines([0], xRange[0], xRange[1], linewidth=0.75 )
plt.vlines([0], yRange[0], yRange[1], linewidth=0.75 )
if len(sol) != 0 :
for s in sol :
plt.plot(s, 0, marker='o', color='0.0')
plt.fill_between(x, y, 0, where=y<0, facecolor='b', alpha=0.2)
plt.grid(color='0.8')
plt.xlim(xRange[0], xRange[1])
plt.xticks(range(xRange[0], xRange[1]+1, 1))
plt.ylim(yRange[0], yRange[1])
plt.yticks(range(yRange[0], yRange[1]+1, 1))
plt.savefig('test.svg',format = 'svg'); # SVG形式で出力
plt.show()
print('(2) 不等式を満たす xの範囲は、',end='')
if len(sol) == 2 :
if sol[0]>sol[1] :
print(f'{sol[1]} < x < {sol[0]} である。')
else :
print(f'{sol[0]} < x < {sol[1]} である。')
else:
print('存在しない')