3 Programmieren mit MATLAB Lösungen zu den Aufgaben Aufgabe 3.1 Das Ziel dieser Aufgabe besteht darin, den Zugriff auf die drei verschiedenen Adressräume Hauptbereich, Globalbereich und Funktionsbereich zu verstehen. a) Definieren Sie im Hauptbereich eine Variable va. Versuchen Sie aus einer Funktion heraus va zu lesen. Weisen Sie va mit assignin einen Wert zu. Beim Ablauf wird eine Fehlermeldung erzeugt und das Programm abgebrochen. Sobald der Zugriff auf va in afg3_1a nicht mehr erfolgt, wird der neue Wert 44 zugewiesen. va=33; afg3_1_f va function afg3_1a va % va assignin('base','va',44) end ??? Undefined function or variable 'va'. Error in ==> afg3_1_f at 2 va % va b) Weisen Sie über eine Funktion einer Variablen vg im Globalbereich einen Wert zu. Greifen Sie aus einer Funktion heraus auf diese Variable vg im Globalbereich zu und überschreiben Sie deren Inhalt. function afg3_1b global vg vg=99; end c) Lesen Sie diese Variable vg über das Kommandofenster wieder aus. Prof. Georg Stark Lösungen - 3. Programmieren mit MATLAB 2 >> global vg >> vg vg = 99 Aufgabe 3.2 Es sollen Vektoren und Matrizen definiert werden. a) Definieren Sie einen Zeitvektor tv mit der Abtastperiode dt=0.1s und dem Intervall 0...10s. dt=0.1; tv=0:dt:10; b) Gegeben ist eine 2,2-Matrix M1 mit beliebigem Inhalt. Definieren Sie eine 2,3-Matrix M2, die zusätzlich zu M1 den Spaltenvektor [1 1]’ enthält. M1=[4 5;6 7]; M2=[M1 [1 1]’] M2 = 4 6 5 7 1 1 c) Definieren Sie eine 3,3-Matrix M3, die zusätzlich zu M2 den Zeilenvektor [0 0 1] aufweist. M3=[M2;[0 0 1]] M3 = 4 6 0 5 7 0 1 1 1 Aufgabe 3.3 Gegeben ist die Matrix A=[1 2 3; 4 5 6; 7 8 9]. a) Lesen Sie das Element mit dem Wert 6 aus. >> el=A(2,3) el = 6 Prof. Georg Stark Lösungen - 3. Programmieren mit MATLAB 3 b) Lesen Sie mit einem einzigen Zugriff die Elemente mit den Werten 1, 2, 7, 9 aus. Als ergänzende Information muss dabei beachtet werden, dass Matrizen als Liste in der Reihenfolge der Spalten gespeichert werden. Das Element mit dem Wert 2 kann sowohl mit dem Indexpaar (1,2) als auch mit dem fortlaufenden Index (4) ausgelesen werden. >> A([1 3 4 9]) ans = 1 7 2 9 c) Erzeugen Sie die Matrix B aus der linken, oberen 2,2-Teilmatrix. >> B=A([1 2],[1 2]) B = 1 4 2 5 d) Lesen Sie alle Elemente der 2. Zeile aus. >> A(2,:) ans = 4 5 6 Aufgabe 3.4 Vektoren und Matrizen sollen berechnet werden. a) Gegeben sind zwei Vektoren v1=[2 1] und v2=[1 2]. Berechnen Sie das Skalarprodukt sowohl mit der dot-Funktion als auch mit dem Multiplikationsoperator *. Welche Werte muss v2 aufweisen, damit das Skalarprodukt den Wert null hat? >> skal=dot(v1,v2) skal = 4 Berechnung als Matrixprodukt mit einem Zeilen- und einem Spaltenvektor (!). >> skal=v1*v2' skal = Prof. Georg Stark Lösungen - 3. Programmieren mit MATLAB 4 4 Damit gilt skal=0, muss v2 den Wert [1 -2] aufweisen. b) Gegeben ist der Vektor v=[1 -1]. Wenden Sie die Funktionen norm, length und abs auf v an. Erklären Sie die Unterschiede. >> norm(v) ans = 1.4142 % Betrag des Vektors >> length(v) ans = 2 % Anzahl der Elemente >> abs(v) ans = 1 1 % von allen Elementen wird der Absolutwert berechnet. c) Gegeben ist die Matrix [2 1; 1 1]. Berechnen Sie die Determinante direkt aus den Elementen und mit Hilfe der det-Funktion. M = 2 1 1 1 >> det(M) ans = 1 >> M(1,1)*M(2,2)-M(2,1)*M(1,2) ans = 1 d) Berechnen Sie die Determinante einer singulären 2,2-Matrix. Welche Beziehung gilt dann für deren Spalten- und Zeilenvektoren? Die Determinante einer singulären Matrix hat immer den Wert 0. Das Lösungstheorem für ein homogenes LGS besagt, dass es nur dann nichtriviale Lösungen gibt, falls gilt det(A) = 0. r r Für die Spaltenvektoren von A s1 und s2 gilt: r r A ⋅ x = [s1 r ⎡ x1 ⎤ r r r s2 ]⋅ ⎢ ⎥ = x1 ⋅ s1 + x 2 ⋅ s2 = 0 ⎣x 2 ⎦ Dies bedeutet, dass bei einer singulären Matrix die Spaltenvektoren linear abhängig sind. Prof. Georg Stark Lösungen - 3. Programmieren mit MATLAB 5 e) Gegeben ist der Vektor v1=[2 3 4]. Quadrieren Sie alle Elemente von v1 mit Hilfe eines Vektors v2. Welchen Wert hat dieser Vektor? >> v2=[2 2 2]; >> v1.^v2 ans = 4 9 16 f) Zwei Vektoren sind definiert mit a=[1 1 0], b=[ 2 0 0]. Berechnen Sie einen Vector c, der senkrecht auf a und b steht und einen Vektor d, der senkrecht auf b und c steht. Geben Sie alle möglichen Lösungen an. >> c=cross(a,b) c = 0 0 -2 >> d=cross(b,c) d = 0 4 0 Aufgabe 3.5 Gegeben sind zwei Geraden in der Ebene durch ihren Hinführungs- und Richtungsvektor: g1: a=[0 1]; u=[1 1]; g2: b=[3 0]; v=[-2 2]. a) Stellen Sie die beiden Geradengleichungen in expliziter Form und in Vektorform auf. r ⎡0⎤ ⎡1⎤ g1: explizit: y = x + 1 ; Vektorform: x = ⎢ ⎥ + t ⎢ ⎥ . ⎣1⎦ ⎣1⎦ r ⎡3⎤ ⎡− 2⎤ g2: explizit: y = − x + 3 ; Vektorform: x = ⎢ ⎥ + t ⎢ ⎥ . ⎣0 ⎦ ⎣ 2 ⎦ b) Berechnen Sie den Schnittpunkt durch Lösen eines linearen Gleichungssystems mit Hilfe der Matrixdivision. a=[0 1]'; u=[1 1]'; b=[3 0]'; v=[-2 2]'; A=[u -v]; r=b-a; % Systemmatrix und Störvektor k=A\r; % Matrixdivision s1=a+k(1)*u % Schnittpunkte s1 und s2 sind gleich s2=b+k(2)*v s1 = 1 2 s2 = 1 2 Prof. Georg Stark 6 Lösungen - 3. Programmieren mit MATLAB Aufgabe 3.6 Gegeben sind zwei Geraden im Raum in Vektordarstellung, g1: a=[0 1 1]; u=[1 1 0]; g2: b=[3 0 -1]; v=[-2 2 0]. a) Berechnen Sie die Lotfußpunkte des Abstandsvektors mit Hilfe eines linearen, überbestimmten Gleichungssystems. a=[0 1 1]'; u=[1 1 0]'; b=[3 0 -1]'; v=[-2 2 0]'; A=[u -v]; r=b-a; % Systemmatrix und Störvektor k=A\r; s1=a+k(1)*u % Lotfusspunkte s2=b+k(2)*v s1 = 1 2 1 s2 = 1.0000 2.0000 -1.0000 b) Berechnen Sie die Lotfußpunkte mit Hilfe einer Lotgeraden und dem daraus folgenden bestimmten Gleichungssystem. Die Lösung erfolgt mit dem Verfahren, dargestellt in Abschnitt 2.2.4. % g1: x=a+k1*u; g2: x=b+k2*v; g3: x=c+k3*w; Spaltenvektoren a=[0 1 1]'; u=[1 1 0]'; b=[3 0 -1]'; v=[-2 2 0]'; A=[u -v cross(u,v)]; r=b-a; % Systemmatrix und Störvektor k=A\r; s1=a+k(1)*u % Lotfusspunkte s2=b+k(2)*v c) Welchen Abstand haben die beiden Lotfußpunkte? d=norm(s1-s2) d = 2 Prof. Georg Stark % Abstand Lösungen - 3. Programmieren mit MATLAB 7 Aufgabe 3.7 Gegeben ist ein beliebiges rechtwinkliges Dreieck ABC, rechter Winkel bei B. a) Berechnen Sie die beiden anderen Winkel α, γ mit Hilfe der inversen trigonometrischen Funktionen asin, acos und atan. Gegeben sind die drei Seitenlängen a, b, c. C γ b β a c A a B alpha=asin(a/b); alpha=acos(c/b); alpha=atan(a/c); gamma=asin(c/b); gamma=acos(a/b); gamma=atan(c/a); b) Welche Wertebereiche sind für die Winkel α, γ gegeben? 0 ≤ α, λ ≤ π / 2 . c) Berechnen Sie die Winkel α, γ für die Seitenlängen a=3 , b=5. >> c=sqrt(b^2-a^2) c =4 alpha=asin(a/b)*180/pi % grad alpha = 36.8699 % grad gamma = 53.1301 % grad gamma+alpha = 90 % grad Aufgabe 3.8 In einem allgemeinen Dreieck ABC soll der Winkel β bei B berechnet werden. a) Berechnen Sie β für a=b=4, c=3. Anwendung des Kosinussatzes b 2 = a 2 + c 2 − 2ac ⋅ cos β >> beta=acos( (c^2+a^2-b^2)/(2*a*c))*180/pi beta =67.9757 % grad Prof. Georg Stark Lösungen - 3. Programmieren mit MATLAB 8 b) Welche Werte haben die beiden anderen Winkel α, γ ? >> alpha=acos( (c^2+b^2-a^2)/(2*b*c))*180/pi alpha = 67.9757 % grad Es gilt alpha=beta, da es sich um ein gleichschenkliges Dreieck handelt. >> gamma=180-2*alpha gamma =44.0486 % grad Aufgabe 3.9 Gegeben sind vier Punkte Pi mit den Ortsvektoren. ⎡ xi ⎤ r ⎢ ⎥ r pi = ⎢ yi ⎥; pi = 2 . ⎢⎣ 0 ⎥⎦ r r a) Bestimmen Sie die xi und yi so, dass die resultierenden Vektoren p1 L p4 mit der xAchse die Winkel 30°, 150°, 210°, 330° einschließen. >> p1(1)=2*cos(pi/6) p1 = 1.7321 % 30 grad >> p1(2)=2*sin(pi/6) p1 = 1.7321 1.0000 >> p2(1)=-2*cos(pi/6) % 150 grad >> p2(2)=2*sin(pi/6) >> p3(1)=-2*cos(pi/6) % 210 grad >> p3(2)=-2*sin(pi/6) >> p4(1)=2*cos(pi/6) % 330 grad >> p4(2)=-2*sin(pi/6) b) Berechnen Sie zur Kontrolle die unter a) definierten Winkel mit Hilfe der atan2Funktion. >> phi1=atan2(p1(2),p1(1))*180/pi phi1 = 30.0000 % grad >> phi2=atan2(p2(2),p2(1))*180/pi phi2 = 150.0000 % grad Prof. Georg Stark 9 Lösungen - 3. Programmieren mit MATLAB >> phi3=atan2(p3(2),p3(1))*180/pi phi3 = -150.0000 % grad >> phi4=atan2(p4(2),p4(1))*180/pi phi4 = -30.0000 % grad c) Welche Winkel ergeben sich, wenn die Punkte Pi um 2 LE parallel zur x-Achse verschoben werden? p1v(1)=p1(1)+2; p2v(1)=p2(1)+2; p3v(1)=p3(1)+2; p4v(1)=p4(1)+2; p1v(2)=p1(2); p2v(2)=p2(2); p3v(2)=p3(2); p4v(2)=p4(2); % Verschieben der Punkte phi1v=atan2(p1v(2),p1v(1))*180/pi % Winkelberechnung phi2v=atan2(p2v(2),p2v(1))*180/pi phi3v=atan2(p3v(2),p3v(1))*180/pi phi4v=atan2(p4v(2),p4v(1))*180/pi phi1v phi2v phi3v phi4v = = = = 15.0000 % grad 75.0000 % grad -75.0000 % grad -15.0000 % grad Aufgabe 3.10 Zeichenketten sollen eingelesen und verarbeitet werden. a) Schreiben Sie eine Funktion, die den heutigen Wochentag abfragt und anschließend den Satz Heute ist <Wochentag > ausgibt. function ein_we str=input('Geben Sie den heutigen Wochentag ein! \n', 's'); ausstr=strcat('Heute ist \n',str); fprintf(ausstr); Die Systemreaktion ist: Geben Sie den heutigen Wochentag ein! Sonntag Heute ist Sonntag>> Prof. Georg Stark 10 Lösungen - 3. Programmieren mit MATLAB b) Erweitern Sie die Funktion so, dass bei Eingabe einer Zeichenkette, die keinen Wochentag darstellt, eine Fehlermeldung erfolgt. function ein_we wochentage={'Montag' 'Dienstag' 'Mittwoch'... 'Donnerstag' 'Freitag' 'Samstag' 'Sonntag'}; str=input('Geben Sie den heutigen Wochentag ein! \n', 's'); indexliste=strmatch(str,wochentage); if (isempty(indexliste)) error('falsche Eingabe') end ausstr=strcat('Heute ist \n',str); fprintf(ausstr); Aufgabe 3.11 Gegeben ist ein Array ZA mit beliebig vielen, gleichlangen Zeichenketten. Jede beginnt mit einem Schlüsselwort, darauf folgen zwei ganze Zahlen, getrennt durch Leerzeichen. a) Schreiben Sie eine Funktion, welche die beiden Zahlen in einer Zeichenkette jeweils in die Zeile einer Matrix schreibt. function zeichenketten ZA=[ 'ss1 22 33' 'ss2 44 55' 'ss3 66 77' ]; [ze sp]=size(ZA); for k=1:ze str=ZA(k,:); matzeile=sscanf(str,'%*s %d %d',[1 2]); mat(k,:)=matzeile; end mat=22 44 66 33 55 77 b) Geben Sie anschließend alle Zeilen der Matrix mit Hilfe einer sprintf-Anweisung aus. for k=1:ze sprintf('Zeile %d : end Prof. Georg Stark %d %d',k ,mat(k,1),mat(k,2) ) Lösungen - 3. Programmieren mit MATLAB Zeile 1 : Zeile 2 : Zeile 3 : 22 44 66 11 33 55 77 c) Erweitern Sie die Funktion so, dass der Inhalt von ZA in eine Cell-Array-Matrix ZCA kopiert wird. Dabei wird jede Zeichenkette von ZA in alle Teilzeichenketten aufgelöst und als Elemente einer Zeile von ZCA abgespeichert. for k=1:ze [tok rest]=strtok(ZA(k,:)); ZCA{k,1}=tok; ZCA{k,2}=mat(k,1); ZCA{k,3}=mat(k,2); end ZCA = 'ss1' 'ss2' 'ss3' [22] [44] [66] [33] [55] [77] Aufgabe 3.12 Unterschiedliche Arten von Funktionen sollen programmiert werden. a) Programmieren Sie eine Hauptfunktion hfun mit folgenden Eigenschaften. Beim Aufruf wird eine beliebige Zahl übergeben und in die lokale Variable hf_var geschrieben. Anschließend wird dieser Wert mit Hilfe der privaten Funktion pfun quadriert, in einer globalen Variablen g_var zur Verfügung gestellt und dann als Funktionswert von hfun übergeben. function aus_hfun=hfun(ein) hf_var=ein; global g_var; efun; g_var=pfun(hf_var); %Quadrieren aus_hfun=g_var; end b) Programmieren Sie die private Funktion pfun. Ihr wird als Parameter eine Zahl übergeben, deren Quadrat als Funktionswert geliefert wird. function quad=pfun(einp) quad=einp^2; end Prof. Georg Stark Lösungen - 3. Programmieren mit MATLAB 12 c) Programmieren Sie in hfun zusätzlich eine eingebettete Funktion efun. Diese greift vor dem Aufruf von pfun direkt auf hf_var zu, multipliziert deren Inhalt mit 2 und schreibt das Ergebnis nach hf_var zurück. function aus_hfun=hfun(ein) hf_var=ein; global g_var; efun; g_var=pfun(hf_var); %Quadrieren aus_hfun=g_var; function efun % eingebettete Funktion hf_var=hf_var*2 end end d) Führen Sie hfun über das Kommandofenster aus und verfolgen Sie den Ablauf im Debugger. Die Hauptfunktion hfun wird mit dem Parameter 3 aufgerufen. Die lokale Variable hf_var hat nach dem Aufruf der eingebetten Funktion efun den Wert 6. Nach Beendigung der Funktion wird das Ergebnis 36 geliefert. >> hfun(3) hf_var = 6 ans = 36 Aufgabe 3.13 Schreiben Sie eine Funktion zum Vergleich zweier Textdateien, deren Pfade beim Aufruf als Parameter übergeben werden. Das Ergebnis wird in einer dritten Datei mit dem Namen VGL_Datei1_Datei2.txt abgespeichert. Der Vergleich wird zeilenweise durchgeführt. Falls zwei entsprechende Zeilen ungleich sind, werden diese zusammen mit ihren Zeilennummern in die Ergebnisdatei geschrieben. Die Anzahl der ungleichen Zeilen wird als Funktionswert übergeben. Alle Dateifunktionen werden mit einem try-Block überwacht. Über den catch-Block wird eine Fehlermeldung ausgegeben. Prof. Georg Stark Lösungen - 3. Programmieren mit MATLAB 13 function ungleich=dateivergleich(dat1, dat2) dat1txt=[dat1 '.txt']; dat2txt=[dat2 '.txt']; dat3txt=['VGL_' dat1 '_' dat2 '.txt']; fid1=fopen(dat1txt,'r'); fid2=fopen(dat2txt,'r'); fid3=fopen(dat3txt,'w'); ungleich=0; iz=0; while 1 try str1=fgetl(fid1); catch error('Dateifehler beim Lesen\n') end if str1==-1 break end try str2=fgetl(fid2); catch error('Dateifehler beim Lesen\n') end if str2==-1 break end iz=iz+1; if vgl_str(str1,str2) fprintf(fid3,'Fehler in Zeile %d\n', iz); fprintf(fid3,str1); fprintf(fid3,'\n'); fprintf(fid3,str2); fprintf(fid3,'\n'); ungleich=ungleich+1; end end fclose(fid1); fclose(fid2); fclose(fid3); end function ungleich=vgl_str(s1,s2) % Vergleich zweier Zeichenketten [z d1]=size(s1); [z d2]=size(s2); ungleich=0; if d1~=d2 Prof. Georg Stark 14 Lösungen - 3. Programmieren mit MATLAB ungleich=1; return end for k=1:d1 a=s1(k); b=s2(k); if a~=b ungleich=1; return end end end Aufgabe 3.14 a) Schreiben Sie eine Grafikfunktion mit den folgenden Eigenschaften. Als Parameter werden Mittelpunkt und Radius eines Kreises übergeben. Der Kreis wird als Linie grafisch dargestellt. Zusätzlich werden die Koordinatenachsen angezeigt, beschriftet und geeignet skaliert. Der Mittelpunkt wird durch ein kleines Kreuz dargestellt und beschriftet. function kreis(m,r) aufloesung=0.01; % Darstellung Kreis t=0:aufloesung:2*pi; x=r*cos(t)+m(1); y=r*sin(t)+m(2); hold on plot(x,y,'R--') plot([m(1)-r/10 m(1)+r/10],[m(2) m(2)],'B') plot([m(1) m(1)],[m(2)-r/10 m(2)+r/10],'B') axis([m(1)-2*r m(1)+2*r m(2)-2*r m(2)+2*r]) title ('Darstellung eines Kreises'); xlabel('x-Achse'); ylabel('y-Achse'); text(m(1)+r/4,m(2),'M') grid on b) Erweitern Sie die Grafikfunktion um die zusätzliche Darstellung eines dem Kreis eingeschriebenen gleichseitigen Dreiecks. Eine Kante verläuft parallel zur x-Achse. p1(1)=-r*cos(pi/6)+m(1); p1(2)=-r*sin(pi/6)+m(2); p2(1)=r*cos(pi/6)+m(1); Prof. Georg Stark % Darstellung Dreieck 15 Lösungen - 3. Programmieren mit MATLAB p2(2)=-r*sin(pi/6)+m(2); p3(1)=m(1); p3(2)=m(2)+r; plot([p1(1) p2(1)],[p1(2) p2(2)], 'G') plot([p1(1) p3(1)],[p1(2) p3(2)], 'G') plot([p2(1) p3(1)],[p2(2) p3(2)], 'G') Aufgabe 3.15 Programmieren Sie eine Funktion, welche die Kanten eines Prismas dreidimensional darstellt. Die parallelen Grund- und Deckflächen bilden ein reguläres Fünfeck, dessen eine Seite parallel zur x-Achse verläuft. Die Mittelachse des Prismas liegt auf der z-Achse. Beim Aufruf der Funktion werden als Parameter der Radius des Umkreises des Fünfecks und die Höhe übergeben. function prisma(r,h) pu(1,1)=-r*cos(54*pi/180); pu(1,2)=-r*sin(54*pi/180); pu(2,1)=r*cos(54*pi/180); pu(2,2)=-r*sin(54*pi/180); pu(3,1)=r*cos(18*pi/180); pu(3,2)=r*sin(18*pi/180); pu(4,1)=0; pu(4,2)=r; pu(5,1)=-r*cos(18*pi/180); pu(5,2)=r*sin(18*pi/180); pu(:,3)=[0 0 0 0 0]; % Punkte der Grundfläche hold on for k=1:4 % Darstellung Grundfläche plot3([pu(k,1) pu(k+1,1)],[pu(k,2) pu(k+1,2)], [pu(k,3) pu(k+1,3)], 'G') end plot3([pu(5,1) pu(1,1)],[pu(5,2) pu(1,2)], [pu(5,3) pu(1,3)],'G') po=pu; po(:,3)=[h h h h h]; for k=1:4 plot3([po(k,1) po(k+1,3)], 'G') end Prof. Georg Stark % Darstellung Deckfläche po(k+1,1)],[po(k,2) po(k+1,2)], [po(k,3) Lösungen - 3. Programmieren mit MATLAB 16 plot3([po(5,1) po(1,1)],[po(5,2) po(1,2)], [po(5,3) po(1,3)],'G') for k=1:5 % Darstellung Seitenkanten plot3([pu(k,1) po(k,1)],[pu(k,2) po(k,2)], [pu(k,3) po(k,3)], 'G') end title ('Darstellung eines Prismas'); xlabel('x-Achse'); ylabel('y-Achse'); zlabel('z-Achse'); Der Aufruf erfolgt zum Beispiel mit prisma(3,5). Eine Ansicht zeigt das folgende Bild. Prof. Georg Stark