SymPy Plotting Backends で”少し込み入った関数”を plot()
するとき,思いもかけずにエラーとなった場合の対応。
以下の Issue で回答があった件:
必要なモジュールの import
from sympy import *
from sympy.abc import *
from spb import *
# グラフを SVG で Notebook にインライン表示
%config InlineBackend.figure_formats = ['svg']
関数の定義の中に if
文がある例
実際に「補足:SymPy と SPB で宇宙年齢のグラフを描く」のページでエラーが出て困った。宇宙年齢は密度パラメータ $\Omega_{\rm m}$ の関数であるが,曲率定数 $k$ の符号によって関数形が変わる。そのため,1個の関数で全ての $k$ の場合の宇宙年齢を $\Omega_{\rm m}$ の関数としてあらわそうとすると,if
文が必要になり,最初なぜエラーになるのかわからなかったので,備忘録としてメモ。
例えば,以下のような例。
def f(x):
if x < 0:
return -x
else:
return x
以下のように plot()
しようとするとエラーになる。
plot(f(x), (x, -2, 2));
傾向と対策
通常ならば
plot(f(x), (x, -2, 2))
とするところだが,関数 f(x)
の定義が少し込み入っていて if
文がある場合,これだとエラーになる。
対策は,
- 関数名のみにする(かっこや引数は省略する)
force_real_eval=True
のオプションをつける
つまり,以下のようにすればよい。
plot(f, (x, -2, 2), force_real_eval=True)
# plot(f(x), (x, -2, 2)) ではなくて...
plot(f, (x, -2, 2), force_real_eval=True);
関数の定義の中に数値解法の nsolve()
がある例
例えば,以下のような例。
def g(x):
return nsolve(sin(t)-x, t, 0)
以下のように plot() しようとするとエラーになる。
plot(g(x), (x, -1, 1));
傾向と対策
通常ならば
plot(g(x), (x, -1, 1))
とするところだが,関数 g(x)
の定義が少し込み入っていて nsolve()
文がある場合,これだとエラーになる。
対策は,
- 関数名のみにする(かっこや引数は省略する)
つまり,以下のようにすればよい。
plot(g, (x, -1, 1))
# plot(g(x), (x, -1, 1)) ではなくて...
plot(g, (x, -1, 1));
参考:Maxima で少し込み入った関数をグラフにする
SymPy & SymPy Plotting Backends で plot()
する際に,思いもかけずにエラーとなった以下のような関数を Maxima でグラフにしたらどうなるか,という比較参考。
関数の定義の中に if
文がある例
例えば,以下のような例。
f(x):= if x < 0 then -x else x;
plot2d()
plot2d()
では特に問題なくグラフが作成される。
plot2d(f(x), [x, -10, 10])$
draw2d()
draw2d()
でも特に問題なくグラフが作成される。
draw2d(explicit(f(x), x, -10, 10))$
関数の定義の中に数値解法の find_root()
がある場合
例えば,以下のような例。
g(x):= find_root(sin(t)-x=0, t, -%pi/2, %pi/2);
plot2d()
plot2d()
では,なぜか以下のようなエラーが出てグラフが作成されない。
plot2d(g(x), [x, -1, 1])$
draw2d()
draw2d()
では特に問題なくグラフが作成される。
draw2d(explicit(g(x), x, -1, 1))$