代入して方程式の解を求める典型的な問題です.
一歩づつ,出力しながら変形していくのがコツ. 数式処理ソフトはやり方を教えないと動かないよ.
代入: subs
展開: expand
方程式の解: solve(eq, a)
sympyでは方程式の解solveに渡す式(eq)=0が成り立つ未知数(a)をとく.eqにはあらかじめ0となるように右辺を移項した式を求めておく必要がある.
from sympy import *
init_session()
IPython console for SymPy 1.6.1 (Python 3.8.3-64-bit) (ground types: gmpy) These commands were executed: >>> from __future__ import division >>> from sympy import * >>> x, y, z, t = symbols('x y z t') >>> k, m, n = symbols('k m n', integer=True) >>> f, g, h = symbols('f g h', cls=Function) >>> init_printing() Documentation can be found at https://docs.sympy.org/1.6.1/
x,a = symbols('x a')
P = x*(x+3)*(2*x-3)
P0 = expand(P.subs({x:a+1}))
P0
P1 = expand(P.subs({x:a}))
P1
eq1 = (P0-P1)/2
eq1
solve(eq1,a)
高校の一年生の時にやる平方完成ですが,sympyに限らず数式処理ソフトは苦手なようです.微分して頂点の座標を求めて作って行きます.
from sympy import *
init_session()
x = symbols('x')
f = x**2+3*x-2
eq1 = diff(f,x)
eq1
IPython console for SymPy 1.6.1 (Python 3.8.3-64-bit) (ground types: gmpy) These commands were executed: >>> from __future__ import division >>> from sympy import * >>> x, y, z, t = symbols('x y z t') >>> k, m, n = symbols('k m n', integer=True) >>> f, g, h = symbols('f g h', cls=Function) >>> init_printing() Documentation can be found at https://docs.sympy.org/1.6.1/
solve(eq1,x)
f.subs({x:-3/2})
solve(f,x)
def l_y(x, x1):
m = diff(f,x)
eq = m.subs({x:x1})*(x-x1)+f.subs({x:x1})
return eq
print(l_y(x,2))
7*x - 6
%matplotlib inline
plot(f,l_y(x,2), (x,-4,4))
<sympy.plotting.plot.Plot at 0x7fb6ab7ce670>
頂点を一致させる問題です.1番の問題と本質的には同じなんですが,未知数が二つになったので途端に見通しが悪くなります.
一般の解答例では,紙面の都合上,解の導出を短く表示していますが,解いていく最中では,一つ一つ積み上げていってます.解答例を見ながら,「かっこの中側から打つ」ということの意味を理解して,実践してください.
from sympy import *
#init_session()
init_printing()
まずは二つの曲線の方程式をy1, y2として打ち込みます.変数として宣言しとくことを忘れないように.
x, y,a,b = symbols('x y a b')
y1 = 4*x**2-8*x+5
y2 = -2*(x+a)**2+b
y1の頂点を求めます.微分して傾きがゼロになるxをx0とします. [0]は配列の中身を取り出すためです.
x0=solve(diff(y1,x),x)[0]
x0
これ(x=x0)をy1に代入して,その値をy0とします.
y0 = y1.subs({x:x0})
y0
x=x0でy2が頂点となるようなa0を求めます.
a0=solve(solve(diff(y2,x),x)[0]-x0,a)[0]
a0
一度にやると上のようですが,これの中身を見て,一つ一つのstepをsympyに教えてやっているのを見盗ってください.
diff(y2,x)
solve(diff(y2,x),x)
solve(diff(y2,x),x)[0]
solve(diff(y2,x),x)[0]-x0
solve(solve(diff(y2,x),x)[0]-x0,a)
solve(solve(diff(y2,x),x)[0]-x0,a)[0]
出てきた答えをそのまま次のステップの代入にして,次々と操作を加えていく様子が見えますでしょうか?
わからんようになったら,間の結果を変数として取り出して,それを次の式に代入(subs)していくと見やすいです.
b0 =solve((y2-y0).subs({a:a0}).subs({x:x0}),b)[0]
b0
%matplotlib inline
line_1 = y1
line_2 = y2.subs({a:a0}).subs({b:b0})
line_2
plot(line_1, line_2, (x,-1,3))
<sympy.plotting.plot.Plot at 0x7fb6ab843070>
こういった問題では,判別式を使った解法を指導しているというTAさんからの指導(?)があったんで,やって見た.
from sympy import *
init_session()
IPython console for SymPy 1.6.1 (Python 3.8.3-64-bit) (ground types: gmpy) These commands were executed: >>> from __future__ import division >>> from sympy import * >>> x, y, z, t = symbols('x y z t') >>> k, m, n = symbols('k m n', integer=True) >>> f, g, h = symbols('f g h', cls=Function) >>> init_printing() Documentation can be found at https://docs.sympy.org/1.6.1/
x, y,a,b = symbols('x y a b')
y1 = 4*x**2-8*x+5
y2 = -2*(x+a)**2+b
y3 = expand(y1-y2)
y3
cc=y3.coeff(x,0)
bb=y3.coeff(x,1)
aa=y3.coeff(x,2)
print(aa,bb,cc)
6 4*a - 8 2*a**2 - b + 5
expand(bb**2-4*aa*cc)
頂点を代数式で出す問題で,式変形が必要になる典型的な問題です.factorとかsimplifyとかは試行錯誤が必要です.fractionは分数式での基本となるやり方なんで,idiom的に覚えてください.
代入: subs
展開: expand
簡単化: simplify
通分: together
因数分解:factor
分数: fraction
分母: d(enominator)
分子: n(umerator)
from sympy import *
#init_session()
init_printing()
x, y,a,b = symbols('x y a b')
y = a*x**2-b*x-a+b
y.subs({x:-2})-6
b0=solve(y.subs({x:-2})-6,b)
b0
df = diff(y,x)
df
s1 = solve(df,x)
s1
x0 = s1[0].subs({b:b0[0]})
x0
simplify((y.subs({x:x0}).subs({b:b0[0]})))
簡単化しなさいというのに反応していない典型的な例です.まぁ,簡単というのは人間とコンピュータで違うのでしょうね.地道にばらして,教えて行きましょう.
eq2 = together((y.subs({x:x0}).subs({b:b0[0]})))
eq2
n,d = fraction(eq2)
factor(expand(n))
時々sympyとの意見があって,スパッと綺麗にしてくれることがあります.たまにです.嬉しくなりますが...
factor(together((y.subs({x:x0}).subs({b:b0[0]}))))