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の構成を返します。ufu
このバージョンでは、次のようなことができます。
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))
