2
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

高校数学の「2次関数グラフ」関連の問題をPythonで解く

Last updated at Posted at 2019-07-25

概要

 2次関数(放物線)のグラフに関する問題(高校数学)を 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)$ を求めています。

Python
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) で、グラフは以下の通りである。

無題.png

問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) を行なってます。

Python
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 である。

無題.png

問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の範囲は、存在しない

無題.png

グラフをきれいに描画

印刷物などでも使えるような整形したグラフ(SVG)を出力するように手を加えたものです。ただし、問題毎に範囲などを細かく微調整する必要があります。

無題.png

Python
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('存在しない')
2
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?