s.. _section-functions-issues:
Häufige Probleme mit Funktionen¶
Das Definieren von Funktionen kann in mancher Hinsicht verwirrend sein (z.B. beim Ableiten oder Plotten). In diesem Abschnitt versuchen wir die relevanten Probleme anzusprechen.
Nun erläutern wir verschiedene Möglichkeiten Dinge zu definieren, die das Recht haben könnten „Funktionen“ genannt zu werden:
1. Definition einer Python-Funktion wie in Funktionen, Einrückungen, und Zählen beschrieben. Diese Funktionen können geplottet, aber nicht abgeleitet oder integriert werden.
sage: def f(z): return z^2
sage: type(f)
<... 'function'>
sage: f(3)
9
sage: plot(f, 0, 2)
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> def f(z): return z**Integer(2)
>>> type(f)
<... 'function'>
>>> f(Integer(3))
9
>>> plot(f, Integer(0), Integer(2))
Graphics object consisting of 1 graphics primitive
def f(z): return z^2 type(f) f(3) plot(f, 0, 2)
Beachten Sie die Syntax in der letzten Zeile. Falls Sie stattdessen
plot(f(z), 0, 2)
verwenden, erhalten Sie einen Fehler, da z
eine Dummy-Variable in der Definition von f
ist, und außerhalb
dieser nicht definiert ist. In der Tat gibt sogar nur f(z)
einen
Fehler zurück. Das Folgende funktioniert in diesem Fall, obwohl es im
Allgemeinen Probleme verursachen kann und deshalb vermieden werden
sollte. (Beachten Sie unten den 4. Punkt)
sage: var('z') # z wird als Variable definiert
z
sage: f(z)
z^2
sage: plot(f(z), 0, 2)
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> var('z') # z wird als Variable definiert
z
>>> f(z)
z^2
>>> plot(f(z), Integer(0), Integer(2))
Graphics object consisting of 1 graphics primitive
var('z') # z wird als Variable definiert f(z) plot(f(z), 0, 2)
Nun ist \(f(z)`\) ein symbolischer Ausdruck. Dies ist unser nächster Stichpunkt unserer Aufzählung.
2. Definition eines „aufrufbaren symbolischen Ausdrucks“. Diese können geplottet, differenziert und integriert werden.
sage: g(x) = x^2
sage: g # g bildet x auf x^2 ab
x |--> x^2
sage: g(3)
9
sage: Dg = g.derivative(); Dg
x |--> 2*x
sage: Dg(3)
6
sage: type(g)
<class 'sage.symbolic.expression.Expression'>
sage: plot(g, 0, 2)
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> __tmp__=var("x"); g = symbolic_expression(x**Integer(2)).function(x)
>>> g # g bildet x auf x^2 ab
x |--> x^2
>>> g(Integer(3))
9
>>> Dg = g.derivative(); Dg
x |--> 2*x
>>> Dg(Integer(3))
6
>>> type(g)
<class 'sage.symbolic.expression.Expression'>
>>> plot(g, Integer(0), Integer(2))
Graphics object consisting of 1 graphics primitive
g(x) = x^2 g # g bildet x auf x^2 ab g(3) Dg = g.derivative(); Dg Dg(3) type(g) plot(g, 0, 2)
Beachten Sie, dass während g
ein aufrufbarer symbolischer Ausdruck
ist, g(x)
ein verwandtes aber unterschiedliches Objekt ist,
welches auch geplottet, differenziert, usw. werden kann - wenn auch
mit einigen Problemen: Lesen Sie den 5. Stichpunkt unterhalb, um eine
Erläuterung zu erhalten.
sage: g(x)
x^2
sage: type(g(x))
<class 'sage.symbolic.expression.Expression'>
sage: g(x).derivative()
2*x
sage: plot(g(x), 0, 2)
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> g(x)
x^2
>>> type(g(x))
<class 'sage.symbolic.expression.Expression'>
>>> g(x).derivative()
2*x
>>> plot(g(x), Integer(0), Integer(2))
Graphics object consisting of 1 graphics primitive
g(x) type(g(x)) g(x).derivative() plot(g(x), 0, 2)
3. Benutzung einer vordefinierten ‚trigonometrischen Sage-Funktion‘. Diese können mit ein wenig Hilfestellung differenziert und integriert werden.
sage: type(sin)
<class 'sage.functions.trig.Function_sin'>
sage: plot(sin, 0, 2)
Graphics object consisting of 1 graphics primitive
sage: type(sin(x))
<class 'sage.symbolic.expression.Expression'>
sage: plot(sin(x), 0, 2)
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> type(sin)
<class 'sage.functions.trig.Function_sin'>
>>> plot(sin, Integer(0), Integer(2))
Graphics object consisting of 1 graphics primitive
>>> type(sin(x))
<class 'sage.symbolic.expression.Expression'>
>>> plot(sin(x), Integer(0), Integer(2))
Graphics object consisting of 1 graphics primitive
type(sin) plot(sin, 0, 2) type(sin(x)) plot(sin(x), 0, 2)
Alleinestehend kann sin
nicht differenziert werden, zumindest nicht
um cos
zu erhalten.
sage: f = sin
sage: f.derivative()
Traceback (most recent call last):
...
AttributeError: ...
>>> from sage.all import *
>>> f = sin
>>> f.derivative()
Traceback (most recent call last):
...
AttributeError: ...
f = sin f.derivative()
f = sin(x)
anstelle von sin
zu benutzen funktioniert, aber
es ist wohl noch besser f(x) = sin(x)
zu benutzen, um einen
aufrufbaren symbolischen Ausdruck zu definieren.
sage: S(x) = sin(x)
sage: S.derivative()
x |--> cos(x)
>>> from sage.all import *
>>> __tmp__=var("x"); S = symbolic_expression(sin(x)).function(x)
>>> S.derivative()
x |--> cos(x)
S(x) = sin(x) S.derivative()
Hier sind ein paar häufige Probleme mit Erklärungen:
4. Versehentliche Auswertung.
sage: def h(x):
....: if x<2:
....: return 0
....: else:
....: return x-2
>>> from sage.all import *
>>> def h(x):
... if x<Integer(2):
... return Integer(0)
... else:
... return x-Integer(2)
def h(x): if x<2: return 0 else: return x-2
Das Problem: plot(h(x), 0, 4)
zeichnet die Linie \(y=x-2\) und nicht
die mehrzeilige Funktion, welche durch h
definiert wird. Der
Grund? In dem Befehl plot(h(x), 0, 4)
wird zuerst h(x)
ausgewertet: Das bedeutet, dass x
in die Funktion h
eingesetzt
wird, was wiederum bedeutet, dass x<2
ausgewertet wird.
sage: type(x<2)
<class 'sage.symbolic.expression.Expression'>
>>> from sage.all import *
>>> type(x<Integer(2))
<class 'sage.symbolic.expression.Expression'>
type(x<2)
Wenn eine symbolische Gleichung ausgewertet wird, wie in der
Definition von h
, wird falls sie nicht offensichtlicherweise wahr
ist, False zurück gegeben. Also wird h(x)
zu x-2
ausgewertet
und dies ist die Funktion, die geplottet wird.
Die Lösung: verwenden Sie nicht plot(h(x), 0, 4)
; benutzen Sie stattdessen:
sage: plot(h, 0, 4)
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> plot(h, Integer(0), Integer(4))
Graphics object consisting of 1 graphics primitive
plot(h, 0, 4)
5. Versehentliches Erzeugen einer Konstanten anstelle von einer Funktion.
sage: f = x
sage: g = f.derivative()
sage: g
1
>>> from sage.all import *
>>> f = x
>>> g = f.derivative()
>>> g
1
f = x g = f.derivative() g
Das Problem: g(3)
, zum Beispiel, gibt folgenden Fehler zurück:
„ValueError: the number of arguments must be less than or equal to 0.“
sage: type(f)
<class 'sage.symbolic.expression.Expression'>
sage: type(g)
<class 'sage.symbolic.expression.Expression'>
>>> from sage.all import *
>>> type(f)
<class 'sage.symbolic.expression.Expression'>
>>> type(g)
<class 'sage.symbolic.expression.Expression'>
type(f) type(g)
g
ist keine Funktion, es ist eine Konstante, hat also keine
zugehörigen Variablen, und man kann in sie nichts einsetzen.
Die Lösung: Es gibt mehrere Möglichkeiten.
Definieren Sie
f
anfangs als symbolischen Ausdruck.
sage: f(x) = x # statt 'f = x'
sage: g = f.derivative()
sage: g
x |--> 1
sage: g(3)
1
sage: type(g)
<class 'sage.symbolic.expression.Expression'>
>>> from sage.all import *
>>> __tmp__=var("x"); f = symbolic_expression(x ).function(x)# statt 'f = x'
>>> g = f.derivative()
>>> g
x |--> 1
>>> g(Integer(3))
1
>>> type(g)
<class 'sage.symbolic.expression.Expression'>
f(x) = x # statt 'f = x' g = f.derivative() g g(3) type(g)
Oder mit der ursprünglichen Definition von
f
, definieren Sieg
als symbolischen Ausdruck.
sage: f = x
sage: g(x) = f.derivative() # statt 'g = f.derivative()'
sage: g
x |--> 1
sage: g(3)
1
sage: type(g)
<class 'sage.symbolic.expression.Expression'>
>>> from sage.all import *
>>> f = x
>>> __tmp__=var("x"); g = symbolic_expression(f.derivative() ).function(x)# statt 'g = f.derivative()'
>>> g
x |--> 1
>>> g(Integer(3))
1
>>> type(g)
<class 'sage.symbolic.expression.Expression'>
f = x g(x) = f.derivative() # statt 'g = f.derivative()' g g(3) type(g)
Oder mit den ursprünglichen Definitionen von
f
andg
, geben Sie die Variable an, in diese Sie den Wert einsetzen.
sage: f = x
sage: g = f.derivative()
sage: g
1
sage: g(x=3) # statt 'g(3)'
1
>>> from sage.all import *
>>> f = x
>>> g = f.derivative()
>>> g
1
>>> g(x=Integer(3)) # statt 'g(3)'
1
f = x g = f.derivative() g g(x=3) # statt 'g(3)'
Schließlich ist hier noch eine Möglichkeit den Unterschied zwischen der
Ableitung von f = x
und der von f(x) = x
zu erkennen:
sage: f(x) = x
sage: g = f.derivative()
sage: g.variables() # Die in g präsenten Variablen
()
sage: g.arguments() # Die Argumente die in g gesteckt werden können
(x,)
sage: f = x
sage: h = f.derivative()
sage: h.variables()
()
sage: h.arguments()
()
>>> from sage.all import *
>>> __tmp__=var("x"); f = symbolic_expression(x).function(x)
>>> g = f.derivative()
>>> g.variables() # Die in g präsenten Variablen
()
>>> g.arguments() # Die Argumente die in g gesteckt werden können
(x,)
>>> f = x
>>> h = f.derivative()
>>> h.variables()
()
>>> h.arguments()
()
f(x) = x g = f.derivative() g.variables() # Die in g präsenten Variablen g.arguments() # Die Argumente die in g gesteckt werden können f = x h = f.derivative() h.variables() h.arguments()
Wie dieses Beispiel verdeutlichen sollte, nimmt h
keine Argumente
an, und deshalb gibt h(3)
einen Fehler zurück.