『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

【SymPy】関数の極限値

関数の極限値

関数 f(x) について、変数 x を限りなく a の値に近づけるときに f(x) が唯一の値 L に近づくならば、Lf(x)極限値 とよび、次のような記号で表します。
 limxaf(x)=L
たとえば f(x)=x2+c について、x を限りなく 1 に近づけたときの f(x) の極限値は f(1)=1+c となります:
 limx1(x2+c)=1+c
極限値が常に存在するとは限りません。たとえば sinx11 の間を振動する周期関数なので、x+ の極限値を定めることができません。

sympy.limit()

SymPy パッケージsympy.limit() を使うと関数の極限値を得ることができます。
たとえば、limxaf(x) は次のように記述します。

sympy.limit(f(x), x, a)

解析学で有名な極限公式
 
limx0sinxx=1
を確認してみましょう。

# SYMPY_LIMIT_SINX/X

# In[1]

# sympyをインポート
import sympy

# 記号xを定義
sympy.var('x')

# y=sinx/x
y = sympy.sin(x)/x

# x→0の極限値
lim_y = sympy.limit(y, x, 0)

print(lim_y)

# y=sinx/xのグラフをプロット
p = sympy.plot(y, (x, -12, 12), ylabel="y")

# 1

極限値の計算:sympy.limit()
微分積分学では次の極限公式もよく登場します。
 limx0tanxx=1limx01cosxx2=12 

# In[2]

# f(x)とg(x)を定義
fx = sympy.tan(x)/x
gx = (1-sympy.cos(x)) / x**2

# xを0に近づけたときのf(x)とg(x)の極限値
lim_fx = sympy.limit(fx, x, 0)
lim_gx = sympy.limit(gx, x, 0)

print([lim_fx, lim_gx])
# [1, 1/2]

xsin(1/x) は振動しながら原点に収束する関数です。
 
limx0xsin1x=0 

# In[3]

# y=sin(1/x)
y = x * sympy.sin(1/x)

# xを0に近づけた時のsin(1/x)の極限値
lim_y = sympy.limit(y, x, 0)

print(lim_y)

# y=sin(1/x)のグラフをプロット
p = sympy.plot(y, (x, -0.1, 0.1), ylabel = "y", line_color="red")
# 0

振動関数の極限値:sympy.limit()

極限値が存在しない場合

sinxx の極限値をもちませんが、その場合でも 1 から 1 の間で振動することを <-1, 1> のような記号で表示します。SymPy においては、極限値が一定範囲で振動する状況を AccumBounds() オブジェクトで表現します。

# SYMPY_LIMIT_OSCILLATE

# In[1]

import sympy

# シンボルxを定義
sympy.var('x')

# 無限大のシンボルを定義
oo = sympy.oo

# f(x)=sinx
fx = sympy.sin(x)

# xを0に近づけた時のsinxの極限値
lim_fx = sympy.limit(fx, x, oo)

# 極限値は定まらず-1から1の間を振動するのでAccumBoundsオブジェクトが返る
print(lim_fx)

# AccumBounds(-1, 1)

右側極限と左側極限

解析学では関数 f(x) がある値 ax 軸の正の方向から近づくときの極限値を右側極限、負の方向から近づくときの極限値を左側極限とよび、それぞれ limxa+0f(x), limxa0f(x) と表します。たとえば tanx は右側から π/2 に近づくと 、左側から π/2 に近づくと という極限値をとります。sympy.limit() の第 4 引数に ‘+’ を渡すと右側極限を、’-‘ を渡すと左側極限を返します。

# SYMPY_LIMIT_RIGHT_LEFT

# In[1]

import sympy

# 記号xを定義
sympy.var('x')

# 無限大の定義
oo = sympy.oo

# 円周率の定義
pi = sympy.pi

# f(x)=tan(x)
fx = sympy.tan(x)

# tanxの右側極限
lim_fx_right = sympy.limit(fx, x, pi/2, '+')

# tanxの左側極限
lim_fx_left = sympy.limit(fx, x, pi/2, '-')

print("右側極限 {}".format(lim_fx_right))
print("左側極限 {}".format(lim_fx_left))

# 右側極限 -oo
# 左側極限 oo

コメント

  1. HNaito より:

    下記は誤植と思われますので、ご確認ください。
    LIMIT_01 In[1] プログラムで、lim_y = sympy.limit(fx, x, 0) → lim_y = sympy.limit(y, x, 0)

    sympy.plot の xlabel と ylabel の位置が、以前は xlabel は x軸の右端、ylabel は y軸の上端でしたが、最近の Google Colab では x軸、y軸のそれぞれ中央に変更されたようです。 今回のようなプラス、マイナスの両方向に均等に座標が伸びているグラフでは、座標軸とラベルが重なってしまいます。xlable や ylabel の位置を指定する方法などはありましたでしょうか?

    LIMIT_02 In[1] プログラムの実行結果は、AccumBounds(-1, 1)となり、print文を使わずに、コードの末尾に sympy.limit(fx, s, oo)を置いて実行すると、⟨−1,1⟩が表示されました。

    • あとりえこばと より:

      Jupyter Notebook でも同様の現象が確認されました。
      SymPy のバージョンアップが原因かもしれないと思ってダウングレードも試してみましたが、改善されませんでした。Google Colab と Jupyter Notebook はどちらも IPython カーネルを利用するので、IPython に設計変更がなされた可能性があります。今、色々と試行錯誤していますが、今のところ解決策は見つかっていません。申し訳ないです。

      LIMIT_02 In[1] のプログラムの動作を再確認しました。AccumBounds は有限区間を表すためのクラスです。AccumBounds(-1, 1) は -1 から 1 のいずれかの範囲をとるという意味です。

      import sympy
       
      #区間[0,1]オブジェクトを生成
      interval = sympy.AccumBounds(-1, 1)
       
      print(interval)
      # AccumBounds(-1,1)


      SymPy のバージョンアップに伴って、極限値が定まらず、かつその範囲が有限である場合に、AccumBounds() オブジェクトを返すようになったのだと思います。