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))
只是绘制一条水平线。谁能解释一下发生了什么?
答案 0 :(得分:1)
前者传递函数,允许在plot()
内调用它。后者调用函数一次并传递返回的值,每次都得到相同的值。
答案 1 :(得分:1)
类似于@Ignacio所说的,原因是被调用的函数一次。与sin
等其他函数相比,这个问题是有条件的。调用函数时会计算if
语句,而不会将其保留为符号语句。也就是说,u > -1 and u < 1
[1] 在第一个函数调用上进行评估,并相应地处理result
(即留在0
)。
作为正在发生的事情的例证:
sage: x = var('x')
sage: print ":)" if x > 0 else ":("
:(
一般 [2] 没有办法解决这个问题,因为Python必须在if
语句中评估条件,以确定函数时要采用的代码路径被称为。
有一个解决方案应该有效(但还没有)。 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
调用,它会检查u
是否为函数(在某种意义上),如果是,则返回f
与u
的组合。< / p>
此版本允许我们执行以下操作:
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)
,这意味着该示例将打印:)
。
答案 2 :(得分:0)
现在,这是一个(可能)更简单的解决方案,使用lambdas。
sage: plot(lambda x:f(x), (x,-5,5))