Matlab Datenstrukturen

5. Feldelemente

Wir haben schon gesagt, daß die einzelnen Elemente eines Feldes mit Hilfe des Feldnamens und einer Indexangabe identifiziert werden können. Bei zwei- und höherdimensionalen Feldern erfolgt die Indexangabe durche einen Indexvektor, dessen Länge der Dimension des Feldes entspricht.
Der eindimensionale Zugriff ist auf Elemente von Feldern beliebiger Dimension möglich und bezieht sich immer auf das
interne, eindimensionale Feld, das jedem Feld zugeordnet ist.
» a=rand(1,5)
a =
    0.9501    0.2311    0.6068    0.4860    0.8913
» a(1,3)
ans =
    0.6068
» a(3)
ans =
    0.6068
» b=rand(5,1)
b =
    0.7621
    0.4565
    0.0185
    0.8214
    0.4447
» b(2,1)
ans =
    0.4565
» b(2)
ans =
    0.4565
Die einzelnen Feldelemente sind skalare Daten und können wie diese benutzt werden, Feldelemente mit ganzzahligen Werten können insbesondere auch als Index verwendet werden. Wird der Wert eines Feldelementes benutzt, so muß dieser definiert sein.

Beispiel 6.3:

Die Matlab-Funktion pascal liefert eine Matrix, bei der die Elemente in Zeile 1 und Spalte 1 jeweils den Wert 1 haben. Für die Werte in den anderen Zeilen und Spalten gilt:
M(i,j) = M(i,j-1) + M(i-1,j)
» A=pascal(3)
A =
     1     1     1
     1     2     3
     1     3     6
» A(2,3)
ans =
    3
» pi+A(1,2)/4.5
ans =
    3.3638
» A(A(1,1),A(2,3))
ans =
     1
» A(4,1)
???  Index exceeds matrix dimensions.
Wie ein Variablenname mit einem skalaren Wert, so kann auch ein Feldelemente zur Bezeichnung seines Wertes, aber auch Ziel einer Wertzuweisung auftreten. Ist das betreffenden Feldelement schon definiert, d.h. ist ihm schon ein anderer Wert zugewiesen worden, so erhält es einen neuen Wert, der alte geht verloren.
Falls das Feld insgesamt bisher noch nicht definiert war, wird es mit der minimal möglichen Gestalt erzeugt.
Falls das Feld schon definiert ist, nicht jedoch das Feldelement, wird das Feld auf die minimal notwendige Gestalt erweitert. Bei der Erzeugung oder Erweiterung eines Feldes erhalten neudefinierte Feldelemente, zu denen kein Wert vorliegt, den Wert 0.
»» A(2)=rand(1)

A =

         0    0.9501

» A(2,3)=0.5

A =

         0    0.9501         0
         0         0    0.5000

» A(7)=1
???  In an assignment  A(matrix) = B, a vector A can't be resized to a matrix.

» A(2,3,2)=0.1

A(:,:,1) =

         0    0.9501         0
         0         0    0.5000


A(:,:,2) =

         0         0         0
         0         0    0.1000

» A(3)

ans = A(2)=rand(1)
A =
         0    0.9218
» A(4)=0.5
A =
         0    0.9218         0    0.5000
» A(2,2,3)=1.5
A(:,:,1) =
         0    0.9218         0    0.5000
         0         0         0         0
A(:,:,2) =
         0     0     0     0
         0     0     0     0
A(:,:,3) =
         0         0         0         0
         0    1.5000         0         0
» A(1,1,2)=A(1,2,1)+A(1,4,1)*pi
A(:,:,1) =
         0    0.9218         0    0.5000
         0         0         0         0
A(:,:,2) =
    2.4926         0         0         0
         0         0         0         0
A(:,:,3) =
         0         0         0         0
         0    1.5000         0         0
» A(2,2,2)=0.5*A(1,1,1,2)
??? Index exceeds matrix dimensions.

7. Teilfelder

Da Matlab Skalare als 1*1 Matrizen behandelt, ist zu erwarten, daß man Teilfelder analog zu den Feldelementen benutzen kann.
Teilfelder werden durch den Feldnamen und eine Indexangabe bezeichnet, wobei mindestens in einer Dimension ein Vektor steht.
Als Kurzform für einen Indexvektor, der alle möglichen Indexwerte einer Dimension umfaßt kann : angegeben werden. Wir haben dies bisher schon getan, um den intern zugeordneten Vektor zu einem Feld zu bezeichnen. Man beachte, d&aszlig; dieser Vektor, abhängig von der Gestalt des Indexvektors als Zeilen -und als Spaltenvektor behandelt werden kann.
» A(3,3,3)=5
A(:,:,1) =
     1     0     0
     0     1     0
     0     0     0
A(:,:,2) =
     0     0     0
     0     0     0
     0     0     0
A(:,:,3) =
     0     0     0
     0     0     0
     0     0     5
» A(:,1,1)=(1:3)'
A(:,:,1) =
     1     0     0
     2     1     0
     3     0     0
A(:,:,2) =
     0     0     0
     0     0     0
     0     0     0
A(:,:,3) =
     0     0     0
     0     0     0
     0     0     5
» A=fix(abs(10*randn(5,5)))
A =
     8     3     6    16     5
    12     6    11     2     2
    15     8    12    10     9
    14     7     0    14    21
     5    12     1     8     0
» B=3+A(1:2,1:2)
B =
    11     6
    15     9
