Zurück zum Inhaltsverzeichnis
Kapitel 15
Grenzwerte
Grenzwerte für x -> und x -> x0
Die Verwendung von limit soll zunächst an einem einfachen Beispiel demonstriert werden
> restart:
> f:=(2*x+1)/(x-3);
Eine Zeichnung ist immer sinnvoll
> plot({limit(f,x=infinity),f},x=-10..15,-5..8);
> #plot({limit(f,x=infinity),f},x=-infinity..infinity,-5..8);
>
Verhalten für große x
>
> Limit(f,x=infinity)=limit(f,x=infinity), Limit(f,x=-infinity)=limit(f,x=-infinity);
Und nicht:
> subs(x=infinity,f);
Verhalten in einem Punkt
> Limit(f,x=0)=limit(f,x=0);
Unstetigkeitsstelle mit uneigentlichem Grenzwert
> x0:=op(discont(f,x));
>
Limit(f,x=x0)=limit(f,x=x0), Limit(f,x=x0,left)=limit(f,x=x0,left),
Limit(f,x=x0,right)=limit(f,x=x0,right);
Und nicht:
> subs(x=x0,f);
Error, division by zero
Richtungsangaben
Es gibt vier Richtungsangaben für die Annäherung an einen Punkt
> for dir in [left,right,real, complex] do
> dir=limit(f,x=x0,dir) od;
>
Dem unendlich fernen Punkt kann man sich nur von einer Seite nähern
> limit(f,x=infinity,right);
Error, (in limit) inconsistent direction with infinities
Mit bidirektional gegen ist gegen +- gemeint:
> limit(f,x=infinity,real);
> limit(arctan(x),x=infinity,real);
denn
> limit(arctan(x),x=infinity);
> limit(arctan(x),x=-infinity);
>
Endlicher Sprung
> f:=cos(x)/sqrt(1-sin(x));
> discont(f,x);
> plot(f, x=0..4*Pi);
> limit( f, x=Pi/2);
> limit( f, x=Pi/2, left);
> limit( f, x=Pi/2, right);
>
Hebbare Unstetigkeit
> f:=(sqrt(1+x)-1)/x;
> discont(f,x);
> plot(f,x=-1..10);
>
Ein etwas schwierigeres Beispiel
> f:=tan(Pi/4+x)^cot(2*x);
> limit(f, x=0 );
Maple verwendet häufig die Reihenentwicklung
> series(f, x=0);
Es handelt sich wirklich um eine abenteuerliche Funktion (die auch komplexwertig ist)
> plot(f, x=-1..10);
Man kann noch etwas mit dieser Funktion experimentieren
> subs(x=0,f);
Und ein falsches Ergebnis provozieren
> evalf(subs(x=0,f));
> eval(f,x=0);
Error, (in cot) numeric exception: division by zero
Oder die Rechengenauigkeit testen
> eval(f,x=1e-5);
> evalf(%);
> Digits:=10:
> eval(f,x=1e-10);
> evalf(%);
Mit einer größeren Stellenzahl (Digits s.o.) klappt es.
>
Noch ein unbestimmter Ausdruck der Sorte (nach dem Motto 'was wächst schneller'):
> limit(x!/x^x, x=infinity);
limit(x!/x^x, x=0);
plot(x!/x^x, x=0..10);
>
Grenzwerte mit Parametern
Der Term kann auch weitere Unbekannte enthalten
> f:=(-x^(-a)+x^a) / (x-1/x);
> limit(f, x=1);
> limit( cos(a/x)^x, x=infinity);
> limit(exp(-k*x),x=infinity);
Hier muß allerdings eine weitere Annahme gemacht werden
> assume(k>0): limit(exp(-k*x),x=infinity);
>
Manchmal kann man nur mit Bestimmtheit sagen, daß die Funktion beschränkt ist
> limit(sin(x),x=infinity);
> limit(a*sin(x),x=infinity);
> limit( b*sin(1/x), x=0);
>
>
Der Differentialquotient
Maple kennt auch den Differentialquotienten
> f:='f':
> fs:=limit( (f(x+dx) -f(x)) / dx, dx=0);
Und die zweite Ableitung
> fss:=limit( (f(x+2*dx) -2*f(x+dx) +f(x)) / (dx^2), dx=0);
> eval(fs,f=sin);
> eval(fss,f=sqrt);
>
Grenzwerte zusammenfassen
Mit combine können Grenzwerte zusammengefasst werden
> combine(limit(1/x,x=a)*limit(x,x=a));
Oder auch nicht
> combine(limit(1/x,x=0,right)*limit(x,x=0,right));
Die träge Schreibweise sollte man dabei nicht verwenden
> combine(Limit(1/x,x=0)*Limit(x,x=0));
> value(%);
>
Grenzwerte von Funktionen mit mehreren Variablen
Nur sehr eingeschränkt verwendbar
> restart:
> limit(x/y,{x=3,y=4});
> limit(x/y,{x=3,y=infinity});
> limit(x/y,{x=infinity,y=4});
> limit(x/y,{x=infinity,y=infinity});
> limit(x/y,{x=0,y=0});
> limit(x^2/y^2,{x=0,y=0});
>
Die Richtungsangabe wird nicht umgesetzt
> limit(x/y,{x=3,y=4},right);
> limit(x/y,{x=0,y=0},right);
Es gibt viele Richtungen und Grenzwerte...
> plot3d(x/y,x=-2..2,y=-2..2,view=[-2..2,-2..2,-2..2],axes=framed,grid=[30,30],color=red);
> plot3d(x/y,x=-2..2,y=-2..2,view=[-2..2,-2..2,-2..2],axes=framed,grid=[100,100],color=red,style=patchcontour,contours=30);
>
Zurückführen auf einen eindimensionalen Grenzwert durch Angabe einer Richtung (eines Wegs)
> limit(x/(m*x),x=0); # y=m*x
> limit(x/sqrt(x),x=0); # y=sqrt(x)
> limit(x/x^2,x=0,right); # y=x^2
Komplexe Grenzwerte
> restart:with(plots):
Warning, the name changecoords has been redefined
Der 'omnidirektionale' Grenzwert (Richtungsangabe complex) liefert eine falsche Aussage
> limit(1/z,z=0,complex);
und kann auch nicht mit dem multidirektionalen limit berechnet werden
> limit(1/(x+I*y),{x=0,y=0},right);
>
Vielmehr muss der Benutzer wieder die Richtung der Annäherung angeben.
Annäherung längs einer Geraden
> limit(1/(x+I*m*x),x=0,left);
> simplify(evalc(limit(1/(x+I*m*x),x=0,left))); # y=m*x
Annäherung längs
> limit(1/(x+I*sqrt(x)),x=0,right); # y=sqrt(x)
Nach Real- und Imaginärteil getrennt:
> limit(Re(1/(x+I*sqrt(x))),x=0,right); # y=sqrt(x)
> limit(Im(1/(x+I*sqrt(x))),x=0,right); # y=sqrt(x)
Annäherung längs
> limit(1/(x+I*x^2),x=0,left); # y=x^2
Nach Real- und Imaginärteil getrennt:
> limit(Re(1/(x+I*x^2)),x=0,left); # y=x^2
> limit(Im(1/(x+I*x^2)),x=0,left); # y=x^2
>
>
Auch hier hilft eine Zeichnung
> pre:=plot3d(Re(1/(x+I*y)),x=-2..2,y=-2..2,view=[-2..2,-2..2,-2..2],axes=framed,grid=[30,30],color=grey):
> pim:=plot3d(Im(1/(x+I*y)),x=-2..2,y=-2..2,view=[-2..2,-2..2,-2..2],axes=framed,grid=[50,50],color=yellow,style=patchcontour,contours=30):
> wegre:=plots[spacecurve]([x,sqrt(x),evalc(Re(1/(x+I*sqrt(x))))],x=0..2,axes=framed,color=black, thickness=5,numpoints=1000):
> #display(pre,wegre);
> wegim:=spacecurve([x,sqrt(x),evalc(Im(1/(x+I*sqrt(x))))],x=0..2,axes=framed,color=black, thickness=5,numpoints=500): #wegim;
> #display(pim,wegim);
>
> display(wegre,wegim,pim,display(pre,color=grey),orientation=[124,72]);
>
wegebene:=implicitplot3d( y^2=x ,x=-2..2,y=-2..2,
zz=-2..2,style=patchnogrid,color=red,grid=[5,45,5]):#wegebene;
> display(pim,pre,wegre,wegim,wegebene);
>
Weitere Möglichkeiten zur Veranschaulichung und Kontrolle
> restart: with(plots):
Warning, the name changecoords has been redefined
> z:=seq(x+I*2*x,x=seq(1/(100.*n),n=1..10));
> complexplot([z],style=point);
>
> w:=seq(evalc(1/z[i]),i=1..10);
> complexplot([w],style=point);
> z:=seq(x+I*sqrt(x),x=seq(1/(100.*n),n=1..10));
> complexplot([z],style=point);
>
> w:=seq(evalc(1/z[i]),i=1..10);
> complexplot([w],style=point);
> z:=seq(x+I*x^2,x=seq(1/(100.*n),n=1..10));
> complexplot([z],style=point);
>
>
> w:=seq(evalc(1/z[i]),i=1..10);
> complexplot([w],style=point);
>
Als Funktion
> y:='y':
> z:=x+I*y;
> y:=2*x;
> complexplot(z,x=0..10);
> complexplot(1/z,x=0.0001..10,numpoints=500);
> y:=sqrt(x);
> complexplot(1/z,x=0.001..10,numpoints=500);
> y:=x^2:
> complexplot(1/z,x=0.1..10,numpoints=500);
>
>
>
SummenDie Befehle add und sum im Vergleich
Bestimmte Summen mit numerischem Laufbereich werden mit add gebildet
> restart:
> add(i,i=1..100);
Gauß soll das fast so schnell wie Maple berechnet haben. Sein Mathematiklehrer wollte etwas Ruhe haben und ließ die Klasse alle Zahlen von 1 bis 100 addieren. Nach kurzer Zeit kam Gauß mit seinem Heft ans Lehrerpult und sagte 'lieget se' (da liegen die Zahlen). Nur hatte er die 100 Zahlen nicht unter einander geschrieben und addiert, sondern er hatte eine Formel gefunden:
> Sum(i,i=1..n)=factor(sum(i,i=1..n));
Und es ist gut, dass auch Maple diese Formel kennt:
> restart:
> symb:=n->sum(i,i=1..n);
>
st:=time():
symb(10^7);
time()-st;
Zum Vergleich:
> num:=n->add(i,i=1..n);
>
st:=time():
num(10^7);
time()-st;
Oder mit der Angabe des benötigten Speichers
> showtime();
O1 := symb(10^7);
time = 0.00, bytes = 5090
O2 := num(10^7);
time = 55.45, bytes = 273272958
O3 := off;
>
Trotzdem ist es oft sinnvoll, add statt sum zu verwenden:
> f:=x->add(a[i]*x^i,i=0..5);
> f(0);
> g:=x->sum(a[i]*x^i,i=0..5);
> g(0);
Alternativen:
> g:=x->sum('a[i]*'x'^i',i=0..5); g(0);
>
> h:=unapply(sum(a[i]*x^i,i=0..5),x);
> h(0);
>
Oder wenn man eben wirklich nur numerisch und nicht symbolisch rechnen will:
> ad:=add(1/i^3,i=1..1000);
> su:=sum(1/i^3,i=1..1000);
Natürlich läßt sich eine symbolisches Ergebnis auch nachträglich numerisch berechnen.
> evalf(su);
> evalf(ad);
>
Der Befehl add ist auch insofern stabiler als sum, als die Laufvariable und der Summand nicht mit '.. ' gekapselt werden müssen, und kann z.B. zur eigenen Reihenentwicklung verwendet werden (Variablenliste in diff in [ ] für k=0):
>
> reihe:=(f,x0,n)->add((x-x0)^k*eval(diff(f(x),[x$k]),x=x0)/k!,k=0..n);
> reihe(sin^2+cos,Pi/3,5);
>
> plot({reihe(sin^2+cos,Pi/3,10),sin(x)^2+cos(x)},x=-1..4);
>
> reihe(x->x^4-x^2,2,5);
> simplify(%);
> reihe(x->x^2+sin(x),Pi,5);
>
Auch Schachtelungen sind erlaubt
> add( add(k[i,j]*x^(i+j), i=1..3), j=1..3);
>
>
Summenformeln
Unbestimmte Summen
Ohne Angabe des Laufbereichs, also mit sum(f(i), i) erhält man einen Term g(i) so dass g(i+1)-g(i)=f(i) für alle i gilt:
> s:=factor(sum(i,i));
> simplify(eval(s,i=n+1)-eval(s,i=n));
> factor(sum(2*i,i));
> factor(sum(i^2,i));
>
Bestimmte Summen
Mit Angabe des Laufbereichs, also mit sum(f(i), i=m..n) erhält man einen Term g(m,n) = g(n+1)-g(m) wobei g die unbestimmte Summe ist.
>
> simplify(eval(s,i=n+1)-eval(s,i=m));
> simplify(sum(i,i=m..n));
> factor(sum(i^2,i=1..n));
> factor(sum(i^2,i=1..n-1));
(Ohne Angabe des Laufbereichs erhält man also in der Regel die Summe von 1 bis n-1.)
>
Mit sum können ebenfalls Summen von Summen gebildet werden
> sum( sum(x^(k+j), k), j);
>
> sort(sum( sum(x^(k+j), k=1..j), j=1..5));
>
Unendliche Reihen
Unendliche Reihen werden mit der oberen Grenze infinity formuliert
> sum(1/i!,i=0..infinity);
> sum(1/(2*i+1)^4,i=0..infinity);
> sum(1/i^(2*k),i=1..infinity);
> sum(i,i=1..infinity);
> sum(1/i,i=1..infinity);
>
Verschiedene Typen von Summen
Maple verwendet je nach Typ des Summanden verschiedene Methoden zur symbolischen Summation:
Polynome werden unter Verwendung von Bernoulli-Polynomen bernoulli(n,x) summiert. Rationale Funktionen der Summationsvariablen werden nach Moenck summiert. Dabei wird u.U. die -Funktion, die -Funktion und die Eulersche Konstante oder die verallgemeinerte hypergeometrische Funktion (siehe ?zeta, ?Psi, ?gamma, ?hypergeom) verwendet.
>
> sum(1/k^x,k=1..infinity);
> sum(1/i,i);
> sum(k/(k-1),k=2..n);
> Psi(3); Psi(100); expand(Psi(100));
>
Die hypergeometrische Funktion kann in 'Standardfunktionen' umgewandelt werden
> sum((-1)^k/(k^2+1),k=1..infinity);
> # evalf(%); # innerhalb zwei Minuten kein Ergebnis
Warning, computation interrupted
> convert( %, StandardFunctions);
> evalf(%);
>
Schließlich können auch Terme summiert werden, die Binomialkoeffizienten enthalten:
> sum(k*binomial(n,k), k=0..n);
> sum(binomial(n+k,k), k=0..n);
>
Eine Besonderheit stellt die Summation über die Wurzeln eines Polynoms (oder allgemeiner von RootOf-Termen) dar:
> Sum(k/(k-1), k=RootOf(x^3+x^2+1))=sum(k/(k-1), k=RootOf(x^3+x^2+1));
Dies vereinfacht die weitere Bearbeitung, auch wenn die Summe nicht explizit berechnet wird, z.B.:
> allvalues(RootOf(x^3+x^2+1));
> sum(exp(k), k=RootOf(x^3+x^2+1));
> evalf(%);
>
Maple setzt auch automatisch RootOfs ein
> sum(1/(x^4+1),x=1..infinity);
die bei Bedarf numerisch ausgewertet werden können
> evalf(%);
>
>
Konvergenz und Divergenz
Für die geometrische Reihe bekommt man nicht nur die Teilsumme
> restart:
> s:=n->sum(a*q^i,i=0..n-1);
> normal(s(n));
sondern auch ohne Rückfrage den Grenzwert:
> s(infinity);
Mit limit muss man Annahmen machen
> lim:=limit(s(n),n=infinity);
> assume(q<1);additionally(q>-1);
> lim;
> additionally(q>0);#about(q);
> lim;
die aber zu eng sind
> assume(-1<q,q<0);#about(q);
> lim;q:='q':
Auch hier ist es also angebracht, symbolische Berechnungen numerisch zu kontrollieren, oder eine Zeichnung zu erstellen:
> a:=1: q:=-1.01:
> seq(s(n),n=1000..1010);
> plot([seq([n,s(n)],n=1000..1050)]);
>
>
Asymptotische Näherung für Reihen
Euler-Maclaurinsche Summation:
Für die Summe sum(expr,x) kann mit eulermac(expr,x) eine asymptotische Näherung aufgestellt werden, d.h.,
mit F(x) = eulermac(f(x),x) ist F(x + 1) - F(x) asymptotisch gleich f(x).
>
> eulermac(k/(1+k^2),k,4);
> convert(%,polynom);
>
zum Vergleich
> sum(k/(1+k^2),k);
>
Oder mit Bereichsangabe
> eulermac(k/(1+k^2),k=1..x,4);
> convert(%,polynom);
>
Hier sind weitere Möglichkeiten, die Güte der Näherung zu beurteilen:
> seq([evalf(sum(k/(1+k^2),k=1..n)),evalf(convert(eulermac(k/(1+k^2),k=1..n,4),polynom))],n=1000..1010);
>
>
> sum(x/(1+x^2),x=1..1000);
> evalf(%);
> evalf(eulermac(x/(1+x^2),x=1..1000,4));
>
Analog zu add können Produkte mit mul berechnet werden
> mul( 1+1/x^2, x=1..20);
> evalf(%);
>
Für symbolische Berechnungen gibt es den Befehl product:
> product(x,x);
> Product(x^2,x=1..5)=product(x^2,x=1..5);
> Product(1+1/x^2, x)=product(1+1/x^2, x);
> evalf( product( 1+1/x^2, x=1..100) );
> product( 1+1/x^2, x=1..infinity);
> evalf( % );
> limit( product( 1+1/x^2, x=1..n), n=infinity );
> simplify(%);
>
>
> sum( (-1)^x/x^2, x=1..n);
> convert(%,StandardFunctions);
> eval(%,n=2000);
> showtime();
O1 := evalf( sum( (-1)^x/x^2, x=1..2000), 40);
time = 1.15, bytes = 8741878
O2 := evalf( Sum( (-1)^x/x^2, x=1..2000), 40);
time = 0.19, bytes = 1346178
O3 := off;
>
Numerische Berechnungen im Unendlichen
> f:=sinh(x)^2-sinh(x^2);
> limit( f, x=infinity);
Falsch
> evalf( Limit( f, x=infinity));
Aber
> evalf( limit( f, x=infinity));
Test
> evalf(subs(x=10^2, f));
>
>