🔖
東工大機械系院試をpythonで解いてみた[数学編]
はじめに
東工大の機械系の院試の問題をpythonを使って解いてみます。今回は令和3年度の数学の試験を解いていきます。過去問は以下のページにあります。
問1
問1 (1)
回転体の体積を求める問題です。まず図を書いてみます。
import matplotlib.pyplot as plt
import numpy as np
#仮の値
a = 2
b = 5
# 円のパラメータ
center = (0, b)
radius = a
# 円の点を生成
theta = np.linspace(0, 2*np.pi, 100)
x = center[0] + radius * np.cos(theta)
y = center[1] + radius * np.sin(theta)
# プロット
plt.figure(figsize=(6,6))
plt.plot(x, y)
plt.plot(np.linspace(-10, 10,100), np.linspace(-10, 10,100),linestyle='--')
plt.scatter(*center, color='red', label=f'Center (0,b)')
plt.axhline(0, color='grey', linewidth=0.5)
plt.axvline(0, color='grey', linewidth=0.5)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Circle and Line')
plt.xlim(-10, 10)
plt.ylim(-10, 10)
plt.xticks([])
plt.yticks([])
plt.legend(loc='upper left')
plt.show()
このままでは体積を求めるのは難しいので、座標を-45度回転させます。
# 座標を与えられた角度で回転させる関数
def rotate_point(x, y, angle_deg):
angle_rad = np.radians(angle_deg) # 角度をラジアンに変換
x_rot = x * np.cos(angle_rad) - y * np.sin(angle_rad) # x座標の回転
y_rot = x * np.sin(angle_rad) + y * np.cos(angle_rad) # y座標の回転
return x_rot, y_rot
# y=xの直線を-45度回転させる
x_line = np.linspace(-10, 10, 100)
y_line = np.linspace(-10, 10, 100)
x_line_rot, y_line_rot = rotate_point(x_line, y_line, -45)
# 円と直線を-45度回転させる
x_rot, y_rot = rotate_point(x, y, -45)
# プロット
plt.figure(figsize=(6,6))
plt.plot(x_rot, y_rot) # 回転した円をプロット
plt.plot(x_line_rot, y_line_rot, linestyle='--') # 回転した直線をプロット
plt.scatter(*rotate_point(center[0], center[1], -45), color='red', label=f'Center (b/√2,b/√2)') # 回転した円の中心をプロット
plt.axhline(0, color='grey', linewidth=0.5)
plt.axvline(0, color='grey', linewidth=0.5)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Rotated Circle and Line')
plt.xlim(-10, 10)
plt.ylim(-10, 10)
plt.xticks([])
plt.yticks([])
plt.legend(loc='upper left')
plt.show()
さらにx軸方向に平行移動させます。
# 回転後の新しい中心座標を計算
new_center = rotate_point(center[0], center[1], -45)
# 新しい中心のx座標を0に移動するために必要な平行移動を計算
translation_x = -new_center[0]
# 回転した円を平行移動
x_translated = x_rot + translation_x
# プロット
plt.figure(figsize=(6,6))
plt.plot(x_translated, y_rot)
plt.plot(x_line_rot, y_line_rot, linestyle='--')
plt.scatter(0, new_center[1], color='red', label=f'Center (0,b/√2)')
plt.axhline(0, color='grey', linewidth=0.5)
plt.axvline(0, color='grey', linewidth=0.5)
plt.gca().set_aspect('equal', adjustable='box')
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.title('Translated Rotated Circle and Line')
plt.xlim(-10, 10)
plt.ylim(-10, 10)
plt.xticks([])
plt.yticks([])
plt.legend(loc='upper left')
plt.show()
この円で囲まれた領域をx軸回りに回転させれば答えが求まります。
領域の方程式をyについて解くと、
回転体の体積は次のように表されます。
それでは計算します。
from sympy import symbols, pi, integrate, sqrt
# 変数を定義
x = symbols('x')
a, b = symbols('a b', positive=True, real=True)
# 円盤の半径を定義
y_1= b/sqrt(2) + sqrt(a**2 - x**2)
y_2= b/sqrt(2) - sqrt(a**2 - x**2)
# 微小なスライスの体積の式を定義
dV = pi * (y_1**2 -y_2**2)
# -aからaまでの式を積分
V = integrate(dV, (x, -a, a))
V
よって答えは
となります。
問1 (2)
同次形の微分方程式の問題です。
from sympy import symbols, Function, Eq, diff, dsolve, tan
# 変数と関数を定義する
x, C1 = symbols('x C1')
y = Function('y')(x)
u = x + y
# 元の微分方程式 dy/dx = (x+y)^2
dy_dx_original = u**2
# u の微分方程式
du_dx = 1 + dy_dx_original
# u の微分方程式を解く
u = Function('u')(x)
differential_equation_for_u = Eq(diff(u, x), u**2 + 1)
general_solution_for_u = dsolve(differential_equation_for_u)
# y(x) に変換する
y_general_solution = general_solution_for_u.rhs - x
print('y=',y_general_solution)
答えは
となります。
問2
問2(1)
import numpy as np
# 行列Aを定義
A = np.array([[2, 1], [1, 2]])
# 固有値と固有ベクトルを計算
eigenvalues, eigenvectors = np.linalg.eig(A)
# 固有ベクトルを正規化
normalized_eigenvectors = eigenvectors / np.linalg.norm(eigenvectors, axis=0)
print(eigenvalues)#固有値
print(normalized_eigenvectors)#固有ベクトル
#出力結果
[3. 1.]
[[ 0.70710678 -0.70710678]
[ 0.70710678 0.70710678]]
問2(2)
正則行列Pを用いて、行列Aを
と対角化することで、行列Aのn乗は
と求めることができます。
import numpy as np
from sympy import symbols, Matrix
# 自然数nを定義
n = symbols('n', integer=True, positive=True)
# 行列Aを定義
A = np.array([[2, 1], [1, 2]])
# Aの固有値と固有ベクトルを計算
eigenvalues, eigenvectors = np.linalg.eig(A)
# 固有ベクトルを正規化
eigenvectors = eigenvectors / np.linalg.norm(eigenvectors, axis=0)
# 行列Pを構成
P = Matrix(eigenvectors)
# 対角行列Dを構成
D = Matrix(np.diag(eigenvalues))
# Pの逆行列を計算
P_inv = P.inv()
# A^nを計算
A_n = P * D**n * P_inv
A_n
よって
となります。
問3
問3(1)
テイラー展開において、0周りでのべき級数展開を考えたものがマクローリン展開なので、
from sympy import symbols, diff, series
z = symbols('z')
f = 1/(1+z)
f_series = series(f, z, 0, 10)
f_series
答えは
となります。
問3(2)
試験ではローラン展開を行って留数を求めますが、ここでは residue 関数を使用します。
from sympy import symbols, exp, residue
z = symbols('z')
f = 1/(z*(exp(z) - 1))
res = residue(f, z, 0)
res
答えは
となります。
問4
問4(1)
複素フーリエ級数
よって
from sympy import symbols, integrate, exp, pi, I
x = symbols('x')
n = symbols('n', integer=True)
# p(x)(-0.5<=x<=0.5)を定義
p = 1
# 周期Tを定義
T = 2
# 複素フーリエ係数c_nを計算,p(x)の定義より積分範囲は(-0.5, 0.5)
c_n = (1/T) * integrate(p * exp(-I * 2*pi*n*x/T), (x, -0.5, 0.5))
# n = 0, 1, 2, 3の場合のc_nを計算
c_n_values = [c_n.subs(n, i) for i in range(4)]
# c_nの式を展開して簡単化
c_n_simplified = [c.expand(complex=True).simplify() for c in c_n_values]
c_n_simplified
答えは
となります。
問4(2)
パーシヴァルの等式より、
def C(n):#(C_-3)^2から(C_3)^2まで定義
c_n_numerical = [0.5, 1/pi, 0, -1/(3*pi)]
return c_n_numerical[abs(n) % 4]**2
def sigma(func, frm, to):#Σを定義
result = 0;
for i in range(frm, to+1):
result += func(i)
return result
ans=2*sigma(C, -3, 3)
ans
答えは
となります。
まとめ
すべての問題をpythonを使って解くことができました。
既存の関数で一発で答えが出せるものもあって驚きました。
Discussion