函数的一些常见问题

自定义函数的某些问题可能令人迷惑(如微分或绘图)。这一节我们讨论一下相关的话题。

有多种方法定义可以被称为”函数”的东西:

  1. 定义Python函数,正如函数、缩进和计数中所提到的那样。这些函数可用于绘图,但是不能用于微分和积分。
    1. sage: def f(z): return z^2
    2. sage: type(f)
    3. <type 'function'>
    4. sage: f(3)
    5. 9
    6. sage: plot(f, 0, 2)
    7. Graphics object consisting of 1 graphics primitive

注意最后一行的语法。如果使用plot(f(z),0,2)的话,会报NameError错误。 因为在f的定义中z是一个形式变量,在f之外,z没有定义。实际上只是f(z)有问题。下面的代码就可以正确工作,但是一般来说这也是有问题的,要尽量避免(参见下面第4条)。

  1. sage: var('z') # 定义z为一个变量
  2. z
  3. sage: f(z)
  4. z^2
  5. sage: plot(f(z), 0, 2)
  6. Graphics object consisting of 1 graphics primitive

这里,f(z)是一个符号表达式,这是我们下一条要讨论的。

  1. 定义”可调用的符号表达式”。可用于绘图、微分和积分。
    1. sage: g(x) = x^2
    2. sage: g # g sends x to x^2
    3. x |--> x^2
    4. sage: g(3)
    5. 9
    6. sage: Dg = g.derivative(); Dg
    7. x |--> 2*x
    8. sage: Dg(3)
    9. 6
    10. sage: type(g)
    11. <type 'sage.symbolic.expression.Expression'>
    12. sage: plot(g, 0, 2)
    13. Graphics object consisting of 1 graphics primitive

注意g是可调用的符号表达式,g(x)是一个与之相关,但是不同类型的对象,虽然g(x)也可用于绘图、微分等。参见下面第5条的展示。

  1. sage: g(x)
  2. x^2
  3. sage: type(g(x))
  4. <type 'sage.symbolic.expression.Expression'>
  5. sage: g(x).derivative()
  6. 2*x
  7. sage: plot(g(x), 0, 2)
  8. Graphics object consisting of 1 graphics primitive
  1. 预定义的Sage”微积分函数”,可用于绘图。要进行微积分的话,还要加工一下。
    1. sage: type(sin)
    2. <class 'sage.functions.trig.Function_sin'>
    3. sage: plot(sin, 0, 2)
    4. sage: type(sin(x))
    5. <type 'sage.symbolic.expression.Expression'>
    6. sage: plot(sin(x), 0, 2)
    7. Graphics object consisting of 1 graphics primitive

sin本身不能进行微分,至少不会得到cos.

  1. sage: f = sin
  2. sage: f.derivative()
  3. Traceback (most recent call last):
  4. ...
  5. AttributeError: ...

使用f = sin(x)而不是sin, 就可以进行微分了, 而且比用f(x) = sin(x)建立一个可调用的符号表达式要好。

  1. sage: S(x) = sin(x)
  2. sage: S.derivative()
  3. x |--> cos(x)

下面解释一些常见的问题:

  1. 意外的运算结果(Accidental evaluation)
    1. sage: def h(x):
    2. ....: if x<2:
    3. ....: return 0
    4. ....: else:
    5. ....: return x-2

问题:plot(h(x), 0, 4)画出来的是直线$y=x-2$, 而不是h定义的折线。为什么?在命令plot(h(x), 0, 4)中,h(x)首先被计算,也就是将x代入h, 从而x<2被计算。

  1. sage: bool(x < 2)
  2. False
  3. sage: h(x)
  4. x - 2

注意:这里存在两个不同的x:一个是在定义h时作为函数内的局部变量,另一个则是在Sage启动时便设置好的符号变量。

解决方案:不要用plot(h(x), 0, 4), 而是用

  1. sage: plot(h, 0, 4)
  2. Graphics object consisting of 1 graphics primitive
  1. 意外地得到一个常数而不是一个函数
    1. sage: f = x
    2. sage: g = f.derivative()
    3. sage: g
    4. 1

问题:g(3)返回错误: “ValueError: the number of arguments must be less than or equal to 0.”

  1. sage: type(f)
  2. <type 'sage.symbolic.expression.Expression'>
  3. sage: type(g)
  4. <type 'sage.symbolic.expression.Expression'>

g不是一个函数,而是一个常量,所以它没有相关的自变量,也就不能再做其他运算。

解决方案:有好几种方式。

  • 定义f为符号表达式。
  1. sage: f(x) = x # 而不是 'f = x'
  2. sage: g = f.derivative()
  3. sage: g
  4. x |--> 1
  5. sage: g(3)
  6. 1
  7. sage: type(g)
  8. <type 'sage.symbolic.expression.Expression'>
  • 或者f还是原来那样定义,而把g定义为符号表达式。

    1. sage: f = x
    2. sage: g(x) = f.derivative() # 而不是 'g = f.derivative()'
    3. sage: g
    4. x |--> 1
    5. sage: g(3)
    6. 1
    7. sage: type(g)
    8. <type 'sage.symbolic.expression.Expression'>
  • 或者fg都还是原来那样定义,但是指定你所替代的变量。

  1. sage: f = x
  2. sage: g = f.derivative()
  3. sage: g
  4. 1
  5. sage: g(x=3) # 而不是 'g(3)'
  6. 1

最后,还有一种方法来说明f = xf(x) = x导数间的区别:

  1. sage: f(x) = x
  2. sage: g = f.derivative()
  3. sage: g.variables() # g 的变量
  4. ()
  5. sage: g.arguments() # g 的参数
  6. (x,)
  7. sage: f = x
  8. sage: h = f.derivative()
  9. sage: h.variables()
  10. ()
  11. sage: h.arguments()
  12. ()

正象这个例子所展示的那样,h不接受任何参数,这正是h(3)报错的原因。