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))
只是画了一条水平线。谁能解释发生了什么?
与@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);它没有处理无限的间隔。)
您也可以只检测 to 的参数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
with的组合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)
这意味着示例将打印:)
。
前者传递函数,允许在内部调用它plot()
。后者调用一次函数并传递返回值,每次都得到相同的值。
这是一个(可能)更简单的解决方案,使用 lambdas。
sage: plot(lambda x:f(x), (x,-5,5))