def f(u):
value = 0.0
if u > -1 and u < 1:
value = u * u
return value
上記を考えると、以下は予想されるプロットを生成します。
plot(f,(x,-5,5))
しかしplot(f(x),(x,-5,5))
、水平線を引くだけです。誰が何が起こっているのか説明できますか?
前者は関数を渡し、内部で呼び出せるようにしますplot()
。後者は関数を 1 回呼び出して戻り値を渡すため、毎回同じ値になります。
@Ignacioが言ったことと同様に、原因は関数が一度呼び出されていることです。これと他の関数のような問題sin
は、条件付きです。ステートメントは、if
関数が呼び出されたときに評価され、シンボリック ステートメントとして保存されません。つまり、u > -1 and u < 1
[1]は最初の関数呼び出しで評価され、result
それに応じて処理されます (つまり、 に残され0
ます)。
何が起こっているかの実例として:
sage: x = var('x')
sage: print ":)" if x > 0 else ":("
:(
一般に、これを回避する方法はありません[2]if
。関数が呼び出されたときにどのコード パスを使用するかを判断するために、Python はステートメント内の条件を評価する必要があるためです。
動作するはずの解決策があります (ただし、まだ動作していません)。Sage は を提供するPiecewise
ので、次のように定義できますf
。
f = Piecewise([((-5, -1), ConstantFunction(0)),
((-1, 1), x*x),
((1, 5), ConstantFunction(0))],
x)
残念ながら、 の実装はPiecewise
まだ不完全であり、非常に不足しているため、これをプロットする唯一の方法は次のようになります。
f.plot()
(制限: 変数で呼び出そうとするf
とエラーが発生します。従来の では機能しません。 でplot
ドメインを制限することはできません。Piecewise.plot
すべてをプロットします (したがって、±5 に制限した理由)。そうではありません)。無限間隔に対処します。)
への引数f
が数値か変数かを検出し、それに基づいて適切なアクションを実行することもできます。
def f(u):
try:
float(u) # see it's a number by trying to convert
return u*u if -1 < u < 1 else 0.0
except TypeError: # the conversion failed
if callable(f):
return lambda uu: f(u(uu))
else:
return f
呼び出しに注意してください。 (ある意味で) が関数であるcallable
かどうかを確認し、そうであればwithの構成を返します。u
f
u
このバージョンでは、次のようなことができます。
sage: f(10)
0.0
sage: f(x)(0.5)
0.25
sage: f(x+3)(-2.2)
0.64
plot
また、どちらの形式でも完全に正常に機能します。DeprecationWarnings
(構文のために警告u(uu)
が表示されますが、これを回避する方法はいくつかありますu.variables
が、かなり厄介です。)
注: この「機能する」ソリューションは非常に壊れやすく、最適とは言えません。それが機能した場合、Piecewise
バージョンは正しいソリューションになります。
[1]: Python では実際にこれを のように書くことができます-1 < u < 1
。かなりクール。
[2]: いくつかの特別なケースでは可能ですが、たとえば、 がわかっている場合はx > 0
、 を使用できassume(x > 0)
ます:)
。
これは、ラムダを使用した(おそらく)今のところより単純なソリューションです。
sage: plot(lambda x:f(x), (x,-5,5))