» B(:)
ans =
    11
    15
     6
     9
» B(1:4)
ans =
    11    15     6     9
» C=A(1,:)
C =
     8     3     6    16     5
» D=reshape(A,[1,25])
D =
  Columns 1 through 12 
     8    12    15    14     5     3     6     8     7    12     6    11
  Columns 13 through 24 
    12     0     1    16     2    10    14     8     5     2     9    21
  Column 25 
     0
» D(A(1,:))
ans =
      8    15     3    16     5
» A(1,5)=3
A =
     0     0     0     0     3
» A(2*(1:2))=4
A =
     0     4     0     4     3 
» A(1:5)
ans =
     0     4     0     4     3
» A(:)
ans =
     0
     4
     0
     4
     3
» A(:,:)
ans =
     0     4     0     4     3
Treten Teilfelder als Ziel von Wertzuweisungen auf, so gilt dasselbe wie für den Fall, daß einzelne Feldelemente als Ziel auftreten. Das gesamte Feld wird bei Bedarf neu erzeugt oder vergrößert. Es ist darauf zu achten, daß bei solchen Angaben keine Mehrdeutigkeiten entstehen:
» A(1:4,1:2)=5
A =
     5     5
     5     5
     5     5
     5     5
» A(3,2:3)=1
A =
     5     5     0
     5     5     0
     5     1     1
     5     5     0
» A(:,3)=2
A =
     5     5     2
     5     5     2
     5     1     2
     5     5     2
» A(:,:,1)=(1:3)'
??? Ambiguous or mismatched subscripted assignment.

Beispiel 7.1

Bei der Untersuchung des Wärmetransportes auf einer Platte betrachtet man häfig Gitter, deren Randpunkte einen vorgegebenen Wert haben.
» Git      = zeros(21,21);
» Git(:,1) = 0.0:0.05:1.0;
» Git(1,:) = Git(:,1)';
» Git(21,:)= 1.0-Git(1,:);
» Git(:,21)= 1 - Git(:,1);
Mit:
» contourf(Gitter)
erhalten wir den nachfolgenden Höhenlinienplot der Werte dieses Gitters. Um die Verteilung der Wärme auf diesem Gitter im Laufe der Zeit zu simulieren, berechnet man wiederholt den Wert jedes Gitterpunktes als Mittelwert seiner vier Nachbarpunkte:
» Git(2:20,2:20)= ...
   0.25*(Git(1:19,2:20)+Git(2:20,1:19)+Git(3:21,2:20)+Git(2:20,3:21));
» contourf(Gitter)
Das nachfolgende M-Skript erzeugt eine Schleife über diese beiden Anweisungen und damit eine rudimentäre Form der Animation, wozu gesagt werden muß daß Matlab ausgefeiltere Animationsmethoden kennt.
Git       = zeros(21,21);
Git(1,:)  = 0.0:0.05:1.0;
Git(21,:) = 1 - Git(1,:);
Git(:,1)  = Git(1,:)';
Git(:,21) = 1 - Git(:,1);
contourf(Git)
L = 2:20;
for ia=1:50
 weiter=input('Weiter?');
 for ii=1:4
  Git(L,L)=0.25*(Git(L-1,L)+Git(L,L-1)+Git(L+1,L)+Git(L,L+1));
 end
 contourf(Git);
end
Eine andere Form der Visualisierung liefert das folgende M-Skript:
Git       = zeros(21,21);
Git(1,:)  = 0.0:0.05:1.0;
Git(21,:) = 1 - Git(1,:);
Git(:,1)  = Git(1,:)';
Git(:,21) = 1 - Git(:,1);
L = 2:20;
for ia=1:21
 for ii=1:12
  Git(L,L)=0.25*(Git(L-1,L)+Git(L,L-1)+Git(L+1,L)+Git(L,L+1));
 end
 G(:,:,ia) = Git(:,:);
end
slice(G,18,18,1:10:21)
Die Gitterwerte nach den Mittelwertbildungen werden im dreidimensionalen Feld G als Ebenen abgespeichert, d.h. unter verschiedenen z-Koordinaten. Die z-Koordinate bezeichnen wir im folgenden auch als Zeit-Koordinate
Mit slice werden verschiedene Schnitte durch den Körper G (3-dimensionales Feld) dargestellt.
Die Schnitte für z=1,11 und 21 sind Höhenlinienplots für unser Gitter zu verschiedenen Zeitpunkten.
Der Schnitt für x=18 zeigt die zeitliche Veränderung der Werte längs der Gitterebene (18,:).
Der Schnitt für y=18 zeigt analog die Veränderung der Werte längs der Gitterebene (:,18).
Da beide Ebenen nahe am Rand liegen, ändert sich in ihnen die Temperatur nach kurzer Zeit kaum noch.

Beispiel 7.2

Viele physikalische Problemstellungen lassen sich durch Netze mit Knoten und diese verbindende Elemente beschreiben, man denke etwa an ein Stabwerk oder ein elektrisches Netzwerk.
Die Gleichungen, die ein solches Netz beschreiben lassen sich häfig automatisch aus den Elementlisten generieren.
Im Falle eines elektrischen Netzwerkes mit Leitwerten und Stromquellen gehen wir von Leitwert- bzw. Stromquell-Listen der Form:
   von-Knoten  zu-Knoten  Leitwert bzw. Stromstärke
aus und erzeugen das beschreibende Gleichungssystem G*p=s nach folgenden Regeln: