Mathematische Software
Transcrição
Mathematische Software
Mathematische Software Albrecht Gebhardt, Rose-Gerd Koboltschnig 7. Oktober 2013 2 Inhaltsverzeichnis 1 Einleitung 1.1 13 Notation . . . . . . . . . . . . . . . . . . . . . . . . . 2 Unix/Linux Grundlagen 14 17 2.1 Erste Schritte . . . . . . . . . . . . . . . . . . . . . . 17 2.2 Geschichtliches . . . . . . . . . . . . . . . . . . . . . 18 2.3 Grundkonzepte von Unix . . . . . . . . . . . . . . . 21 2.4 User . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.5 Kommandos . . . . . . . . . . . . . . . . . . . . . . . 24 2.5.1 Ein-/Ausgabeumleitung . . . . . . . . . . . . 26 Fileoperationen . . . . . . . . . . . . . . . . . . . . . 27 2.6.1 Verzeichnisstruktur . . . . . . . . . . . . . . . 28 2.6.2 Dateitypen . . . . . . . . . . . . . . . . . . . 28 2.6.3 Wichtige Kommandos . . . . . . . . . . . . . 30 2.6.4 Navigation in der Filehierarchie . . . . . . . . 35 2.6.5 Zugriffsrechte . . . . . . . . . . . . . . . . . . 36 Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.6 2.7 3 4 INHALTSVERZEICHNIS 2.7.1 Shellprogrammierung . . . . . . . . . . . . . 40 2.7.1.1 Variablen . . . . . . . . . . . . . . . 41 2.7.1.2 Variablensubstitution . . . . . . . . 42 2.7.1.3 Arithmetische Substitution . . . . . 43 2.7.1.4 Kommandosubstitution . . . . . . . 43 2.7.1.5 Bedingte Ausführung von Befehlen . 44 2.7.1.6 Schleifen . . . . . . . . . . . . . . . 46 2.7.1.7 Dateien einlesen . . . . . . . . . . . 47 2.8 Umgang mit X und der Desktop Oberfläche . . . . . 48 2.9 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . 50 2.9.1 Kommandozeile / Dateioperationen . . . . . 50 2.9.2 Interaktion mit X 51 . . . . . . . . . . . . . . . 3 Editoren 53 3.1 vi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3.2 emacs . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.2.1 buffers, windows, frames . . . . . . . . . . . . 57 3.2.2 Kommandos . . . . . . . . . . . . . . . . . . 58 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . 60 3.3 4 LATEX 63 4.1 Grundlagen . . . . . . . . . . . . . . . . . . . . . . . 63 4.1.1 Überblick . . . . . . . . . . . . . . . . . . . . 64 4.1.2 Dokumentaufbau . . . . . . . . . . . . . . . . 65 4.1.3 Packages . . . . . . . . . . . . . . . . . . . . 66 4.1.4 Einfacher Text . . . . . . . . . . . . . . . . . 67 INHALTSVERZEICHNIS 4.1.5 4.2 4.3 4.4 4.5 5 Gliederung . . . . . . . . . . . . . . . . . . . 69 Environments . . . . . . . . . . . . . . . . . . . . . . 69 4.2.1 Aufzählungen . . . . . . . . . . . . . . . . . . 69 4.2.2 verbatim Umgebung . . . . . . . . . . . . . . 70 4.2.3 Eigene Umgebungen . . . . . . . . . . . . . . 70 4.2.4 Formeln . . . . . . . . . . . . . . . . . . . . . 71 4.2.4.1 Formeltypen . . . . . . . . . . . . . 71 4.2.4.2 Formelelemente . . . . . . . . . . . 73 4.2.5 Tabellen . . . . . . . . . . . . . . . . . . . . . 75 4.2.6 Bilder . . . . . . . . . . . . . . . . . . . . . . 78 Querverweise . . . . . . . . . . . . . . . . . . . . . . 79 4.3.1 Fußnoten . . . . . . . . . . . . . . . . . . . . 81 4.3.2 Einfache Referenzen . . . . . . . . . . . . . . 81 4.3.3 Literaturverzeichnis . . . . . . . . . . . . . . 82 4.3.4 Stichwortverzeichnis . . . . . . . . . . . . . . 89 EX im Emacs: AUCTEX . . . . . . . . . . . . . . 4.4.1 Dateigliederung . . . . . . . . . . . . . . . . . 89 4.4.2 Command-Menü . . . . . . . . . . . . . . . . 91 4.4.3 LaTeX-Menü . . . . . . . . . . . . . . . . . . 91 4.4.4 Preview-Menü . . . . . . . . . . . . . . . . . 92 4.4.5 Math-Menü . . . . . . . . . . . . . . . . . . . 93 4.4.6 93 4.4.7 RefTEX . . . . . . . . . . . . . . . . . . . . . BibTEX . . . . . . . . . . . . . . . . . . . . . 4.4.8 Rechtschreibprüfung . . . . . . . . . . . . . . 94 Präsentationen . . . . . . . . . . . . . . . . . . . . . 95 4.5.1 96 LAT Beamer . . . . . . . . . . . . . . . . . . . . . 90 94 6 INHALTSVERZEICHNIS 4.5.2 Prosper . . . . . . . . . . . . . . . . . . . . . 5 Computer Algebra Systeme 5.1 97 99 Überblick . . . . . . . . . . . . . . . . . . . . . . . . 100 5.1.1 MAXIMA . . . . . . . . . . . . . . . . . . . . 100 5.1.2 Reduce . . . . . . . . . . . . . . . . . . . . . 104 5.1.3 Axiom . . . . . . . . . . . . . . . . . . . . . . 106 5.1.4 Maple . . . . . . . . . . . . . . . . . . . . . . 108 5.1.5 Mathematica . . . . . . . . . . . . . . . . . . 111 5.1.6 MuPAD . . . . . . . . . . . . . . . . . . . . . 112 5.1.7 Yacas . . . . . . . . . . . . . . . . . . . . . . 114 5.2 Einfache Arithmetik . . . . . . . . . . . . . . . . . . 116 5.3 Funktionen . . . . . . . . . . . . . . . . . . . . . . . 122 5.4 Gleichungen . . . . . . . . . . . . . . . . . . . . . . . 125 5.5 Grenzwerte . . . . . . . . . . . . . . . . . . . . . . . 127 5.6 Differentiation . . . . . . . . . . . . . . . . . . . . . 128 5.7 Integrale . . . . . . . . . . . . . . . . . . . . . . . . . 131 5.8 Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 5.9 Aufgaben . . . . . . . . . . . . . . . . . . . . . . . . 133 5.9.1 Einfache Anwendungen . . . . . . . . . . . . 133 5.9.2 Funktionen . . . . . . . . . . . . . . . . . . . 140 6 R 143 6.1 Geschichte von S und R . . . . . . . . . . . . . . . . 143 6.2 Erste Schritte mit R . . . . . . . . . . . . . . . . . . 144 6.3 Arithmetik mit R . . . . . . . . . . . . . . . . . . . . 146 INHALTSVERZEICHNIS 6.4 7 Vektoren . . . . . . . . . . . . . . . . . . . . . . . . . 148 Zugriff auf einzelne Werte eines Vektors 150 6.5 Matrizen . . . . . . . . . . . . . . . . . . . . . . . . . 153 Zugriff auf einzelne Werte einer Matrix 153 6.6 Listen und dataframes . . . . . . . . . . . . . . . . . 159 6.7 Einlesen externer Daten . . . . . . . . . . . . . . . . 161 6.7.1 Verwenden der scan-Funktion . . . . . . . . . 161 6.7.2 Verwenden der read.table-Funktion . . . . . 162 6.7.3 Laden von Daten aus anderen R-Paketen . . . 166 Datenanalyse mit R . . . . . . . . . . . . . . . . . . . 168 6.8.1 Einfache Grafiken . . . . . . . . . . . . . . . 168 6.8.1.1 Balken- oder Stabdiagramme . . . . 169 6.8.1.2 Kreisdiagramme . . . . . . . . . . . 174 6.8.1.3 Streifendiagramme . . . . . . . . . . 175 6.8.1.4 Liniendiagramme . . . . . . . . . . 176 6.8.1.5 Weitere Graphikfunktionen . . . . . 179 Visualisieren der Verteilung der Daten . . . . 180 6.8.2.1 181 6.8 6.8.2 Stamm-Blatt-Diagramme . . . . . . Das Basisdiagramm 6.8.3 6.8.4 . . . . . . . . . . 182 6.8.2.2 Histogramme . . . . . . . . . . . . . 184 6.8.2.3 Das Boxplot . . . . . . . . . . . . . 188 Zusammenhang zwischen Merkmalen . . . . . 193 6.8.3.1 Streudiagramme . . . . . . . . . . . 193 6.8.3.2 Korrelation zwischen zwei Merkmalen 194 Lineare Regression - Methode der kleinsten Quadrate . . . . . . . . . . . . . . . . . . . . 197 8 INHALTSVERZEICHNIS 6.9 Programmieren mit R 6.9.1 6.9.2 . . . . . . . . . . . . . . . . . 199 Steueranweisungen und Funktionen in R . . . 199 6.9.1.1 Bedingte Ausführung: if . . . . . . 199 6.9.1.2 Wiederholte Ausführung: for-Schleifen200 6.9.1.3 Einige eingebaute Funktionen . . . . 202 6.9.1.4 Definieren einfacher Funktionen . . 202 Funktionen erstellen und editieren . . . . . . 203 6.9.2.1 Einlesen von Funktionen aus und Speichern von Funktionen in eine Datei 205 6.10 Interface zu externen Routinen in C oder Fortran . . 205 6.10.1 Grundlagen . . . . . . . . . . . . . . . . . . . 206 6.10.2 C Interface . . . . . . . . . . . . . . . . . . . 207 6.10.3 Fortran Interface . . . . . . . . . . . . . . . . 208 6.11 Pakete . . . . . . . . . . . . . . . . . . . . . . . . . . 210 6.11.1 Filestruktur . . . . . . . . . . . . . . . . . . . 211 6.11.2 Hilfeseiten . . . . . . . . . . . . . . . . . . . . 212 6.11.3 C / Fortran . . . . . . . . . . . . . . . . . . . 215 6.11.4 Installation von Paketen . . . . . . . . . . . . 218 6.12 R, Emacs und LAT EX . . . . . . . . . . . . . . . . . . 7 Octave 219 223 7.1 Grundlagen . . . . . . . . . . . . . . . . . . . . . . . 224 7.2 Variablen und Datentypen . . . . . . . . . . . . . . . 225 7.3 Operatoren . . . . . . . . . . . . . . . . . . . . . . . 229 7.4 Steueranweisungen . . . . . . . . . . . . . . . . . . . 231 7.4.1 231 Verzweigungen . . . . . . . . . . . . . . . . . INHALTSVERZEICHNIS 7.4.2 9 Schleifen . . . . . . . . . . . . . . . . . . . . . 232 7.5 Funktionen . . . . . . . . . . . . . . . . . . . . . . . 234 7.6 Grafik . . . . . . . . . . . . . . . . . . . . . . . . . . 239 7.7 Octave, LATEX und Emacs . . . . . . . . . . . . . . . Aufgaben . . . . . . . . . . . . . . . . . . . . . . . . 240 242 7.8.1 Nullstellenbestimmung . . . . . . . . . . . . . 242 7.8.2 Gleichungssysteme mit Töplitzmatrizen . . . 246 7.8 8 Programmieren 8.1 8.2 255 Hilfsmittel . . . . . . . . . . . . . . . . . . . . . . . . 255 8.1.1 Make . . . . . . . . . . . . . . . . . . . . . . 255 FORTRAN . . . . . . . . . . . . . . . . . . . . . . . 258 8.2.1 Geschichte . . . . . . . . . . . . . . . . . . . . 258 8.2.2 Aufbau von FORTRAN Programmen . . . . 258 8.2.2.1 Verwendbare Zeichen . . . . . . . . 258 8.2.2.2 Zeilen . . . . . . . . . . . . . . . . . 259 8.2.2.3 Struktur von FORTRAN Programmen260 8.2.2.4 Unterprogramme und Funktionen . 261 8.2.2.5 Compileraufruf . . . . . . . . . . . . 262 Datentypen und Variablendeklarationen . . . 263 8.2.3.1 Typen . . . . . . . . . . . . . . . . . 263 8.2.3.2 Die PARAMETER Anweisung . . . . . 264 8.2.3.3 Variablen . . . . . . . . . . . . . . . 264 8.2.4 Ausdrücke . . . . . . . . . . . . . . . . . . . . 266 8.2.5 Ein- und Ausgabe . . . . . . . . . . . . . . . 267 8.2.5.1 268 8.2.3 Dateioperationen . . . . . . . . . . . 10 INHALTSVERZEICHNIS 8.2.6 8.2.7 8.2.8 Steueranweisungen . . . . . . . . . . . . . . . 269 8.2.6.1 Bedingungen . . . . . . . . . . . . . 269 8.2.6.2 Schleifen und Verzweigungen . . . . 270 Beispiel - lineare Interpolation . . . . . . . . 271 Einfache Variante, Daten fix eingetragen mittels DATA . . . . . . 271 Verbesserte Variante, mit Sortierung . 274 Verbesserte Variante, Daten aus Datei 276 Variante mit Unterprogramm . . . . . 278 Anwendung: LAPACK . . . . . . . . . . . . . 280 8.2.8.1 8.3 Einfache Vektor- und Matrixoperationen . . . . . . . . . . . . . . . . 281 8.2.8.2 Lineare Gleichungssysteme . . . . . 285 8.2.8.3 Eigenwertaufgaben . . . . . . . . . . 287 8.2.8.4 Beispiele . . . . . . . . . . . . . . . 290 Lösungen: . . . . . . . . . . . . . . . . 291 C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 8.3.1 Programmaufbau . . . . . . . . . . . . . . . . 305 8.3.1.1 Compileraufruf . . . . . . . . . . . . 307 8.3.2 Schlüsselwörter und Bezeichner . . . . . . . . 308 8.3.3 Datentypen . . . . . . . . . . . . . . . . . . . 309 8.3.3.1 Elementare Typen . . . . . . . . . . 310 Integer Typen . . . . . . . . . . . . . . 310 Gleitkommatypen . . . . . . . . . . . . 311 Abgeleitete Typen . . . . . . . . . . 311 Vektoren . . . . . . . . . . . . . . . . . 311 8.3.3.2 INHALTSVERZEICHNIS 8.4 11 Aufzählungstypen . . . . . . . . . . . . 312 Zusammengesetzte Typen . . . . . . . 312 8.3.3.3 Zeiger . . . . . . . . . . . . . . . . . 314 8.3.3.4 Zeichenkonstante und Stringliterale 316 8.3.4 Operationen . . . . . . . . . . . . . . . . . . . 316 8.3.5 Steueranweisungen . . . . . . . . . . . . . . . 319 8.3.5.1 Bedingungen . . . . . . . . . . . . . 319 8.3.5.2 if Verzweigung . . . . . . . . . . . 319 8.3.5.3 switch Verzweigung . . . . . . . . . 320 8.3.5.4 for Schleifen . . . . . . . . . . . . . 320 8.3.5.5 while Schleifen . . . . . . . . . . . 321 8.3.6 Funktionen . . . . . . . . . . . . . . . . . . . 321 8.3.7 Interface zu FORTRAN Funktionen . . . . . 323 8.3.8 LAPACK und C . . . . . . . . . . . . . . . . 325 Debugging . . . . . . . . . . . . . . . . . . . . . . . . 328 Tabellen 332 Abbildungen 335 Literatur 336 Index 340 12 INHALTSVERZEICHNIS Kapitel 1 Einleitung Die Lehrveranstaltung Mathematische Software“ hat zum Ziel, Sie ” mit einigen der Werkzeuge bekannt zu machen, denen Sie während Ihrer Ausbildung begegnen werden. Dabei kann natürlich nicht auf alles eingegangen werden. Um Ihnen trotzdem einen ausreichenden Überblick geben zu können, werden die unterschiedlichen Softwarepakete auch nicht bis ins letzte Detail vorgestellt. Vielmehr soll Ihnen die Fähigkeit vermittelt werden, aufbauend auf Grundkenntnissen sich selbständig die erforderlichen Fähigkeiten sukzessive anzueignen. Es werden Ihnen soweit möglich solche Softwarepakete präsentiert, die einerseits in Freeware Implementierungen, andererseits aber auch in kommerziellen Formen existieren. Auf diese Weise soll Ihnen der problemlose Zugriff auf die verschiedenen “mathematischen Programmiersprachen” ermöglicht werden, ohne Sie zum Kauf (immer noch recht teurer) Studentenversionen zu zwingen. Beispiele dafür sind die Kombinationen R/S-PLUS oder octave/MATLAB. Teilweise existieren die Programme nur in der freien Version (LATEX), manche 13 14 KAPITEL 1. EINLEITUNG nur in einer (allerdings kostenlosen) Studentenversion (AMPL). Im mathematischen Bereich haben sich seit langem Unix Systeme wegen ihrer Stabilität, Multiuserfähigkeit und standardisierten Programmierbarkeit durchgesetzt. Aus diesem Grund basieren alle vorgestellten Programmpakete auf Unix. In unserem Fall kommt Linux, ein freies Unix(-ähnliches) Betriebssystem zum Einsatz. Zum Teil existieren auch Windowsvarianten der besprochenen Programme, deren Bedienung meist äquivalent erfolgt. Die Installation derselben müssen Sie aber selbst bewältigen1 . Als Einstieg zu Linux wird Ihnen mit der jeweils aktuellen Ubuntu Live-CD ein komplett von CD lauffähiges System zur Hand gegeben. 1.1 Notation Zur Notation wird soweit als möglich folgende Metasysntax verwendet: • Ein- und Ausgaben von Programmen, Befehle und Programmteile werden in Schreibmaschinenschrift gesetzt. • Schlüsselworte der entsprechenden Programme oder Programmiersprachen werden zusätzlich fett gedruckt. • Kommentare im Kommentarstil der jeweiligen Anwendung erscheinen kursiv • Wenn nötig werden Leerzeichen und Tabulatoren durch ??? hervorgehoben. • Platzhalter für Bezeichner und Werte die vom Anwender erst einzusetzen sind werden unterstrichen 1 Wir sehen es natürlich lieber, wenn Sie sich gleich an eine Linuxinstallation wagen ;-) 1.1. NOTATION 15 • Optionale Parameter werden in hohle eckige Klammern J und K gesetzt. • Sich gegenseitig ausschliessende Alternativen werden in verdoppelte runde Klammern (( und )) eingeschlossen und mit einem hohlen Balken [] getrennt. 16 KAPITEL 1. EINLEITUNG Kapitel 2 Unix/Linux Grundlagen 2.1 Erste Schritte Zunächst die wichtigsten Schritte für Neulinge: • Wie fahre ich einen Rechner im Studentenbereich unter Linux hoch? 1. Falls Windows läuft: Neu Starten“, sonst lediglich ein” schalten, 2. Bootmenü abwarten, 3. mit Cursortasten Linux starten“ auswählen, Enter . ” • Wie schalte ich ihn wieder aus oder wechsele zu Windows zurück? 17 18 KAPITEL 2. UNIX/LINUX GRUNDLAGEN 1. Zuerst abmelden ( System/Log out“ bei Verwendung von ” GNOME, Logout“ im K“-Menü bei Verwendung von ” ” KDE) 2. danach Halt“, Restart“ oder Reboot“ wählen. ” ” ” 2.2 Geschichtliches Die Geschichte von UNIX beginnt Ende der 60er Jahre bei AT&T, dem damals noch in dieser Form existierenden Telefonmonopolisten der USA. • 1969: Ken Thompson entwickelt UNICS in Assembler auf einer DEC PDP 7 (ein 18 Bit Computer) (Er versuchte damit, Entwicklungen aus dem zuvor gescheiterten Projekt eines Grossrechnerbetriebssystems MULTICS zu retten) • 1971: Ken Thompson und Dennis Ritchie schreiben UNIX (jetzt schon X statt CS) auf einer DEC PDP 11 neu1 , Dennis Ritchie entwickelt dazu die Programmiersprache C (sie ist Nachfolger der Sprache B, daher ihr Name, siehe auch Abschnitt 8.3) • 70er Jahre: AT&T beginnt UNIX zu vermarkten, Universitäten erhalten den Quelltext gegen geringe Kosten, an der Berkeley University entsteht eine abgewandelte und erweiterte Version: BSD (Berkeley Software Distribution) • 1983: Die AT&T Version von UNIX entwickelt sich zum System V • 1983: 4.2BSD wird mit TCP/IP Netzwerkfähigkeit ausgestattet. 1 http://research.microsoft.com/~gbell/Digital/timeline/quiz8r.htm 2.2. GESCHICHTLICHES 19 Abbildung 2.1: D. Ritchie und K. Thompson an einer DEC PDP 11 20 KAPITEL 2. UNIX/LINUX GRUNDLAGEN • 1983: Richard Stallman startet das GNU2 Projekt, eine Initiative zur Erstellung freier Software, um die Freiheit der User und Programmierer bei der Wahl ihrer Werkzeuge zu sichern. • 1986: Die grafische Oberfläche X (heute X11 Release 7) erscheint, zuerst entwickelt auf DEC VAX Rechnern. • 80/90er Jahre: Es entstehen viele kommerzielle Version von UNIX, meist von den Herstellern entsprechender Unix-Workstations: AIX (IBM), SunOS später Solaris (SUN), Ultrix (DEC), OSF - später Digital Unix, heute Tru64 Unix (DEC, dann Compaq jetzt HP), HP-UX (HP), IRIX (SGI), Sinix (Siemens), Xenix (Microsoft) später SCO UNIX, UnixWare (der direkte Nachfahre von System V) usw., die meist verschiedene Eigenschaften von System V“ und BSD“ kombinieren. ” ” Diese Durchschnittsmenge von SVR4 (System V Release 4) und BSD begründet den POSIX3 Standard, dies bildet die Grundlage der Quelltextportabilität zwischen vielen neu entstehenden UNIX Varianten. • 1991 beginnt Linus Torwalds Linux zu entwickeln, mit der Zeit wird dies neben den freien BSD Unixen (FreeBSD/NetBSD/OpenBSD) zum wohl bekanntesten Vertreter der frei erhältlichen Unixe. FreeBSD ist übrigens der Grundbaustein von MacOS X. Genaueres über die Anfänge von UNIX findet man z.B. in Ritchie [1980]. Bilder der PDP und VAX Maschinen, mit denen die UNIX Entwicklung begann, sowie weitere Informationen zur UNIX Geschichte kann man unter folgenden Adressen finden: 2 GNU= GNU is Not UNIX“, http://www.gnu.org/gnu/gnu-history.html Operating System ” 3 Portable 2.3. GRUNDKONZEPTE VON UNIX 21 http://vt100.net/timeline/ http://www.unix-systems.org/what_is_unix/history_timeline.html Einen Überblick über die Abstammungsverhältnisse“ gibt folgen” der Link: http://www.levenez.com/unix/history.html 2.3 Grundkonzepte von Unix Folgendes ist eine Auswahl der wichtigsten Eigenschaften von UNIX Systemen: • Multitasking (Prozesse können neue Prozesse starten ( fork“) ” und dann parallel laufen), • Multiuserfähigkeit ( time sharing“, mehrere Benutzer teilen ” sich einen Rechner), • einheitliches Dateisystem (alles als File abbildbar, z.B. auch Systemkomponenten ( devices“)), Baumstruktur, ” • ein Kernel (unix, vmunix, vmlinuz) führt Systemaufgaben durch (Geräte-, Speicher- und Prozeßverwaltung), • die restliche Arbeit wird von vielen kleinen austauschbaren Useranwendungen erledigt ( userland applications“ und dae” ” mons“), • die Kommunikation zwischen einzelnen Tools erfolgt (u.a.) über 22 KAPITEL 2. UNIX/LINUX GRUNDLAGEN pipes“4 , wurde später auch in DOS-Kommandos wie dir | ” ” more“ verwendet, • Netzwerkfähigkeit (UDP, TCP/IP), • Shell-Interface (Kommandozeile) für Benutzer. Die grafische Oberfläche (das X Window System, kurz X11) ist übrigens nicht Teil des Betriebssystems, sondern auch nur einer von den vielen Bausteinen, die den Betriebsystemkern, das eigentliche Unix, umgeben. Das bedeutet, falls der Bildschirm einmal einfrie” ren“ sollte, muß das nicht heißen, daß der Rechner abgestürzt ist. Es kann lediglich der X Server ein Problem haben, das System läuft derweil ungestört weiter (und ein Administrator könnte sich z.B. über das Netzwerk in den Rechner einloggen und das Problem mit dem X Server lösen). Diese Modularität ist also eine der Hauptursachen für die Stabilität von UNIX Systemen. Die uptime“, also die Ge” samtlaufzeit ohne Ausschalten oder Neustart, von UNIX Systemen beträgt üblicherweise etliche Wochen und Monate (meist kommen nur Stromausfälle oder Hardwarekomponententausch dazwischen). Wie ein UNIX System ohne X11 Oberfläche aussehen kann, können Sie anschauen, wenn Sie mittels Ctl - Alt - F1 auf die erste virtuelle Textkonsole umschalten. Davon gibt es bei den meisten Linuxinstallation sechs Stück ( F1 durch F2 usw. ersetzen), auf der Konsole 7 ( Alt - F7 ) läuft der X Server. Ein X Server allein würde allerdings überhaupt nicht benutzbar sein, man benötigt sogenannte X Clients (Fenster) und vor allem einen Window Manager (er stellt u.a. die Rahmen um die Fenster her). Eine Linuxinstallation besteht also z.B. aus 4 demons [sic] with forks running along the pipes“ - dies hat die Motivation ” für das BSD Maskottchen, den BSD-daemon, geliefert (http://web.archive. org/web/20071226210407/http://www.lemis.com/grog/whyadaemon.html bzw. http://www.mckusick.com/beastie/jpg/foglio.jpg) 2.4. USER 23 • dem Linuxkern (Datei /boot/vmlinuz), • vielen kleinen Tools und Anwendungen, meist aus dem GNU Projekt stammend (deshalb ist die korrekte Bezeichnung eigentlich auch GNU/Linux, z.T. wird aber auch BSD Software verwendet), • dem X.org5 Server als grafischer Oberfläche und • GNOME (http://www.gnome.org) oder KDE6 als Desktop Environment (KDE und GNOME umfassen viel mehr als die Windowmanager Funktionen, z.B. die Applikationsleiste, das Startmenü usw.). Die Zusammenstellung aus Linux Kern, GNU- und anderen Applikationen nennt man im Linux Bereich Distribution“. Auf der Univer” sität Klagenfurt ist zur Zeit die Ubuntu“7 Distribution im Einsatz. ” Einführende Literatur ist z.B. Ronneburg [2001], umfassenden Überblick geben Herold [1999] und Kofler [2000]. 2.4 User Die Welt aus Sicht eines Unixanwenders teilt sich in drei Klassen: • ihn selbst, also den User, • seine (und andere) Gruppe(n) von Usern, • alle restlichen User. 5 http://www.x.org/ 6K Desktop Environment, http://www.kde.org http://www.ubuntu.com 7 ubuntu: 24 KAPITEL 2. UNIX/LINUX GRUNDLAGEN Auf dieser Dreiteilung baut das Berechtigungsschema zum Zugriff auf Dateien und Verzeichnisse auf. Jeder der drei Kategorien kann getrennt das Schreib-, Lese- und Ausführungsrecht gegeben oder entzogen werden. Identifiziert werden User und Gruppen über IDs, Nummern (UID und GID). Klasse login user group other Kürzel (bei ls, siehe unten) u g o Identifikation UID GID - Tabelle 2.1: Usereinteilung Es existiert ein spezieller User mit Sonderrechten, der Administrator root“ (UID=0, GID=0). ” Wenn sich ein User einloggt, wird zunächst sein Passwort überprüft und, wenn dieses stimmt, seine Loginshell“ gestartet und ein ” Sprung ins Homeverzeichnis“ des Users ausgeführt. Beim grafischen ” Login übernimmt ein Displaymanager das Starten des entsprechenden Windowmanagers. Die Loginshell erscheint dort erst nach dem Öffnen eines Kommandofensters (z.B. xterm). Das Homeverzeichnis liegt üblicherweise unter /home/users/name und lässt sich auch als ~name oder einfach ~ abkürzen, es ist ebenfalls in der Umgebungsvariablen HOME gespeichert. 2.5 Kommandos Nach dem Starten der Shell kann der User Kommandos starten. Die allgemein übliche Form dazu ist command -option(s) arguments 2.5. KOMMANDOS 25 Bei den Optionen gibt es meist Kurz- und Langformen unterschieden durch einen oder zwei Striche. Optionen in Kurzform können hinter einem Strich beliebig kombiniert werden. # ls zeigt den Inhalt von Verzeichnissen an, # unter DOS/Windows: dir ls -a # ls Befehl (-a: alle Dateien, # auch versteckte) ls --all # mit langer Option ls -l -a # zwei kurze Optionen (-l: ausführlich) ls -la # beides kombiniert ls -al # Reihenfolge egal Da man sich natürlich nicht alle Optionen merken kann, gibt es im allgemeinen zu jedem Kommando eine Dokumentation. Viele Kommandos geben mit command -h command --help command -? eine kurze Übersicht der Optionen. Ausführlicher sind die Manualpages die mittels man command angezeigt werden, ein alternatives Format der Hilfeseiten wird mit info command zugänglich (die Anzeige bei man und info wird mit q beendet). Natürlich funktionieren nicht bei jedem Kommando alle diese Methoden, aber mindestens eine führt fast immer zum Erfolg. Falls man 26 KAPITEL 2. UNIX/LINUX GRUNDLAGEN unter X arbeitet und von der Kommandozeile aus ein Programm startet, das ein neues Fenster öffnet (z.B. ein Webbrowser), muss man wie folgt vorgehen: xcommand & Das & Zeichen hinter dem Kommando bewirkt, daß das Programm xcommand im Hintergrund“ gestartet wird, d.h. daß der Komman” dozeilenprompt sofort wieder benutzbar ist und das Fenster von xcommand mehr oder weniger schnell als Paralellprozeß geöffnet wird. Vergisst man das & Zeichen, ist die Kommandozeile solange blockiert, wie xcommand läuft. 2.5.1 Ein-/Ausgabeumleitung Die Ein- und Ausgabe für Kommandos erfolgt (soweit dies keine grafischen Anwendungen sind) über die sog. Standardein- und ausgabekanäle, d.h. Eingabe per Tastatur, (Text-) Ausgabe im Terminal. Mit den Operatoren <, >, << und >> kann man Ein- und Ausgabe auf/von anderen Dateien umleiten: command <inputfile command >outputfile command <inputfile >outputfile Das Programm wartet dann nicht auf Tastatureingaben (falls es überhaupt darauf wartet), sondern liest diese aus dem File inputfile, die Ausgabe des Programms erscheint nicht mehr am Bildschirm sondern wandert in die Textdatei outputfile Mit command >>outputfile 2.6. FILEOPERATIONEN 27 wird das Ausgabefile nicht überschrieben sondern neue Ausgaben werden am Ende angehängt. Der Operator << wird für sog. hereDokumente (Programmeingabe wird zwischen << und eine mit <<MARKE vereinbarte Endekennung geschrieben) verwendet, dies hat aber nur eine Bedeutung für die Shellprogrammierung: command <<EOT ... Eingabe fuers Programm ... EOT Neben Standardein- und -ausgabe existiert auch noch die Standardfehlerausgabe, diese hat die Kanalnummer 2 und kann wie folgt in eine extra Datei umgeleitet werden (hier in Kombination mit den anderen Umleitungen): command <inputfile >outputfile 2>errorfile Gebräuchliches Beispiel: Umleitung von Fehlermeldungen auf das Null-Device, wenn man die Fehlermeldungen nicht sehen will: command 2>/dev/null 2.6 Fileoperationen Für den Anfang ist es wichtig, die Organisation des Filesystems zu verstehen und wichtige Fileoperationen zu kennen. Für das erste Erkunden der Struktur des Filesystems (siehe Abb. 2.2) lässt sich der Filemanager des jeweils benutzen Desktop Environments verwenden. Um die Details, insbesondere die Rechtevergabe zu verstehen, ist besser, auf die Kommandozeile zurückzukehren. 28 KAPITEL 2. UNIX/LINUX GRUNDLAGEN 2.6.1 Verzeichnisstruktur Die Verzeichnisstruktur auf allen UNIX Systemen ist annähernd gleich, bedingt dadurch, daß ein gemeinsamer Vorfahr“ existiert. ” Neuerdings gibt es Bestrebungen, auch die letzten Unterschiede zu minimieren, diesem Ziel ist der FHS8 gewidmet. Die gemeinsame Wurzel aller Verzeichnisse bildet /“, das Root Di” rectory. Unter diesem schließen sich das Root Filesystem (wichtige Daten und Programme für den Systemstart, es enthält Konfigurationsdaten in /etc“). Dann folgen das /usr“ Filesystem mit den ” ” Standard Applikationen, das /usr/local“ Filesystem mit Anwen” dungen die der lokale Administrator dem System hinzugefügt hat, ein Filesystem mit den Homeverzeichnissen der User und eventuell unter /opt“ optionale weitere Software an. In den meisten die” ser Teilhierarchien wiederholt sich eine Aufteilung in bin“, sbin“, ” ” lib“ und man“ Verzeichnisse für normale Anwendungen, statisch ” ” gelinkte oder wichtige Systemanwendungen, Libraries und Manualpages. Für den normalen User sind lediglich das /tmp“- und sein Ho” meverzeichnis beschreibbar, das Homeverzeichnis ist dabei meist für andere auch nicht lesbar. 2.6.2 Dateitypen Von den Dateitypen, die in Tabelle 2.2 zusammengefasst sind, sind natürlich nicht alle für Sie relevant. Wichtig sind die einfachen Dateien und Verzeichnisse, mit denen Sie natürlich schon von anderen Systemen her vertraut sind, es kommen die sogenannten symbolischen Links hinzu sowie die Bedeutung der Rechtevergabe für diese 8 filesystem hierarchy standard, siehe z.B. http://www.debian.org/doc/packaging-manuals/fhs/ 2.6. FILEOPERATIONEN 29 Abbildung 2.2: Schema der Filesystemhierarchie Typ normales File Link Directory Devices named pipes sockets Kürzel bei ls -l - (hard link), l (symlink) d c oder b p s Tabelle 2.2: Dateitypen Anmerkungen = Verweise auf andere Dateien 30 KAPITEL 2. UNIX/LINUX GRUNDLAGEN Dateitypen. Dateinamen müssen keiner speziellen Konvention (z.B. 8.3) folgen, es empfiehlt sich aber, auf Leerzeichen und Umlaute (und natürlich Sonderzeichen mit spezieller Bedeutung) zu verzichten. ACHTUNG: Groß/Kleinschreibung spielt im Gegensatz zu Windows eine Rolle, d.h. die Dateien datei.txt, Datei.txt und DaTeI.Txt sind drei verschiedene Sachen! 2.6.3 Wichtige Kommandos Die wichtigsten Kommandos im Umgang mit Dateien sind: • Inhalt eines Verzeichnisses (list) ls ls dir ls datei das Ganze in Langform mit Angabe von Eigentümer, Rechten usw. ls -l ls -l dir ls -l datei • Datei ausgeben cat datei • Führende N Zeilen von Datei ausgeben 2.6. FILEOPERATIONEN 31 head -nN datei • Letzte N Zeilen von Datei ausgeben tail -nN datei • Datei anschauen (dazu werden sogenannte pager“ verwen” det, die meist eine minimale Navigation mit Bild auf und Bild ab ermöglichen, Ausstieg aus pagern üblicherweise mit q) more datei less datei pg datei • Directory anlegen mkdir dir • Datei kopieren cp datei kopie ein ganzes Verzeichnis kopieren (rekursiv) cp -r dir.alt dir.neu 32 KAPITEL 2. UNIX/LINUX GRUNDLAGEN • Datei oder leeres Directory löschen rm datei rmdir dir volles Directory löschen rm -r dir • Datei oder Directory umbenennen oder in ein anderes Verzeichnis verschieben (Umbenennen ist eigentlich nur ein Spezialfall von Verschieben) mv datei.alt datei.neu mv dir1/datei dir2/subdir3/datei mv dir1 dir2/subdir1 Im Gegensatz zum Verschieben von Verzeichnissen unter Windows (dort wird zum Ziel kopiert und dann die Quelle gelöscht, das dauert also eine Weile) wird unter Unix der Inhalt das Verzeichnisses nur an anderer Stelle in die Hierarchie eingehängt, es werden also keine Daten transportiert (außer die Verschiebung erfolgt über Datenträgergrenzen hinweg, z.B. von Festplatte auf Diskette). • hard links“ erzeugen: ” ln datei link Symbolische Links erzeugen: 2.6. FILEOPERATIONEN 33 ln -s datei link Links sind gewissermaßen Zeiger auf andere Dateien (oder Verzeichnisse, dies aber nur bei symbolischen Links). Bei einem hard link“ sind Datei und Link danach gleichbe” rechtigt, die Daten verschwinden erst bei Löschen der letzten Referenz vom Filesystem (Eigentlich ist jede Datei ein hardlink mit Referenzcounter=1). Ein Symlink ist eine Spezialdatei die einen Verweis auf den Pfad (absolut oder relativ) zum angegebenen Ziel enthält. Das Löschen des symlinks löscht nicht die Datei. Das Löschen der Datei macht den symlink wertlos, der dann auf etwas nicht mehr Vorhandenes zeigt (dangling symlink). Weitere wichtige Kommandos sind • find zum Suchen (besser Finden ;-) von Dateien # find startdir -name gesuchter_name find . -name test.txt # "." steht fuers # aktuelle Directory find subdir1 -name test.\* # * ist "maskiert" # mit dem Zeichen "\" # siehe Abschnitt zur # Shell find . -type d # sucht alle Directories # -type f fuer Suche # nach Dateien • grep zum Suchen von Mustern in Dateien: 34 KAPITEL 2. UNIX/LINUX GRUNDLAGEN # grep Muster datei1 datei2 ... grep agebhard /etc/passwd # sucht den Text agebhard # in der passwd Datei grep \?gebhard /etc/passwd # sucht alle Usernamen die # auf dieses Muster passen, # "?" ist wieder "maskiert" In Verbindung mit find lässt sich grep wie folgt anwenden: # find dir -name muster -exec grep inhalt {} \; find /etc -name p\* -exec grep agebhard {} \; # sucht alle Dateien in \texttt{/etc} deren Name # mit p beginnt und die den Text "agebhard" enthalten. • tar (tape archiver) zum Ein- und Auspacken von Archiven, hält sich offensichtlich nicht an die Konvention Optionen mit - zu beginnen: tar cfv archiv.tar file1 file2 dir1 # "c" create Archiv # "v" fuer verbose # "f" Ausgabefile tar tfv archiv.tar # "t" type # =Auflisten des Inhalts # "f" Eingabefile tar xvf archiv.tar # "x" extract Bei komprimierten Archiven (z.B. archiv.tar.gz) kommt einfach noch die Option z“ dazu (bei Kommpression mit bzip2 ” das eine höhere Kompressionsrate liefert, z.B. archiv.tar.bz2, 2.6. FILEOPERATIONEN 35 die Option j“), die Option v“ bedeutet verbose“ und produ” ” ” ziert Kontrollausgaben der Vorgänge am Bildschirm. Die Option f“ signalisiert die Angabe des Filenamens des Archivs, ” ansonsten würde tar versuchen das Archiv von einem Bandlaufwerk zu lesen. tar xzvf archiv.tar.gz tar xjvf archiv.tar.bz2 # # # # "x" "z" "x" "j" extract, gzip compressed extract, bzip2 compressed • ZIP Archive werden mit zip archiv.zip datei1 subdir1/* erstellt, mit unzip archiv.zip ausgepackt, und mit zip -l archiv.zip lässt man sich das Inhaltsverzeichnis anzeigen. 2.6.4 Navigation in der Filehierarchie Auch wenn Ihnen die Möglichkeiten das grafischen Navigierens durch den Filemanager geboten sind, sollten Sie dennoch die wichtigsten Kommandos zur Navigation per Kommandozeile beherrschen. Damit ist es Ihnen später auch möglich über eine einfache Terminalverbindung, z.B. von zu Hause aus, oder direkt aus einer Anwendung wie R oder octave auf Ihre Dateien zuzugreifen. 36 KAPITEL 2. UNIX/LINUX GRUNDLAGEN • Information über aktuelles Verzeichnis (Wo bin ich? print ” working directory“) pwd • in ein Verzeichnis wechseln cd cd cd cd dir dir/subdir ../subdir2 /tmp Das aktuelle Verzeichnis wird mit . abgekürzt, cd .“ wech” ” ” selt also nirgendwo hin. Verzeichnisse werden relativ (ohne führenden slash /“) oder absolut (mit führendem /) angegeben. ” • temporär in ein Verzeichnis wechseln (Sie wollen zum Ausgangspunkt zurückspringen können, ohne diesen dazu voll ausschreiben zu müssen) pushd temp/subdir wieder zum Ausgangspunkt zurück mit popd 2.6.5 Zugriffsrechte Die Zugriffsrechte werden über die Dateiattribute verwaltet. Diese teilen sich in drei Gruppen, je nachdem wer betroffen ist, siehe 2.1: 2.6. FILEOPERATIONEN 37 • Eigentümer der Datei, • Gruppenzugehörigkeit der Datei, • Rechte für den Rest der Welt. Es können die drei Rechte Lesen (r), Schreiben (w), und Ausführen (x) vergeben werden. Lese- und Schreibrecht sind so zu deuten wie man es erwartet, das Ausführungsrecht kennzeichnet Programme (kompilierte Binärprogramme oder Shellskripts (Batchdateien im DOS Sprachgebrauch)). Programme unter UNIX sind also NICHT an irgendeiner Dateiendung (.exe) zu erkennen und tragen solche Endungen auch nicht! Die Bedeutung des Ausführungsrechts für Verzeichnisse besteht darin, daß das Wechseln (cd) in das Verzeichnis erlaubt wird oder nicht. Das Schreibrecht auf ein Verzeichnis bedeutet, daß man Dateien dort Anlegen und Löschen kann. Wenn also eine Datei zwar schreibgeschützt ist für jemanden der aber dennoch das Schreibrecht auf dem Verzeichnis der Datei hat, kann dieser die Datei zwar nicht ändern aber dennoch löschen! Die Anzeige der Rechte geschieht mit ls -l datei und wird z.B. wie folgt aussehen (hier gleich für ein ganzes Verzeichnis) touch test.txt ln test.txt test.link ln -s test.txt test.symlink echo "test" > test.dat mkdir test.dir ls -l total 180 38 KAPITEL 2. UNIX/LINUX GRUNDLAGEN drwxr-xr-x drwxr-xr-x -rw-r--r-drwxrwxr-x -rw-rw-r-lrwxrwxr-x -rw-rw-r-- 3 38 1 2 2 1 2 agebhard agebhard agebhard agebhard agebhard agebhard agebhard ^^^^^^^^^^ ^ | Rechte | User Typ Referenzcounter agebhard agebhard agebhard agebhard agebhard agebhard agebhard Gruppe 8192 8192 5 8192 0 8 0 Mar Mar Mar Mar Mar Mar Mar 13 6 13 13 13 13 13 09:09 13:33 09:09 09:09 09:09 09:09 09:09 ./ ../ test.dat test.dir/ test.link test.symlink -> tes test.txt Groesse Zugriffszeit Name Die Rechte werden in drei Dreiergruppen (u, g und o, siehe Tabelle 2.1) in der Reihenfolge rwx angegeben, ein - an der entsprechenden Position bedeutet das Nichtvorhandensein der entsprechenden Berechtigung. Rechte werden geändert mittels chmod [argumente] datei wobei die Argumente für chmod entweder numerisch (die drei Dreiergruppen der Rechte als Bitdarstellung einer dreistelligen Oktalzahl interpretiert) oder symbolisch sind (Gruppe+/-Recht): # chmod [u|g|o][+|-][r,w,x] pfad chmod u-w datei chmod g+x dir/subdir chmod o-rwx datei # chmod XXX pfad , XXX=Oktalzahl chmod 644 datei # ergibt Rechte rw-r--r-(=110 100 100) # typisch fuer Dateien chmod 755 datei # ergibt Rechte rwxr-xr-x , (=111 101 101) 2.7. SHELL 39 # typisch fuer Directories # und Programme 2.7 Shell Die im Vorangehenden beschriebenen Kommandos haben schon alle die Shell, also das Kommandozeileninterface verwendet. Die Shell die Sie in der Regel heute vorfinden ist die sogenannte bash“ (=bour” ne again shell). Historisch sind drei Shelltypen auf UNIX Systemen entstanden: • sh: die Bourne Shell (die älteste), • ksh: die Korn Shell, • und die C Shell. csh. Die bash ist aus dem GNU Projekt entstanden und ist die komfortabelste. Sie unterstützt • autocompletion“, d.h. Befehls-, Datei- und Verzeichnisnamen ” müssen nicht ausgeschrieben werden. Sobald Sie die ersten Zeichen davon getippt haben, können Sie versuchen mit dem Tabulator TAB das Geschriebene automatisch vervollständigen zu lassen, sollte dies nicht möglich sein (Piepser!) zeigt nochmaliges TAB eine Auswahl der verbliebenen Möglichkeiten an. • Historyfunktion (Pfeil auf und ab) • ... und vieles mehr. Alle Shells sind programmierbar, und somit als Skriptsprachen einsetzbar. 40 KAPITEL 2. UNIX/LINUX GRUNDLAGEN Die Ein- und Ausgabeströme der Kommandos (siehe auch 2.5.1) können von der Shell über Pipes miteinander verbunden werden, also z.B. ls -l | less Die Shell führt einfache Musterersetzungen für Dateinamen durch ls datei.* cat *.txt ls datei-?.* Will man aber ein Muster als Argument an ein Programm, z.B. find, übergeben, müssen alle Spezialzeichen ({*?|\ usw.) die die Shell schon interpretieren würde mit \“ verstecken ( maskieren“). ” ” 2.7.1 Shellprogrammierung Anhand der bash werden nun die Grundlagen der Shellprogrammierung erläutert. Die verschiedenen Konstrukte sind jeweils entweder direkt auf der Kommandozeile einsetzbar oder in Form eines Shellskripts anwendbar. Shellskripte sind ausführbare Dateien (siehe 2.6.5) deren erste Zeile die Form #!/bin/bash hat (im Falle eines bash Skripts, für andere Shells wird analog der volle Pfadname des jeweiligen Interpreters verwendet) und die auf den folgenden Zeilen Befehle und Konstrukte der jeweiligen Shell enthalten, so wie man sie auch direkt auf der Kommandozeile eingeben würde. 2.7. SHELL 2.7.1.1 41 Variablen Innerhalb der Shell können Werte (Zeichenketten) auf Variablen (sog. Umgebungsvariablen) geschrieben werden. Dies erfolgt mittels VARNAME=wert Variablennamen bestehen aus Buchstaben, Zahlen und Sonderzeichen (ausgenommen Zeichen die innerhalb der Shell eine Sonderbedeutung haben wie ;, =, Leerzeichen, Klammern, \, ...), üblicherweise aber nicht zwingend werden meist ausschließlich Großbuchstaben verwendet. Enthält der wert der Variablen solche Spezialzeichen so sind diese entsprechend zu quoten, bzw. innerhalb von doppelten Hochkommas zu setzen. Variablen gelten innerhalb der Shell von ihrer Definition weg. Sollen Sie auch an von der Shell aufgerufene Programme (also child Prozesse) weitergegeben werden müssen diese Variablen “exportiert” werden: export VARNAME In der bash darf man zusammengefasst auch export VARNAME=wert schreiben (In der Bourneshell muss man es in zwei Schritten getrennt schreiben!) Mittels env lässt sich eine Übersicht aller Variablen ausgeben. Auf den Inhalt einer einzelnen Variablen greift man mit dem $ Operator zu, für die einfache Anzeige von Text wird echo verwendet: 42 KAPITEL 2. UNIX/LINUX GRUNDLAGEN $ VAR2=$VARNAME $ echo $VAR2 wert $ echo 1234${VARNAME}5678 1234wert5678 Wird die Variable so in einen Ausgabestring eingebettet daß ihr Name nicht mehr erkennbar ist, muß dieser in geschweifte Klammern gesetzt werden (s.o.) 2.7.1.2 Variablensubstitution Mittels Variablensubstitution können regular expressions auf den Variablenwert angewandt werden. Hierzu werden die Schreibweisen ${VAR#pattern} ${VAR##pattern} ${VAR%pattern} ${VAR%%pattern} verwendet. Dabei wird der dem Muster pattern entsprechende Teil der Variablen bei • # von vorn • ## von vorn, ausgedehnt auf maximale Länge • % von hinten • %% von hinten, ausgedehnt auf maximale Länge herausgeschnitten und der verbleibende Wert der Variablen zurückgeliefert. Enthält VAR z.B. de Wert test.txt so liefert 2.7. SHELL 43 ${VAR%.txt} nur mehr “test” zurück. 2.7.1.3 Arithmetische Substitution Will man mit (ganzzahligen) Werten rechnen, die auf Variablen gespeichert sind muss die folgende Schreibweise verwendet werden: $((<Ausdruck>)) also z.B. $ a=1 $ b=2 $ echo $((a+b)) 3 2.7.1.4 Kommandosubstitution Bei der Kommandosubstitution wird die Standardausgabe eines Kommandos an die Shell als Text weitergegeben und kann dann z.B. auf einer Variablen gespeichert werden. Die Syntax lautet $(kommando) Mit TXTFILES=$(find . -name \*.txt) lassen sich somit z.B. die Namen aller *.txt Files die im aktuellen Verzeichnis oder irgendwo darunter stehen auf einer Variablen speichern. 44 2.7.1.5 KAPITEL 2. UNIX/LINUX GRUNDLAGEN Bedingte Ausführung von Befehlen if <befehl>; then <befehle>; fi # oder if <befehl> then <befehle> fi Optional können mehrere elseif und ein abschließender else Block eingefügt werden. <befehle> steht für einen oder mehrere Befehle (durch Zeilenumbruch oder ; getrennt). Als Bedingung wird der Rückgabewert eines beliebigen Befehls verwendet. Jedes Programm liefert bei erfolgreicher Ausführung den Wert 0 zurück, einen von 0 verschiedenen Wert (meist einen speziellen Fehlercode) andernfalls. Je nachdem ob im folgenden Beispiel die Datei test.dat vorhanden ist oder nicht wird ein unterschiedlicher Wert durch echo angezeigt: if ls -l test.dat; then echo "Datei vorhanden" else echo "Datei nicht vorhanden" fi Zusätzlich erscheint natürlich auch die Ausgabe des ls Kommandos. Um Bedingungen auch komfortabler formulieren zu können existiert das test Kommando. Mit diesem ließe sich der Test auf das Vorhandensein einer Datei eleganter über if test -f test.dat; then echo "Datei vorhanden" 2.7. SHELL 45 else echo "Datei nicht vorhanden" fi formulieren. Anstelle der Schreibweise test <bedingung> ist auch der Ausdruck [ <bedingung> ] gebräuchlich. In der Tat ist “[” ein hardlink auf test: $ ls -li /usr/bin/test 32673 -rwxr-xr-x 2 root $ ls -li /usr/bin/[ 32673 -rwxr-xr-x 2 root root 20092 Jul 26 2001 /usr/bi root 20092 Jul 26 2001 /usr/bi Wichtige Tests die mit test durchgeführt werden können sind • Vergleich von Zeichenketten if [ "$VAR" = "wert" ]; then echo T; else echo F; fi (Solche Tests sind natürlich nur dann sinnvoll wenn die zu vergleichenden Zeichenketten nicht schon vorher vollständig bekannt sind, also z.B. von Variablen stammen.) • Test ob Zeichenkette leer ist if [ -z "$VAR" ]; then echo T; else echo F; fi • Test auf Vorhandensein einer Datei if [ -e datei ]; then echo T; else echo F; fi • Test auf Lesbarkeit einer Datei if [ -r datei ]; then echo T; else echo F; fi 46 KAPITEL 2. UNIX/LINUX GRUNDLAGEN • Test auf Beschreibbarkeit einer Datei if [ -w datei ]; then echo T; else echo F; fi • Test auf Ausführbarkeit einer Datei if [ -x datei ]; then echo T; else echo F; fi Desweiteren können Tests mit -a (AND) und -o (OR) verknüpft und mit ! verneint werden, bei komplexeren Bedingungen empfiehlt sich Klammersetzung, die Klammern müssen aber maskiert werden (\( und \)). Es existieren noch einige weitere Abfragemöglichkeiten, Details siehe man test. 2.7.1.6 Schleifen Die for Schleife: for VAR in <liste>; do <befehle>; done # oder for VAR in <liste> do <befehle> done Hierbei ist <liste> eine Aufzählung von durch Leerzeichen getrennten Zeichenketten. Soll sich diese Aufzählung über mehrere Zeilen erstrecken sind alle außer der letzten Zeile mit \ abzuschließen. Die while Schleife: while <befehl>; do <befehle>; done # oder 2.7. SHELL 47 while <befehl> do <befehle> done Die until Schleife: until <befehl>; do <befehle>; done # oder until <befehl> do <befehle> done Bei while und until Schleife wird die Schleifenbedingung analog zu if als <befehl> dessen Rückgabewert ausgewertet wird angegeben. Bsp: $ until [ "$A" = "aaa" ]; do A=${A}a; echo $A; done a aa aaa 2.7.1.7 Dateien einlesen Mit read können Variablenwerte aus Dateien (per Default von der Standardeingabe) gelesen werden: read VAR1 VAR2 ... VARN Dabei wird die Eingabezeile an den Leerräumen (Leerzeichen, Tabulatoren) in einzelne Felder aufgeteilt und diese werden der Reihe 48 KAPITEL 2. UNIX/LINUX GRUNDLAGEN nach auf die Variablen geschrieben. Werden weniger Variablen als Felder angegeben enthält die letzte Variable den Rest der jeweiligen Zeile. z.B. weist $ read a b 1 2 3 echo $a echo $b der Variablen a den Wert 1 und der Variablen b den Wert “2 3” zu. Will man nun eine Datei auf diese Weise zeilenweise lesen, muss man das read in einer while Schleife solange ausführen bis der Datei keine Zeilen mehr entnommen werden können: cat test.dat | while read a b c d; do echo $a $b $c $d; done An diese Schleife wird die Datei über eine pipe als Standardeingabe weitergeleitet. 2.8 Umgang mit X und der Desktop Oberfläche Hierzu gibt es außer ein paar grundlegenden Hinweisen nicht viel zu sagen, das meiste sollte sich von selbst erklären. Für Umsteiger von Windowssystemen gibt es ein paar allgemeine Änderungen zu beachten: • ALLE drei Mausbuttons haben eine Bedeutung, allgemein sind dies – Links: Auswählen, Markieren (=Kopieren !!) 2.8. UMGANG MIT X UND DER DESKTOP OBERFLÄCHE 49 – Mitte: Einfügen (was vorher mit linker Maustaste markiert wurde) – Rechts: Ende eines Bereichs (relativ zum letzten links“” Klicks) markieren Je nach Anwendung kommen Sonderbedeutungen (Kontextmenü usw.) hinzu. • Beim Start von Anwendungen über das Klicken auf Icons, genügt EIN Mausklick, mit zwei Mausklicken wird das Programm doppelt gestartet! Je nach Einstellung im Filemanager wird ebenso beim ERSTEN Klick auf eine Datei oder Verzeichnis diese/dieses geöffnet! Die Desktopumgebung (KDE, Gnome oder andere) ergänzt die Eigenschaften von X u.a. um folgendes: • Panel und Startmenü, • bis zu 16 (standardmäßig 4) virtuelle Desktops, das bedeutet wenn Ihnen am Bildschirm der Platz ausgeht wechseln Sie einfach auf einen der anderen Desktops um dort parallel weitere Anwendungen laufen zu lassen (z.B. Desktop 1 fürs Texte editieren, Desktop 2 für Webbrowsing usw.) • Spezielle Menüpunkte machen viele persönliche Einstellungen verfügbar (Fenster- und Mausverhalten, Hintergrund, Bildschirmschoner, Sprache usw.) 50 KAPITEL 2. UNIX/LINUX GRUNDLAGEN 2.9 2.9.1 Übungen Kommandozeile / Dateioperationen Damit Sie nicht in Versuchung kommen, der anfangs vielleicht doch etwas ungewohnten Kommandozeile durch Herumklicksen“ in der ” grafischen Oberfläche entkommen zu wollen, können Sie die folgenden Aufgaben auch ausführen nachdem Sie sich auf der Textkonsole angemeldet haben ( Ctrl - ALT - F1 , zurück kommt man mit ALT - F7 ). 1. Untersuchen Sie mit ls welche Dateien und Verzeichnisse in Ihrem Homeverzeichnis vorhanden sind. Auch nach den folgenden Schritten sollten Sie immer wieder mit ls -l überprüfen, welche Dateien mit welchen Rechten entstanden sind. 2. Legen Sie ein Unterverzeichnis uebung-1 an. 3. Erzeugen Sie dort die Unterverzeichnisse subdir1, subdir2 und subdir3. 4. Legen Sie eine leere Datei leer.dat an (dazu wird der Befehl touch datei verwendet). 5. Kopieren Sie die zentrale Userdatei (/etc/passwd) ins Unterverzeichnis subdir2. Betrachten Sie diese mit einem Pager und versuchen Sie ihre eigene UID herauszufinden (Falls Sie die Linux Mint Live CD verwenden, ist Ihr Username mint). Falls diese nicht dort steht wird wahrscheinlich eine zentrale Userverwaltung per LDAP eingesetzt, lesen Sie Ihre eigenen Daten daraus mittels getent passwd IHRUSERNAME und hängen sie diese Zeile an die Kopie von passwd hinten an. 2.9. ÜBUNGEN 51 6. Legen Sie eine Kopie von passwd in subdir3 an. Ändern Sie die Zugriffsrechte der Kopie so ab, daß niemand die Datei ändern oder löschen kann. 7. Erzeugen Sie jetzt einen Symlink passwd-3 der auf Ihre erste Kopie von passwd zeigt. 8. Verschieben Sie nun das Verzeichnis subdir2 ins Verzeichnis subdir3. Versuchen Sie nun wiederum den Inhalt des Symlinks zu Betrachten. 9. Wechseln Sie zurück ins anfangs angelegte Unterverzeichnis uebung-1 und (a) finden mit find alle Dateien deren Namen mit pass beginnen, (b) extrahieren mit grep aus einer der passwd-Kopien die Zeile mit Ihrem Usernamen, (c) und packen mit tar das ganze Verzeichnis uebung-1 ein, probieren Sie beide Komprimiermethoden, welche ist besser? 2.9.2 Interaktion mit X 1. Starten Sie auf Desktop 1 ein Terminal, auf Desktop 2 den Filemanager und auf Desktop 3 den Firefox Webbrowser. Falls im Panel (die Leiste am unteren Bildschirmrand) keine Desktopauswahl möglich ist, fügen Sie den Desktopumschalter per MausRechtsklick im Panel hinzu. 2. Erhöhen Sie die Anzahl der verfügbaren Desktops (Klick mit rechter Maustaste im Desktopauswahlpanel) 52 KAPITEL 2. UNIX/LINUX GRUNDLAGEN 3. Gehen Sie auf Desktop 1 und verwenden Sie das dortige Terminalfenster um direkt von dort aus neue Terminalfenster (xterm, mate-terminal) zu starten (auf unterschiedliche Art und Weise, mal mit & am Ende mal ohne, was ist der Unterschied?). 4. Untersuchen Sie die Filesystemstruktur mit dem Filemanager (Menüeintrag “Orte” im Panel bei Verwendung von Gnome, “Persönlicher Ordner” im Startmenü bei MATE (Linux Mint)). 5. Öffnen Sie den Text Editor“ im Menü Zubehör (heißt pluma ” bei Linux Mint) sowie ein Terminalfenster. Führen Sie ein paar der Befehle aus Abschnitt 2.9.1 in diesem Terminalfenster aus und kopieren Sie dann mit der Maus die Resultate in den Texteditor. Speichern Sie dies in Ihrem Homeverzeichnis. Kapitel 3 Editoren Neben vielen weniger bedeutenden Texteditoren existieren unter UNIX zwei große Familien von Textprogrammen: • der vi und vi ähnliche Programme • der emacs und dessen Abkömmlinge. Darüber, welchen Editor, emacs oder vi, man denn nun verwenden solle, wird in der Gemeinschaft der UNIX-Anwender schon lange gestritten. Eigentlich muss man beide beherrschen, denn einer von beiden ist mit Sicherheit auf jedem UNIX System installiert. Welchem man den Vorzug gibt, bleibt Geschmackssache. Als grobe Faustregel kann vielleicht gelten: Der vi ist auf Textkonsolen angenehmer, der emacs unter grafischen Oberflächen wie X. 53 54 KAPITEL 3. EDITOREN 3.1 vi Der Name des vi leitet sich von visual“ ab, und deutet darauf hin, ” daß die Vorgänger vom vi (ex und ed) keine Vollbildeditoren waren und somit fast blind bedient werden mußten. Auf den Rechnern im Studentenbereich der Uni Klagenfurt wird der vim (vi improved), eine erweiterte Form des vi eingesetzt, dieser wird auch im folgenden beschrieben. Der vi befindet sich immer in einem der drei Modi • command mode (dies ist der Standard direkt nach dem Start) • input mode • ed mode Im command mode hat jede Taste irgendeine Befehlsbedeutung, bevor man einen Text schreiben will, muss man also zunächst mit der entsprechenden Taste (in diesem Fall z.B. i ) in den input mode wechseln. Will man dann das Geschriebene speichern, muss man wieder zurück in den command mode (mittels ESC oder Ctrl - C ). Von dort aus lassen sich im ed mode“ (erscheint nach Eingabe von ” : ) verschiedene Kommandos (die vom Vorgänger ed übernommen sind) ausführen, z.B. Speichern und Beenden mittels :wq“. Im ed ” mode springt der Eingabecursor in die Fußzeile vom vi. Da im Weiteren hauptsächlich der emacs eingesetzt wird, schließen wir hier ab und verweisen lediglich auf Tabelle 3.1 und 3.2 mit einer Übersicht der wichtigsten Kommandos. Der Aufruf des vi erfolgt mittels vi filename Wenn die Datei filename noch nicht existiert, wird sie dabei neu erzeugt. 3.1. VI Taste i a A x d dw dd D r cw y yw yy p P v V Ctl-V u ZZ . h, j, k, l /muster n N G g 55 Wirkung insert (an Cursorposition) append (wie insert nur ein Zeichen hinter dem Cursor) append am Ende der Zeile i, a, A wechseln in den input mode ! Zeichen löschen Bereich löschen (default ein Zeichen) Wort löschen Zeile löschen bis zum Ende der Zeile löschen Zeichen ersetzen (erwartet das neue Zeichen als Argument!) Wort ersetzen (wechselt dann in Input mode) Bereich kopieren (yank) (default ein Zeichen) Wort kopieren Zeile kopieren Kopiertes wieder einfügen (paste) wie p , aber vor der aktuellen Cursorposition markieren starten (Bereich mit Cursortasten erweitern), danach wirken einige Befehl, z.B. y, auf den markierten Bereich wie v, aber zeilenweise wie v, aber blockweise !!! undo Beenden und Speichern, äquivalent zu :wq im ed mode letzte Aktion wiederholen, manchmal sehr nützlich! entsprechen den Pfeiltasten ← , ↑ , ↓ , → nützlich für Tastaturen, bei denen die Pfeile nicht funktionieren. Mittelfinger auf j“ legen! ” vorwärts nach muster suchen nächstes Auftreten von muster suchen voriges Auftreten von muster suchen in erste Zeile springen in letzte Zeile springen Tabelle 3.1: vi command mode 56 KAPITEL 3. EDITOREN Kommando :s/alt/neu/g :von,bis s/alt/neu/g :1,$ s/alt/neu/g :d :von,bis d :w :w name :q :wq :q! :wq! :h :u :redo Wirkung substitute, wie bei sed, für aktuelle Zeile für Bereich für gesamte Datei ($=letzte Zeile, .=aktuelle Zeile) Zeile loeschen Bereich loeschen (z.B. :.,$ d“ = ” von hier bis Ende loeschen) Speichern Speichern unter Ende Speichern und Beenden Beenden ohne Speichern trotz Änderung Beenden mit Speichern trotz Schreibschutz“ ” Hilfe undo redo (undo rückgängig machen) Tabelle 3.2: vi ed mode Kommandos 3.2. EMACS 3.2 57 emacs Der Emacs ist das erste Programm, das im Rahmen des GNU Projekts entstanden ist, der Autor ist Richard Stallman. Der Emacs ist zum größten Teil in LISP geschrieben. In emacs-LISP wurden mittlerweile viele Erweiterungen geschrieben, so daß der Emacs mittlerweile eine komplette Programmierumgebung für alle möglichen Programmiersprachen darstellt. Man kann mit ihm auch seine Mail lesen, Web-Browsen usw. 3.2.1 buffers, windows, frames Beim Emacs gibt es keine Unterscheidung zwischen input und command mode, Kommandos bestehen in der Regel aus Ctrl und ALT Sequenzen (die bis zu drei Zeichen lang sein können, d.h. Kommandos wie Ctrl - c Ctrl - f Ctrl - d sind keine Seltenheit). Über die Tastenkombination ALT - x (oder ESC x wenn kein ALT vorhanden ist) gelangt man in die Fußzeile des emacs, den sog. mi” nibuffer“. Dort lassen sich direkt emacs Befehle (also LISP Funktionen) aufrufen, dies werden wir einige Male benötigen. Manche emacs Kommandos erwarten die Eingabe von zusätzlichen Parametern, dies geschieht ebenfalls über den minibuffer in der Fußzeile. In den Emacs Menüs stehen die Tastenkombinationen bei den meisten Kommandos mit dabei, dort wird die ALT -Taste meist als M bezeichnet (steht für META key). Der Emacs verwaltet mehrere Eingabefenster, sog. buffer“. Diese ” können geöffnete Dateien, den Ein- und Ausgabebereich verschiedener Programme oder temporären Inhalt ( scratch buffer“) enthalten. ” Später werden in solchen buffern Programme wie R und octave laufen. Der Fensterbereich des Emacs kann horizontal und vertikal geteilt 58 KAPITEL 3. EDITOREN werden. In jedem dieser window“ s lassen sich beliebige buffer dar” stellen, das Umschalten erfolgt über das Buffer“ Menü ( Switch to ” ” Buffer“). Dieses Menü ermöglicht weiterhin über Switch to Buf” fer, other Frame“ das Öffnen neuer Fensterinstanzen ( frames“) des ” Emacs. Diese stellen keinen zweiten parallel laufenden Editor, sondern nur einen zusätzlichen View“ auf den ursprünglich gestarteten ” Emacs dar. 3.2.2 Kommandos Eines der wichtigeren Kommandos ist Ctrl - g Damit lassen sich fehlgeschlagene oder irrtümlicherweise begonnene Kommandos wieder abbrechen. Bricht man solche nicht vollständig ausgeführten Kommandos nicht ab, wird der minibuffer nicht frei um nächste Kommandos eingeben zu können. Folgende Besonderheiten sind zu beachten: • Bei allen Kommandos in Kombination mit Ctrl ist die Großund Kleinschreibung des dazu kombinierten Zeichens egal, ansonsten NICHT! • Kombinationen die in Tabelle 3.3 mit -“ geschrieben sind be” deuten gleichzeitig drücken, ansonsten hintereinander“ ” ” Die meisten der Kommandos aus Tabelle 3.3 sind natürlich auch einfacher über die Menüs zu erreichen, die Kenntnis einiger weniger (Zeilenanfang, Zeilenende, Ausschneiden, Einfügen) kann allerdings die Eingabe wesentlich beschleunigen. Der Aufruf des Emacs erfolgt mittels emacs filename & 3.2. EMACS Ctrl - X Ctrl - X Ctrl - X Ctrl - X Ctrl - K Ctrl - Y Ctrl - R Ctrl - S Alt - % 59 Ctrl Ctrl Ctrl Ctrl Ctrl - Space Speichern Beenden File öffnen File speichern (write) unter ... bis Zeilenende löschen (kill) Zwischenspeicher wieder einfügen (yank) rückwärts inkrementell Suchen vorwärts inkrementell Suchen suchen und ersetzen ACHTUNG: Alt - % bedeutet auf deutscher Tastatur eigentlich SHIFT - Alt - 5 mit regular expressions suchen und ersetzen ACHTUNG: dies ist eigentlich SHIFT - Ctrl - ALT - 5 (also 4 Finger !!) Marke setzen (Markieren beginnen) Ctrl Ctrl Ctrl Ctrl Ctrl Ctrl Ctrl Ctrl Ctrl Markierten Bereich löschen (wipe) Undo (unlimited!) save some files (alle geänderten Files speichern) ein Fenster Fenster teilen, vertikal Fenster teilen, horizontal neuen Frame öffnen in anderes (other) Fenster springen zu anderem Buffer wechseln Ctrl - ALT - % - W X X X X X X X S 1 2 3 52 o b - S C F W Tabelle 3.3: Ausgewählte Emacs Steuerkommandos 60 KAPITEL 3. EDITOREN falls man eine grafische Oberfläche verwendet. Es können auch mehrere Dateien als Argumente angegeben werden. Mit der Kommandozeilenoption -nw“ kann man den emacs vom grafischen X-modus auf ” den Terminalmodus (ähnlich dem vi) zwingen. Dann existieren allerdings keine Menüs und man ist tatsächlich auf die Ctrl -Sequenzen angewiesen. Diesmal darf der Emacs natürlich nicht im Hintergrund (also kein abschließendes &) gestartet werden: emacs -nw filename 3.3 Übungen Ein paar Fingerübungen mit vi und emacs: 1. Erzeugen Sie eine neue Datei vitest.txt mit dem vi und schreiben ein paar Zeilen Text dort hinein. Benennen Sie diese danach auf test-vi um, und führen ein paar Änderungen darin mit dem vi aus. 2. Öffnen Sie die Datei test-vi im emacs im Terminalmodus und speichern Sie diese als test-emacs wieder ab und fügen ein paar Änderungen ein. 3. Öffnen Sie nun test-emacs und test-vi im grafischen Modus mit dem Emacs. Teilen Sie das Fenster und stellen Sie beide Dateien gleichzeitig dar. 4. Erzeugen Sie einen neuen Frame mit der Datei test-vi. 5. Starten Sie innerhalb das Emacs eine Shell. Dies erfolgt mittels ALT - x shell ENTER . Führen Sie dort ein paar UNIX Kommandos aus (ls, ...), speichern Sie den gesamten Output als Datei shell.txt. 3.3. ÜBUNGEN 61 6. Beenden Sie den Emacs, speichern Sie dabei alle evt. noch nicht gesicherten Änderungen ab. 62 KAPITEL 3. EDITOREN Kapitel 4 LATEX 4.1 Grundlagen LATEX ist im Gegensatz zu den sonst gebräuchlichen Textverarbeitungsprogrammen ein Textsatzsystem, das nicht im WYSIWYG Modus ( what you see is what you get“) arbeitet. Die Texte (mit ” LATEX Kommandos vermischt) werden mit einem beliebigem Editor geschrieben und danach ins DVI Format (device independent) übersetzt. Das DVI File wird in der Regel weiter in PostScript Format umgewandelt. Das System besteht aus den Komponenten • TEX: das eigentliche Textsatzsystem, enthält low level“ Be” fehle, • LATEX: eine darauf aufbauende Makrosprache“, fügt u.a. Do” kumentstrukturen hinzu. 63 64 KAPITEL 4. LATEX 4.1.1 Überblick Der Arbeitsablauf teilt sich in die Schritte • .tex File editieren, • mittels latex das DVI File erzeugen, • PostScript Datei mit dvips anlegen. • PDF Datei mit dvipdf oder ps2pdf anlegen. • Besonderheit bei PDF: Es existiert auch ein gesonderter pdflatex Befehl, der ohne Umweg über DVI oder PostScript PDF Dateien erzeugt. Also z.B. vi test.tex latex test.tex xdvi test.dvi # oder: dvips test.dvi gv test.ps # oder ps2pdf test.ps xpdf test.pdf # bzw. pdflatex test.tex # oder alles im Emacs integriert emacs test.tex & # dann ueber Menuepunkte weiter. Meist müssen allerdings Fehlerkorrekturschritte eingefügt werden, so lange bis das gewünschte DVI File entstanden ist. 4.1. GRUNDLAGEN 65 Es existieren weitere Zusatzprogramme wie BibTEX oder Makeindex, mit denen Literaturdatenbanken, Schlagwortverzeichnis u.a.m. verwaltet werden können. Standardmäßig verwendet LATEX die Computer Modern“ Schrif” ten (cm), die neben anderen Schriften zum Umfang des TEX-Systems gehören. Diese Schriften tragen wesentlich zum unverwechselbaren Erscheinungsbild von LATEX-Dokumenten bei. Entwickelt wurde LATEX von Donald. E. Knuth im Jahr 1986. Mittlerweile ist die aktuelle Version von TEX 3.141592 (mit jeder Version wird eine Ziffer mehr von π angehängt), die von LATEX 2ε . LATEX ist von Anfang freie Software gewesen. Die Softwareverteilung erfolgt über die sogenannten CTAN1 Server, dort sind auch viele Zusatzpakete zu LATEX erhältlich. 4.1.2 Dokumentaufbau Ein einfachstes LATEX2.ε Dokument sieht so aus: \ documentclass [12 pt ]{ article } \ usepackage { a 4 , german , graphicx } \ usepackage [ utf 8]{ inputenc } \ begin { document } Text % Kommentar \ newline ... \ end { document } Der \documentclass Befehl zählt in eckigen Klammern gewisse Optionen (10pt, 12pt) auf und gibt den Dokumenttyp (hier article ) an. 1 Comprehensive TEX Archive Network, http://www.ctan.org 66 KAPITEL 4. LATEX Darauf folgt ein Kopfteil der für Einstellungen, das Laden von Zusatzpaketen, eigene Kommandodefinitionen usw. genutzt wird. Der eigentliche Text steht dann im darauffolgenden document-Block, gemeinsam mit Steuerbefehlen (Schlüsselworte die mit \ beginnen) und Kommentaren (alles nach %). Geschweifte Klammern { sind für Befehlsargumente und Gruppierungen reserviert, in eckigen Klammern [] werden bei manchen Befehlen optionale Argumente angegeben. Dokumentklassen unterscheiden sich im Seitenformat, der Seitenanordnung (ein- oder zweiseitig) und den verfügbaren Gliederungsebenen • \part, • \chapter, • \section, • \subsection, • \subsubsection, • \paragraph • und \subparagraph Zu deren Verfügbarkeit siehe Tabelle 4.1, für die Dokumentenklasse letter gelten weitere Besonderheiten2 . 4.1.3 Packages Zusatzpakete werden mittels \usepackage{paket1, paket2, ...} im Dokumentenkopf geladen. Es können auch mehrere \usepackage Aufrufe hintereinander stehen. Wichtige Pakete sind: 2 im Gegensatz zu article stehen Zusatzbefehle für Adresse, Betreff usw. zur Verfügung 4.1. GRUNDLAGEN article report book letter bis \subparagraph bis \subparagraph \part bis \subparagraph \part bis \subparagraph \section \chapter 67 einseitig einseitig zweiseitig einseitig Tabelle 4.1: Dokumentklassen isolatin1 inputenc a4 german babel epsfig graphicx rotating ... 4.1.4 für westeuropäische Sonderzeichen (u.a. ä,ö,ü,ß), alte Methode . . . . . . . . . . . . . . . . . . für beliebige Sonderzeichen (speziell UTF8) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A4 Format (sonst US Letter) . . . . . . . . deutsche Silbentrennung und deutsche Bezeichnungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . mehrsprachige Dokumente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (Kapitel statt Chapter usw.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . für eingebettete EPS Grafiken . . . . . . . . . . . . . für eingebettete Grafiken (EPS, GIF, PNG usw.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . für gedrehte Texte Einfacher Text Einfacher Text wird hintereinander eingegeben, LATEX entscheidet dann über Zeilenumbruch und Silbentrennung. Eine Leerzeile im LATEX-File erzeugt einen neuen Absatz. Der Modus der Silbentrennung wird mit dem german bz. ngerman Paket auf deutsche bzw. neue deutsche Rechtschreibung eingestellt. Dennoch muß man bei manchen zusammengesetzten Worten händisch die Trennfugen angeben, dies geschieht durch Einschieben von \− in das entsprechende Wort. Das Wechseln auf andere Schriftstile und -größen ist mit den in Tabelle 4.2 aufgeführten Befehlen möglich. 68 KAPITEL 4. LATEX \underline{Unterstrichen} Schreibmaschine Fettdruck Hervorhebung Kursiv Geneigt Kapitälchen Unterstrichen {\tiny Winzig} Winzig \texttt{Schreibmaschine} \textbf{Fettdruck} {\em Hervorhebung} \textit{Kursiv} \textsl{Geneigt} \textsc{Kapit”alchen} {\scriptsize Noch kleiner} Noch kleiner {\footnotesize Kleiner} Kleiner {\small Klein} Klein {\large Gro”s} Groß {\Large Gr”o”ser} {\LARGE Noch gr”o”ser} Größer Noch größer {\huge Riesig} Riesig Tabelle 4.2: Schriftarten 4.2. ENVIRONMENTS 4.1.5 69 Gliederung Die Untergliederung in Teile, Kapitel, Abschnitte usw. erfolgt mittels \part, \chapter, \section, \subsection, \subsubsection, \paragraph und als kleinster Unterteilungseinheit \subparagraph So wird z.B. dieser Abschnitt mit den Befehlen: \ subsection { Gliederung } \ label { sec : sections } eingeleitet. Die Nummerierung erfolgt automatisch. Will man später in Querverweisen auf einzelne Abschnitte verweisen können, sollte man von Anfang an symbolische Label für die Untergliederungspunkte vergeben, so wie in obigem Beispiel. Wie später gezeigt wird, erfolgt dies bei Verwendung der AUCTEX Funktionen (Siehe Abschnitt 4.4) im Emacs automatisch. (Dieser Verweis entstand übrigens mittels \ref{sec:auctex}) Das Inhaltsverzeichnis wird durch den Befehl \tableofcontents erzeugt. Die dabei angezeigte Schachtelungstiefe ist abhängig von der verwendeten Dokumentenklasse. 4.2 Environments Environments sind \begin – \end Blöcke, die in verschiedene Modi umschalten. Es gibt dabei vorgefertigte Environments, aber auch die Möglichkeit eigene zu definieren. 4.2.1 Aufzählungen Die enumerate und itemize Umgebung werden für nummerierte bzw. nicht nummerierte Listen eingesetzt: 70 KAPITEL 4. LATEX 1. erstens 2. zweitens \ begin { enumerate } \ item erstens \ item zweitens \ end { enumerate } Dasselbe ohne Nummerierung: • erstens • zweitens \ begin { itemize } \ item erstens \ item zweitens \ end { itemize } Diese Konstruktionen sind beliebig schachtelbar, je nach Schachtelungstiefe werden andere Nummerierungsarten (numerisch, alphabetisch, römisch) oder Itemsymbole (Kreis, Viereck) verwendet. 1. erstens • Teil A • Teil B 2. zweitens 4.2.2 \ begin { enumerate } \ item erstens \ begin { itemize } \ item Teil A \ item Teil B \ end { itemize } \ item zweitens \ end { enumerate } verbatim Umgebung Soll Text unverändert erscheinen so wie er eingegeben werden, so sind die Befehle \ lstinline bzw. die Umgebung verbatim zu verwenden. Dies ist z.B. nötig wenn man Kommandos irgendeiner Programmiersprache in den Text einbetten will und dabei LATEX-Sonderzeichen wie \ dargestellt werden müssen. 4.2.3 Eigene Umgebungen Eigene Umgebungen werden mit \newtheorem im Dokumentkopf erzeugt, diese werden dann durchnummeriert und in hervorgehobener Schrift gesetzt. Als Beispiel zwei selbst definierte Umgebungen für mathematische Sätze und Definitionen: 4.2. ENVIRONMENTS 71 % vor \ begin { do c um en t }: \ newtheorem { satz }{ Satz }[ section ] \ newtheorem { defi }{ Definition }[ section ] Definition 4.2.1 Ein Vektor ist ein Tupel ... Satz 4.2.1 Es sei ... % und spaeter nach \ begin { d o cu me n t }: \ begin { defi } Ein {\ em Vektor } ist ein Tupel ... \ end { defi } \ begin { satz } Es sei ... \ end { satz } Man beachte, daß innerhalb eines kursiv gesetzten Textes die \em Hervorhebungsfunktion den Text wieder geradestellt (\textit tut dies nicht). 4.2.4 Formeln Die weitreichenden Möglichkeiten die LATEX im Formelsatz bietet, sind einer der Gründe für die Verbreitung von LATEX im wissenschaftlich mathematischen Bereich. Die folgenden Abschnitte sollen eine Einführung dazu geben, sicherlich können dort nicht alle Tricks vermittelt werden. 4.2.4.1 Formeltypen Es gibt im wesentlichen zwei Typen von Formeln, solche die innerhalb der Zeile stehen und abgesetzte Formeln. Je nach Nummerierungsmodus ergeben sich weitere Untertypen: • einfache inline-Formeln werden mit $ geklammert: $a=1$ liefert a = 1, dies ist äquivalent zum math Environment a=1 \ begin { math } a =1 \ end { math } 72 KAPITEL 4. LATEX • abgesetzte Formeln in \[ – \] Klammerung : \[ a =1 a=1 \] Dies ist wiederum äquivalent zum displaymath Environment \ begin { displaymath } a =1 a=1 \ end { displaymath } Eine andere Schreibweise dafür ist das Setzen der Formel zwischen doppelte Dollarzeichen: a=1 $$ a =1 $$ • numerierte abgesetzte Formeln: equation Environment: a=1 (4.1) \ begin { equation } a = 1 \ end { equation } • Mehrere nummerierte abgesetzte Formeln können mit vertikaler Ausrichtung am Relationszeichen zusammengefasst werden, dazu dient das eqnarray Environment (als Spaltentrenner fungiert &, neue Zeilen werden mit \\ erzeugt): a = 1 (4.2) b = 2 (4.3) \ begin { eqnarray } a & = & 1 \ label { eq : formel 1}\\ b & = & 2 \\ c & = & 3 \ nonumber \ end { eqnarray } c = 3 Die Nummerierung ist pro Zeile unterdrückbar (\nonumber) bzw. durch Setzen von Labels (\label) später referenzierbar. • Sollen die abgesetzen Formeln zwar am Relationszeichen ausgerichtet, aber überhaupt nicht numeriert werden, verwndet man das eqnarray* Environment, das ansonsten äquivalent zu eqnarray ist: 4.2. ENVIRONMENTS = 1 b = 2 \ begin { eqnarray *} a & = & 1 \\ b & = & 2 \\ c & = & 3 c = 3 \ end { eqnarray *} a 4.2.4.2 73 Formelelemente In Formeln werden andere Schriften verwendet: a, b, c im Gegensatz zu a,b,c. Folgende elementaren Bausteine benötigt man am häufigsten: • Subskript: $a {1}$, $A {ij}$ liefern a1 und Aij Achtung: $A ij$ liefert Ai j, d.h. Subskripte und Superskripte aus mehr als einem Zeichen müssen geklammert werden. Mit geeigneten Emacs Voreinstellungen passiert dies automatisch. • Superskript: $aˆ{2}$, $eˆ{a+b}$ liefern a2 und ea+b a • Brüche: $\frac{a}{b+c}$ liefert b+c . Im abgesetzten displaymath Modus werden Brüche etwas größer dargestellt: a b+c \[ \ frac { a }{ b + c } \] Eine andere Darstelung für Brüche ist mit ${a \over b+c}$ möga lich, dies ergibt ebenfalls b+c . Achtung: Nicht mit dem Binomialkoeeffizienten verwechseln dieser wäre ${a \choose b+c}$, a Ergebnis: b+c . R 10 • Integrale: $\int {x=1}ˆ{10} f(x) dx$ ergibt x=1 f (x)dx, auch hier ist die abgesetzte Variante etwas größer: Z 10 \[ \ int _{ x =1}^{10} f ( x ) dx f (x)dx x=1 \] 74 KAPITEL 4. LATEX Mit einem zusätzlichem \limits Befehl können die Sub- und Superskripte direkt unter den mathematischen Operator platziert werden. Z10 f (x)dx (4.4) x=1 \ begin { equation } \ label { eq : integral } \ int \ limits _{ x =1}^{10} f ( x ) dx \ end { equation } • Summen (\sum) und Produkte (\prod) sind analog zum Integral zu erstellen, z.B. inline“ $\sum {i=1}ˆ{10}a {i}$ bzw. ” 10 P10 Q $\prod\limits {j=1}ˆ{10}w {j}$ ergeben a oder wj . i i=1 j=1 In abgesetzten Formeln erscheint dies ebenfalls größer: 10 X ai = 1 (4.5) i=1 10 Y wj \ begin { eqnarray } \ label { eq : sumprod } \ sum _{ i =1}^{10} a _{ i } &=& 1 \\ = 0 (4.6) \ prod \ limits _{ j =1}^{10} w _{ j } & \ end { eqnarray } j=1 Hier ist \limits überflüssig. • Arrays und Matrizen werden in Analogie zu Tabellen erstellt, siehe Abschnitt 4.2.5. Dazu dient das array Environment: \ begin { eqnarray } \ label { eq : matrix } f ( x ) & = & \ left \{ \ begin { array }{ ll } 1 & \ mbox { f \"{ u } r $x >0$} \\ 0 & \ mbox { sonst } \ end { array } \ right . \\ A = \ left ( \ begin { array }{ cc } 1 & 2 \\ 2 & 4 4.2. ENVIRONMENTS 75 \ end { array } \ right ) \ end { eqnarray } Klammern in einer sich an den Inhalt anpassender Größe erhält man mit einer \left – \right Kombination. D.h. Matrizen entstehen aus einem array das in runde \left – \right Klammern eingeschlossen wird. Will man eine der beiden Klammern weglassen so ist sie durch einen . zu ersetzen. f (x) = A = 1 0 1 2 für x > 0 sonst 2 4 (4.7) (4.8) Wie man an diesem Beispiel sieht, muß Text innerhalb von Formeln in eine \mbox{} eingeschlossen werden. Weiterhin muß man einige wichtige Formelsymbole kennen, eine Auswahl ist in Tabelle 4.3 aufgeführt. 4.2.5 Tabellen Einfache Tabellen werden direkt in den Text eingefügt, hierzu dient das tabular Environment \ begin { tabular }[ h ]{ l | l | c | r } 4 Spalten : & linksb \"{ u } ndig & zentriert & rechtsb \"{ u } ndig \\ \ hline n " achste Zeile & ... \ end { tabular } 76 KAPITEL 4. LATEX $\ne$ $\le$ $\ge$ $\rightarrow$ $\Rightarrow$ $\leftarrow$ $\Leftarrow$ $\Leftrightarrow$ $\cap$ $\cup$ $\bigcap$ $\bigcup$ $\subset$ $\subseteq$ $\in$ $\varepsilon$ $\pi$ $\alpha \ldots$ $\exp(2)$ $\hat{a}$ $\vec{v}$ $\infty$ $\emptyset$ 6= ≤ ≥ → ⇒ ← ⇐ ⇔ ∩ ∪ T S ⊂ ⊆ ∈ ε π α ... exp(2) â ~v ∞ ∅ Tabelle 4.3: Wichtige Formelsymbole 4.2. ENVIRONMENTS 77 linksbündig zentriert rechtsbündig 4 Spalten: nächste Zeile ... Die Argumente beschreiben die Spalten (linksbündig, zentriert oder rechtsbündig) , | kennzeichnet Spaltentrennlinien. Mittels \hline innerhalb der Tabelle kann man Zeilentrennlinien einfügen. Wie schon beim eqnarray Environment steht & als Spaltentrenner und \\ als Zeilentrenner. Abgesetzte Tabellen erzeugt das table Environment, es enhält ein tabular Environment wie oben aber zusätzlich mit Tabellentitel und Nummerierung. Solche Tabellen werden auch ins Tabellenverzeichnis aufgenommen, das mit \listoftables erzeugt werden kann. \ begin { table }[ htbp ] \ begin { center } \ begin { tabular }[ h ]{| l || l | r |} \ hline & Spalte 1 & Spalte 2 \\ \ hline \ hline Zeile 1 & 1 & 2 \\ Zeile 2 & & 3 \\ \ hline \ end { tabular } \ caption { Beispiel f " ur eine abgesetzte Tabelle } \ label { tab : tabbsp } \ end { center } \ end { table } Spalte 1 Zeile 1 Zeile 2 1 Spalte 2 2 3 Tabelle 4.4: Beispiel für eine abgesetzte Tabelle 78 4.2.6 KAPITEL 4. LATEX Bilder Für Abbildungen steht das figure Environment zur Verfügung, analog zu table versieht es die Abbildung mit Bildunterschrift und Nummerierung und bereitet die Aufnahme ins Abbildungsverzeichnis (\listoffigures) vor. \begin{figure}[htbp] \begin{center} \includegraphics*[scale=1]{bild1} % oder alternativ: % \epsfig{file=bild1.eps,scale=1} \caption{Beispiel f"ur \cmd{figure}} \label{fig:ertesbild} \end{center} \end{figure} Für den jeweiligen Bilddateityp benötigt man File-Importfunktion, für EPS Grafiken bietet sich \epsfig an, \includegraphics aus dem graphicx Paket kann auch mit anderen Formaten wie GIF und JPEG umgehen. Das Bild bild1.eps wurde übrigens mit tgif erstellt: $ tgif bild1 & $ # ... weiter laut tgif Menues, $ # zum Schluss "Print", erzeugt bild1.eps Tgif ist ein Vektorgrafikprogramm das recht intuitiv bedienbar ist. Tgif Dateien werden mit der Endung .obj erzeugt, im LATEXDokument verwendet man die EPS Ausgabe dieser Datei, die innerhalb von Tgif durch den Menüeintrag Print“ erzeugt wird (und stan” 4.3. QUERVERWEISE 79 Abbildung 4.1: Beispiel für figure dardmäßig in eine EPS Datei gleichen Namens abgelegt wird). Weitere Vektorgrafikprogramme unter Linux sind u.a. Xfig und QCad, zur Bearbeitung von Pixelgrafiken ist GIMP geeignet. 4.3 Querverweise Es gibt mehrere Arten von Querverweisen innerhalb eines Dokuments. All diesen Querverweisen ist gemeinsam, daß sie meist eine erhöhte Anzahl von latex Durchläufen benötigen bis die Seitenzahlen, Nummern usw. den richtigen Wert haben. Dies liegt daran, daß gewisse Querverweise erst dann bestimmt werden können, wenn schon alle Seiten des Dokuments verarbeitet sind. Dies passiert insbesondere dann wenn man vom Anfang des Dokuments auf dessen Ende verweist, die Seitenzahlen der letzten Kapitel stehen bei Verarbeitung der ersten Teile noch nicht fest. LATEX speichert diese Informationen in temporären Hilfsdateien so daß bei nochmaligem 80 KAPITEL 4. LATEX Durchlauf diese Informationen dann bereitstehen. Wenn man das hyperref Paket verwendet \ usepackage { hyperref } werden all diese Querverweise auch beim Exportieren in HTML oder PDF Format als Hyperlinks angelegt. Zusätzlich bietet hyperref auch das Anlegen vom Links auf externe URLs an. Dazu wird der Befehl \ href { URL }{ Text } bzw. wenn einfach nur der URL angegeben werden soll \ url { URL } verwendet, der URL muss dabei den üblichen Anforderungen an http://, ftp:// oder mailto: URLs entsprechen, der Text des zweiten Arguments ist dann der aktive Teil des Links im Text des Dokuments. In älteren LATEX Versionen musste man für die Verwendung von \url das Paket url verwenden. Dies sorgt dafür, daß der URL in Schreibmaschinenschrift gesetzt wird, daß man LATEX Sonderzeichen im URL verwenden kann und daß der URL am Zeilenende vernünftig abgetrennt werden kann. Als Beispiel dient hier der Verweis auf die Homepage der deutschen LATEX Anwendervereinigung DANTE: http://www.dante.de. \ href { http :// www . dante . de }{\ url { http :// www . dante . de }} In aktuellen Versionen ist \url im Paket hyperref enhalten, wie oben demonstriert. 4.3. QUERVERWEISE 4.3.1 81 Fußnoten Fußnoten sind Verweise auf kleingedruckte Erläuterungen zum Text die am unteren Rand der Seite oder der unmittelbar folgenden Seite stehen3 . Ein Beispiel: ... folgenden Seite stehen \ footnote { je nachdem wieviel Fu " snoten pro Seite auftauchen , werden diese je nach Platzangebot auf die folgenden Seiten verteilt }. Ein ... 4.3.2 Einfache Referenzen Alle mit \label{marke} markierten nummerierten Stellen (Abschnittsüberschriften, Formeln, Tabellen, Abbildungen, ...) sind mittels \ref{marke} referenzierbar. Die Markennamen sind frei wählbar und sollten inhaltlich begründet sein und nicht einer Nummerierung folgen. Es ist ja gerade der Sinn und Zweck dieser symbolischen Marken von einer späteren Umordnung und Erweiterung des Dokuments unabhängig zu sein. Hier wird z.B. auf die erste Formel der eqnarray Umgebung in Abschnitt 4.2.4 verwiesen: siehe Formel (4.2). Quelle dazu: Hier wird z . B . auf die erste Formel der \ lstinline . eqnarray . Umgebung in Abschnitt \ ref { sec : formeln } verwiesen : siehe Formel (\ ref { eq : formel 1}). und die Abschnittsüberschrift dazu lautete \ subsubsection { Formeltypen } \ label { sec : formeln } Spezielle Referenzen sind für Literaturangaben und Zitate vorgesehen, siehe Abschnitt 4.3.3. 3 je nachdem wieviel Fußnoten pro Seite auftauchen, werden diese abhängig vom Platzangebot auf die folgenden Seiten verteilt 82 4.3.3 KAPITEL 4. LATEX Literaturverzeichnis Literaturverweise werden mit dem zum \ref Befehl analogen \cite Befehl erstellt. Die Verweise zeigen in diesem Fall auf symbolische Label die aus einer Literaturdatenbank stammen. Diese werden in .bib Dateien abgelegt und müssen mit dem BibTEX Programm bearbeitet werden. Dadurch erweitert sich der Editierzyklus nun auf folgenden Ablauf: latex, bibtex, latex, latex, dvips, . . . . Der latex Schritt ist mehrmals auszuführen da in jedem Durchlauf Seitenumbrüche erfolgen können (dadurch daß plötzlich die Literaturverweise im Text auftauchen) und somit die Nummerierung z.B. im Inhaltsverzeichnis sich verschiebt. Referenzen werden mittels \cite{marke} Befehlen eingefügt, z.B. Kofler [2000] (erzeugt durch \cite{ kofler :lnx:2000}) Nicht explizit referenzierte Werke werden mit \nocite aufgenommen (z.B. mittels \nocite{kopka:94:vol1} ) Das Literaturverzeichnis selbst wird durch \ b i b l i o g r a p h y s t y l e { plain } \ bibliography { lit } erzeugt, hier mit der Datei lit.bib: @Book{kofler:lnx:2000, author = {Michael Kofler}, ALTeditor = {}, title = {Linux, Installation, Konfiguration, Anwendung}, publisher = {Addison Wesley}, year = {2000}, OPTkey = {}, OPTvolume = {}, OPTnumber = {}, OPTseries = {}, 4.3. QUERVERWEISE address = {Bonn, Paris, Reading - Mass.}, OPTedition = {}, OPTmonth = {}, OPTnote = {}, OPTannote = {} } @Book{ronneburg:gnulnx:2001, author = {Frank Ronneburg}, ALTeditor = {}, title = {Debian GNU/Linux-Anwenderhandbuch}, publisher = {Addison Wesley}, year = {2001}, OPTkey = {}, OPTvolume = {}, OPTnumber = {}, OPTseries = {}, address = {M\"{u}nchen, Boston, San Francisco}, OPTedition = {}, OPTmonth = {}, OPTnote = {}, OPTannote = {} } @Book{herold:lnx:1999, author = {Helmut Herold}, ALTeditor = {}, title = {Linux-Unix-Grundlagen}, publisher = {Addison Wesley}, year = {1999}, OPTkey = {}, 83 84 KAPITEL 4. LATEX OPTvolume = {}, OPTnumber = {}, OPTseries = {}, OPTaddress = {M\"{u}nchen, Reading Massachusetts, Menlo Park C OPTedition = {}, OPTmonth = {}, OPTnote = {}, OPTannote = {} } @Book{kofler:maple:1994, author = {Michael Kofler}, ALTeditor = {}, title = {Maple V Release 2, Einf\"{u}hrung und Leitfaden f\"{u}r den Praktiker}, publisher = {Addison Wesley}, year = {1994}, OPTkey = {}, OPTvolume = {}, OPTnumber = {}, OPTseries = {}, address = {Bonn, Paris, Reading - Mass.}, OPTedition = {}, OPTmonth = {}, OPTnote = {}, OPTannote = {} } @Book{kofler:math:1992, author = {Michael Kofler}, ALTeditor = {}, 4.3. QUERVERWEISE 85 title = {Mathematica, Einf\"{u}hrung und Leitfaden f\"{u}r den Praktiker}, publisher = {Addison Wesley}, year = {1992}, OPTkey = {}, OPTvolume = {}, OPTnumber = {}, OPTseries = {}, address = {Bonn, Paris, Reading - Mass.}, OPTedition = {}, OPTmonth = {}, OPTnote = {}, OPTannote = {} } @Book{wolfram:math:1996, author = {Stephen Wolfram}, ALTeditor = {}, title = {Mathematica, Ein System f\"{u}r Mathematik auf dem Compute publisher = {Addison Wesley}, year = {1996}, OPTkey = {}, OPTvolume = {}, OPTnumber = {}, OPTseries = {}, address = {Bonn, Paris, Reading - Mass.}, OPTedition = {}, OPTmonth = {}, OPTnote = {}, OPTannote = {} } 86 KAPITEL 4. LATEX @Book{char:etal:1993, NOTUSDEDauthor = {Bruce W. Char, Keith O. Geddes, Gaston H. Gon author = {Bruce W. Char and Keith O. Geddes and et.al.}, ALTeditor = {}, title = {First Leaves: A Tutorial Introduction to Maple V}, publisher = {Springer-Verlag}, year = {1993}, OPTkey = {}, OPTvolume = {}, OPTnumber = {}, OPTseries = {}, address = {New York, Berlin, Heidelberg}, OPTedition = {}, OPTmonth = {}, OPTnote = {}, OPTannote = {} } @Book{kopka:94:vol1, author = {Helmut Kopka}, ALTeditor = {}, title = {LaTeX Einf\"{u}hrung}, publisher = {Addison Wesley}, year = {1994}, OPTkey = {}, volume = {1}, OPTnumber = {}, OPTseries = {}, address = {Bonn, Paris, Reading - Mass.}, OPTedition = {}, 4.3. QUERVERWEISE 87 OPTmonth = {}, OPTnote = {}, OPTannote = {} } @Book{tukey70, author = title = publisher = volume = note = year = } {Tukey, J. W.}, {Exploratory Data Analysis}, {Addison-Wesley}, 1, {(Limited Preliminary Edition)}, {1970} @BOOK{stoy93, author = {D. Stoyan}, title = {Stochastik f\"{u}r Ingenieure und Naturwissenschaftler}, year = 1993, publisher = {Akademie-Verlag}, address = {Berlin} } @Book{lug99, author = {E. Anderson and Z. Bai and C. Bischof and S. Blackford and J. Demmel and J. Dongarra and J. Du Croz and A. Greenbaum and 88 KAPITEL 4. LATEX S. Hammarling and A. McKenney and D. Sorensen}, ALTeditor = {}, title = {{LAPACK} Users' Guide Third Edition}, publisher = {SIAM}, year = {1999}, OPTkey = {}, OPTvolume = {}, OPTnumber = {}, OPTseries = {}, address = {Philadelphia}, OPTedition = {}, OPTmonth = {}, note = {Online Version: \url{http://www.netlib.org/lapack/l OPTannote = {} } Für deutschsprachige Literaturverzeichnisse sind Zusatzpakete nötig, z.B. % vor \ begin { do c um en t } \ usepackage { bibgerm } % zum Schluss : \ b i b l i o g r a p h y s t y l e { gerabbrv } \ bibliography { lit } oder \ usepackage { natbib } \ b i b l i o g r a p h y s t y l e { plainnat } \ bibliography { lit } Andere Bibliographiestile sind gerplain, geralpha, ... 4.4. LATEX IM EMACS: AUCTEX 4.3.4 89 Stichwortverzeichnis Mit den Zusatzprogramm makeindex kann man Stichwortverzeichnisse erzeugen. Dies ist für kurze Artikel oder Seminararbeiten sicher nicht nötig, für größere Arbeiten oder Bücher aber durchaus angebracht. Folgendes ist dazu nötig: % vor begin { d o cu m en t } \ usepackage { makeidx } \ makeindex % im Text nach begin { d o cu me n t } Wort \ index { Wort } , Begriff { Begriff ! Erkl " arung } % ... Ausgabe des Index : \ a ddco nte ntsl ine { toc }{ chapter }{ Index } \ printindex Es ist also ein Zusatzpaket zu laden und zu initialisieren. Dann sind wichtige Begriffe mit \index Einträgen zu versehen, diese können einfach oder mehrstufig sein (getrennt mit !). In den latex Übersetzungsablauf ist nun zusätzlich makeindex datei einzuschalten. In diesem Abschnitt wurden zwei Indexeinträge mittels Mit den Zusatzprogramm \ cmd { makeindex } kann man S t i c h w o r t v e r z e i c h n i s s e \ index { S t i c h w o r t v e r z e i c h n i s } erzeugen \ index { Index ! erzeugen eines }. ... angelegt. 4.4 LATEX im Emacs: AUCTEX Im Emacs bzw. XEmacs steht ein Modus mit Spezialbefehlen für LATEX-Autoren zur Verfügung, der sogannnte AUCTEX Modus. Er 90 KAPITEL 4. LATEX sollte automatisch gestartet werden sobald man eine TEX-Datei öffnet. Zu erkennen ist er an den zusätzlichen Command“ und LaTeX“ ” ” Menüs. 4.4.1 Dateigliederung Oft ist eine Aufteilung in mehrere Teile (z.B. pro Kapitel, kap1.tex, kap2.tex) sinnvoll. Das Hauptdokument ( master“ File) enthält dann ” nur mehr den Dokumentenkopf und die \include{teil} Befehle zum Einlesen der einzelnen Teile: \ documentclass [12 pt ]{ article } \ usepackage { isolatin 1 , a 4 , german } \ begin { document } \ include { kap 1} \ include { kap 2} \ end { document } Das Masterdokument sollte einen Abschnitt % %% Local V a r i a b l e s : % %% mode : latex % %% TeX - master : t % %% End : enthalten, die Teile einen entsprechenden mit dem Namen des Masterfiles hinter TeX-master:, im folgenden Beispiel heißt die Hauptdatei mathsoft.tex. % %% Local V a r i a b l e s : % %% mode : latex % %% TeX - master : " m a th s of t " % %% End : 4.4. LATEX IM EMACS: AUCTEX 4.4.2 91 Command-Menü Das Command“ Menü stellt die einzelnen Schritte zur Erstellung ” der Ausgabe bereit, im allgemeinen sind die Schritte von oben nach unten abzuarbeiten. Für ein normales LATEX Dokument ergibt sich der Ablauf 1. LaTeX“ ” 2. View“ (Enter) ” 3. File“ (Enter) ” Der Check“ Menüpunkt bietet einen LATEX-Syntaxcheck an, der ” bei Fehlersuche durchaus hilfreich ist (Man kann dies auch auf der Kommandozeile durch Aufrufen von lacheck datei.tex ausführen). BibTEX und Makeindex sind auch Teil des Command“ Menüs. ” Die Kommandos sind auch über Tastaturkürzel erreichbar. Mittels Ctrl - C Ctrl - C wird der jeweils nächste Arbeitsschritt in der Emacsfußzeile vorgeschlagen und bei Bestätigung mit Enter ausgeführt. 4.4.3 LaTeX-Menü Das LaTeX“ Menü bietet Möglichkeiten zum Einfügen von Ab” schnitten und Environments mit automatischer Labelgenerierung an. Die Parameter der einzelnen Befehle (Abschnittsüberschriften, Tabellenformat, symbolische Label) werden in der Emacsfußzeile abgefragt. Diese Funktion ist über das Tastenkürzel Ctrl - C Ctrl - E erreichbar. Ein weiterer wichtiger Punkt dieses Menüs ist Next Error“. Da” mit kann man schrittweise die fehlerhaften Stellen in seinem LATEXDokument anspringen. Auch das Wechseln von Schriftart und -stil ist 92 KAPITEL 4. LATEX über Change/Insert Font“ möglich. (Tastenkürzel: Ctrl - C Ctrl ” F Ctrl - X , wobei für X die Tasten • E für Hervorhebung (emphasize), • B für Fett (bold) • T für Schreibmaschine (typewriter) • C für Kapitälchen (small caps) • F für Sans Serif • I für Kursiv (italics) • S für slanted • R für Roman • A für Calligraphic stehen. 4.4.4 Preview-Menü Über das Preview“ Menü kann man eine Vorschau von ” • Formeln (inline oder abgesetzt), • Überschriften, • Abbildungen und • Tabellen 4.4. LATEX IM EMACS: AUCTEX 93 in den Quelltext im XEmacs einblenden. Man kann dies für das ganze Dokument, den aktuellen Emacs Buffer oder eine markierte Region ausführen. Will man dann die grafisch dargestellten Bereiche weitereditieren, muss der Vorschaumodus wieder entfernt werden (mittels mittlerer oder rechter Maustaste oder über entsprechende Menüpunkte). Man beachte dabei, daß die Nummerierung der Überschriften und Formeln nicht korrekt sein muß, da nicht notwendigerweise das gesamte Dokument in die Vorschau einbezogen wird. Bei mehrteiligen Dokumenten kann es notwending sein, den Preview Mode vom Hauptdokument aus zu starten. 4.4.5 Math-Menü Das Math“ Menü bietet Zugriff auf jede Menge mathematischer ” Symbole. Allerdings sehen Sie nur die LATEX Kommandos zu den Symbolen und nicht deren Gestalt. Trotzdem ist dies vor allem zu Beginn eine gute Merkhilfe zum Auffinden des passenden Symbols. 4.4.6 Ref TEX Der reftex Modus ermöglicht das bequeme Setzen und Referenzieren von Labels und Zitierstellen. Er • scannt selbständig nach vorhandenen Labels, • durchsucht die Bibliographiedatenbank • und erzeugt eine Inhaltsübersicht. Beim Setzen von Referenzen kann man dann auf eine Liste der schon vorhandenen Labels sortiert nach Abschnittslabels, Tabellenlabels, Abbildungslabels und Gleichungslabels zugreifen. 94 4.4.7 KAPITEL 4. LATEX BibTEX Auch zum Editieren der Bibliographiedatenbankfiles existiert ein passender Emacs Modus. .bib Dateien müssen sich an ein vorgegebenes Format halten. Per Menü kann man Einträge verschiedener Typen (Buch, Artikel, usw) erzeugen und verändern. Nicht zwingend nötige Felder sind mit einem ALT oder OPT Prefix versehen, den man per Hand entfernen kann, wenn man dieses Feld belegen will. Ein Beispiel für einen Bucheintrag der im Emacs erstellt wurde ist @Book { kopka :94: vol 1 , author = { Helmut Kopka } , ALTeditor = {} , title = { LaTeX Einf \"{ u } hrung } , publisher = { Addison Wesley } , year = {1994} , OPTkey = {} , volume = {1} , OPTnumber = {} , OPTseries = {} , address = { Bonn , Paris , Reading - Mass .} , OPTedition = {} , OPTmonth = {} , OPTnote = {} , OPTannote = {} } Hier wurden die optionalen Felder volume und address aktivert. Das erste Feld vor author ist das selbstgewählte symbolische Label, auf das später mit \cite zugegriffen wird. 4.4.8 Rechtschreibprüfung Über das Spell“ Icon in der Iconleiste (oder den Spell-check“ Ein” ” trag im Cmds“ bzw. Edit“ Menü) ist eine Rechtschreibprüfung ” ” 4.5. PRÄSENTATIONEN 95 möglich. Standardmäßig wird ein englisches Wörterbuch verwendet, will man das nicht, muß man mit Ctrl - G abbrechen und über Menü das Deutsch8“ Wörterbuch wählen. Bei fehlerhaften Worten ” bietet ispell eine Auswahl per Nummerntastatur an. Mit Leertaste kann man Fehler übergehen, mit i zusätzliche Wörter in ein persönliches Wörterbuch aufnehmen. Anstatt des sequentiellen Abarbeitung des Texts durch den Spell” check“ Menübefehl lassen sich falschgeschriebene bzw. unbekannte Worte im flyspell-mode“ des Emacs farbig hervorgehoben und ” unterstrichen darstellen. Diesen Modus aktiviert man mittels Alt x flyspell-mode (bzw. nachträglich mit Alt -x flyspell-buffer). Danach kann man auf die ispell Funktionen (Ersetzen oder Aufnahme ins persönliche Wörterbuch) über ein Menü per mittlerer Maustaste zugreifen. 4.5 Präsentationen Hat man einmal seine Texte inklusive mehr oder weniger komplexer Formeln in LATEX geschrieben, will man dies natürlich auch zur Erstellung von Folien oder Bildschirmpräsentationen verwenden. Hierzu existieren mehrere Zusatzpakete, zwei davon werden kurz vorgestellt. Eine ganz alte Methode bot das slides Paket, man lädt es mittels \usepackage{slides} und plaziert dann Blöcke der Form \begin{slide}...\end{slide} und füllt diese aus. Das Ausgabeformat ist A4 hochkant, also eigentlich zum Ausdrucken auf Folien für Overheadprojektoren gedacht, 96 KAPITEL 4. LATEX heute also nicht mehr ganz so aktuell. 4.5.1 Beamer Das aktuelle Paket zum Erstellen von Bildschirmpräsentationen in LATEX ist beamer: \usepackage{beamer} Die Foliendefinition erfolgt mittels \begin{frame} \end{frame} Übersetzt werden muss ein solches Dokument mit pdflatex da die meisten Zusatzfunktionen sowieso nur im PDF Modus funktionieren. Pro frame sollte mit \frametitle eine kurze Überschrift gesetzt werden. Ansonsten ist zu beachten, dass die Schrift automatisch wesentlich größer eingestellt ist und nicht besonders viel Text auf eine Folie passen. Die Folien kann man mit normalen \section (\subsection usw.) Befehlen gliedern, dadurch wird das Inhaltsverzeichnis der Präsentation übersichtlicher. beamer Präsentationen können mit sogenannten themes im Aussehen und Verhalten variiert werden (Auswahl mit \usetheme{ThemeName}). In manchen Varianten werden die Abschnittsüberschriften im Folienkopf dann automaitsch mit angezeigt. Soll eine Folie eine verbatim Umgebung z.B. für Quellcode enthalten, ist zu beachten dass man den frame unbedingt mit \begin{frame}[fragile] beginnt. Man kann den Text auf den frames wie folgt in Blöcke mit optionaler Unterüberschrift teilen: 4.5. PRÄSENTATIONEN 97 \begin{block}{optionaler Titel} Blockinhalt \end{block} Je nach gewähltem theme werden diese Blöcke dann farbig vom Hintergrund abgesetzt. • offizielle Dokumentation: www.tug.org/teTeX/tetex-texmfdist/doc/latex/beamer/beameruserguide pdf • http://math.asu.edu/support/doc/latex/slides.html • eines von vielen Tutorials: http://www2.informatik.hu-berlin.de/~mischulz/beamer. html • Beispiele: http://www.tug.org/teTeX/tetex-texmfdist/doc/ latex/beamer/examples/ 4.5.2 Prosper Prosper ist eine etwas ältere LATEX-Lösung mit der eine Bildschirmpräsentation in PDF-Format und Folienausdrucke in PostScript erstellt werden können. Das Grundgerüst eines Prosper Dokuments sieht folgendermaßen aus: \ documentclass [ pdf , colorBG , slideColor ]{ prosper } \ begin { document } \ begin { slide }{ Folientitel } Folieninhalt \ end { slide } % usw . \ end { document } 98 KAPITEL 4. LATEX Prosper verwendet viele Postscript Makros, deshalb kann der Inhalt nicht als DVI File dargestellt werden, erst im PS oder PDF File ist er zu sehen. Der Compilierablauf ist folgender $ latex folien.tex $ dvips -G0 folien.dvi $ ps2pdf folien.ps Die itemize Umgebung wird dabei grafisch etwas verändert, ja nach Vorlage (man kann in den documentclass Optionen aus einer Reihe von Vorlagen wählen: azure, frames, troispoints, ...) Man kann für die Slides den Übergang als Option angeben, möglich sind Split, Blinds, Box, Dissolve, Glitter, Replace \ overlays {2}{ \ begin { slide }[ Glitter ]{ Folientitel } \ begin { itemize } \ FromSlide {1} \ item Erstens \ FromSlide {2} \ item Zweitens \ end { itemize } \ end { slide } } Mit dem overlays Befehl und den FromSlide, ToSlide und \UntilSlide Kommandos kann man Seiten schrittweise verändern. Kapitel 5 Computer Algebra Systeme Unter einem Computer Algebra System (CAS) versteht man ein Programm, mit dem es möglich ist, mathematische Terme symbolisch zu verarbeiten. Das CAS soll Umformungen und Vereinfachungen vornehmen können, Gleichungen auswerten und lösen aber auch Differentiations- und Integrationsregeln beherrschen. Die meisten CAS bieten auch umfangreiche Grafikfunktionen zum Darstellen von Funktionen an. Numerisches Rechnen ist meist auch möglich, dies ist aber nicht das Haupteinsatzgebiet für solche Systeme. Dieses Kapitel soll nur die grundlegenden Schritte für den Einsatz von Computeralgebrasystemen vorstellen. Dabei wird der Schwerpunkt auf frei erhältliche CAS wie MAXIMA gelegt, gleichzeitig sollen aber auch die Unterschiede zu Maple und Mathematica gezeigt werden. Für tiefergehende Kenntnisse wird auf Literatur wie Char et al. [1992],Kofler [1994], Wolfram [1996] und Kofler [1992] 99 100 KAPITEL 5. COMPUTER ALGEBRA SYSTEME verwiesen. 5.1 Überblick Die Geschichte von Computer Algebra Systemen geht bis in die 60er Jahre zurück. 1968 entstand am MIT1 das Programm Macsyma for symbolische, numerische und grafische Aufgabenstellungen. Kurz darauf entstanden AXIOM (bei IBM) and REDUCE, Ende der 70 Jahre folgt DERIVE (1979) und MAPLE (1980). Das wohl bekannteste System entstand erst viel später: Mathematica (1988). Kurz darauf folgt MuPAD im Jahre 1990. Die meisten dieser Systeme basieren ursprünglich auf LISP, einer listenorientierten Programmiersprache. 5.1.1 MAXIMA Das ursprünglich frei verfügbare Macsyma wurde vom MIT zu Beginn der 80er Jahre in ein kommerzielles Produkt umgewandelt. Wiliam Schelter entwickelte die freie Version unter dem Namen MAXIMA weiter. Mittlerweile gibt es das kommerzielle Macsyma nicht mehr, dafür ist MAXIMA eines der wichtigsten Freeware CAS mit einer aktiven Entwicklergemeinschaft. Die Verwandtschaft zu LISP ist bei MAXIMA ziemlich stark auch in der Syntax bemerkbar. MAXIMA ist kommandozeilenorientiert, die Ausgabe erfolgt nur textbasiert mittels ASCII Darstellung. Der Aufruf lautet: maxima 1 Massachusetts Institute of Technology 5.1. ÜBERBLICK 101 Es gibt aber auch ein in Tcl/Tk geschriebenes grafisches Frontend xmaxima mit dem in HTML-Seiten eingebettete MAXIMA Befehle ausgeführt werden können. Der Eingabeprompt von MAXIMA lautet (%iX): , wobei X fortlaufend die Eingaben durchnumeriert. Maxima 5.17.1 http://maxima.sourceforge.net Using Lisp GNU Common Lisp (GCL) GCL 2.6.7 (aka GCL) Distributed under the GNU Public License. See the file COPYING. Dedicated to the memory of William Schelter. The function bug_report() provides bug reporting information. (%i1) 1+1; Ausgaben erscheinen hinter dem Prompt (%oX): (%o1) (%i2) 2 und werden gleichzeitig in eine Variable %oX abgespeichert. Eingaben sind mit einem Semikolon “;” abzuschließen. Wird die Zeile mit “$” beendet, so wird die Ausgabe des Ergebnisses unterdrückt. Die Groß- oder Kleinschreibung wurde in MAXIMA für vordefinierte Funktionen und Symbole in frühen Versionen nicht berücksichtigt, dies war eine der Eigenschaften die direkt von LISP geerbt wurde: (C2) SIN(%PI); (D2) (C3) sin(%Pi); 0 (D3) 0 102 KAPITEL 5. COMPUTER ALGEBRA SYSTEME In aktuellen MAXIMA Versionen funktioniert nur mehr die Kleinschreibung: (%i1) SIN(%PI); (%o1) (%i2) sin(%pi); (%o2) SIN(%PI) 0 Bei selbst definierten Variablen galt die Unterscheidung zwischen Klein- und Großschreibung aber schon immer. Ein Beispiel für die ASCII Ausgabe von Ergebnissen ist (%i3) integrate(sin(x)^3,x); (%o3) 3 cos (x) ------- - cos(x) 3 MAXIMA kann auch im Emacs mittels Alt - x maxima gestartet werden. Die Ein- und Ausgabe erfolgt dann in der selben Art und Weise wie direkt auf der Kommandozeile. Im imaxima-mode2 Mode werden die Ausgaben LATEX-formatiert dargestellt, siehe Abbildung 5.1. Gestartet wird der imaxima-mode mittels Alt - x imaxima. Mit den wxplot* Kommandos können dort sogar Plots direkt im Emacs Fenster dargestellt werden. Der emaxima Mode für den Emacs ermöglicht es, MAXIMA Befehle direkt in ein LATEX Dokument einzubauen. Die Auswertung der Befehle über ein spezielles emaxima Menü fügt dann die Ausgaben in Text oder LATEX Form direkt ins LATEX Dokument ein. Gestartet wird dieser Emacs Mode mittels 2 http://www.ifa.au.dk/~harder/imaxima.html, <[email protected]> Autor: Jesper Harder 5.1. ÜBERBLICK Abbildung 5.1: MAXIMA im Emacs (imaxima) 103 104 KAPITEL 5. COMPUTER ALGEBRA SYSTEME Alt - x emaxima-mode das auf ein bestehendes LATEXDokument angewendet wird, zusätzlich ist im Dokumentkopf das emaxima Paket zu laden, z.B.: \documentclass{article} \usepackage{emaxima} \begin{document} \begin{maxima}[] integrate(sin(x),x); \end{maxima} \end{document} Ein vergleichbares MAXIMA Interface bietet der TeXmacs3 . Dort wird MAXIMA über den Menüpunkt “Insert”/“session”/“maxima” aufgerufen. Im TeXmacs werden die MAXIMA Ausgaben ebenfalls LATEX-formatiert ausgegeben, siehe Abbildung 5.2. Im Gegensatz zu imaxima sind die Ausgaben aber keine eingefügten Bilder und somit besser weiterverarbeitbar. Die Plotausgaben erscheinen allerdings nicht automatisch im TeXmacs Dokument, sondern müssen erst als PostScript Datei abgespeichert und dann eingefügt werden. 5.1.2 Reduce Reduce basiert wie MAXIMA auf der Programmiersprache LISP und ist ebenfalls in den 60er Jahren enstanden. Die aktuelle Version von Reduce4 ist ebenfalls freie Software und meldet sich in einem grafischen Frontend mit dem folgenden Prompt: Reduce (Free CSL version), 14-Apr-11 ... 3 GNU TeXmacs: http://www.texmacs.org/ 4 http://reduce-algebra.sourceforge.net/ 5.1. ÜBERBLICK Abbildung 5.2: MAXIMA Session innerhalb von TeXmacs 105 106 KAPITEL 5. COMPUTER ALGEBRA SYSTEME 1: 1: sin(pi); 0 Die Ausgabe in der Reduce GUI wird mit LATEX formatiert: 2: int(sin(x)^3,x); 2 − cos (x) sin (x) − 2 cos (x) + 2 3 und kann als LATEX Quelltext in andere Anwendungen kopiert werden. Für Plots wird Gnuplot, d.h. auch die Gnuplot-spezifische Syntax verwendet, in diesem Beispiel also z.B. ** statt ^: 3: plot(x**2,x=(0 .. 1)); 5.1.3 Axiom 1971 entstand Axiom (damals noch unter dem Namen Scratchpad) bei IBM. Wie MAXIMA ist es LISP-basiert. Es wurde zuerst auf 5.1. ÜBERBLICK 107 IBM Mainframes der Reihen 3081 und 3090 eingesetzt. Anfang der 90er Jahre wurde das System unter dem Namen Axiom von NAG Ltd. weiterentwickelt und 2001 eingestellt. Seit 2002 ist es unter einer BSD-Lizenz als freie Software verfügbar5 . Die Kommandozeilenversion wird mit axiom gestartet und meldet sich mit GCL (GNU Common Lisp) 2.6.5 CLtL1 Aug 17 2004 19:17:02 Source License: LGPL(gcl,gmp), GPL(unexec,bfd) Binary License: GPL due to GPL'ed components: (READLINE BFD UNEXEC) Modifications of this banner must retain notice of a compatible license Dedicated to the memory of W. Schelter Use (help) to get some basic information on how to use GCL. AXIOM Computer Algebra System Version of Tuesday August 31, 2004 at 22:58:41 ----------------------------------------------------------------------Issue )copyright to view copyright notices. Issue )summary for a summary of useful system commands. Issue )quit to leave AXIOM and return to shell. ----------------------------------------------------------------------Re-reading Re-reading Re-reading Re-reading (1) -> compress.daase operation.daase category.daase browse.daase 5 http://page.axiom-developer.org/ Re-reading interp.daase 108 KAPITEL 5. COMPUTER ALGEBRA SYSTEME Als graphische Oberfläche läßt sich genau wie bei MAXIMA der TEXmacs einsetzen. Im Gegensatz zur terminalorienteren Ausgabe der Kommandozeilenversion wird innerhalb vom TEXmacs LATEXFormelsatz zur Aufbereitung der Ergebnisse eingesetzt. (1) -> sin(%pi) (1) 0 Type: Express (2) -> (2) integrate(sin(x)^3,x) 3 cos(x) - 3cos(x) ----------------3 Type: Union(Expression I Steuerbefehle in Axiom beginnen mit einer einzelnen schließenden Klammer. So beendet man Axiom z.B. mittels )q 5.1.4 Maple Maple war das erste System das auch für kleinere Computer entwickelt wurde (da LISP eine interpretierte Sprache ist, mußten für die darauf aufbauenden CAS leistungsstarke Rechner zur Verfügung stehen). Unter UNIX stehen zwei Aufrufvarianten zur Verfügung, die textorientierte Kommandozeilenversion 5.1. ÜBERBLICK 109 Abbildung 5.3: Axiom Session in TEXmacs maple sowie eine grafische Oberfläche xmaple & die ein Notebookinterface zum Abspeichern und Wiederverwenden von Eingaben anbietet. Die Kommandozeilenversion von Maple meldet sich mit |\^/| ._|\| |/|_. \ MAPLE / <____ ____> | > Maple V Release 5 (Single User) Copyright (c) 1981-1997 by Waterloo Maple Inc. All rights reserved. Maple and Maple V are registered trademarks of Waterloo Maple Inc. Type ? for help. Hinter dem > Prompt erfolgen die Eingaben, abgeschlossen mit “;”. Groß- und Kleinschreibung werden in Maple unterschieden, die meisten Funktionen werden kleingeschrieben, z.B. > sin(Pi); 110 KAPITEL 5. COMPUTER ALGEBRA SYSTEME 0 Auf der Kommandozeile wird wie bei MAXIMA eine ASCII Darstellung für Formeln verwendet: > integrate(sin(x)^3,x); 2 - 1/3 sin(x) cos(x) - 2/3 cos(x) Einen Screenshot der grafischen Oberfläche findet man in Abbildung 5.4 Abbildung 5.4: Maple Session unter X Window 5.1. ÜBERBLICK 5.1.5 111 Mathematica Mathematica ist ein erst ziemlich spät entstandenes CAS, die erste Version stammt aus dem Jahr 1988. Nicht zuletzt deshalb ist es eines der am besten strukturierten Systeme. Auch hier existiert unter UNIX eine Kommandozeilenvariante math und eine grafische Oberfläche mit Notebookinterface mathematica & Die Kommandozeilenversion meldet sich mit Mathematica 4.0 for Digital Unix Copyright 1988-1999 Wolfram Research, Inc. -- Terminal graphics initialized -In[1]:= Die Eingabzeilen werden mit In[X]:= mit fortlaufendem X dargestellt. Eingaben erfolgen in Mathematica ohne abschließendes Semikolon. Im grafischen Frontend ist zu beachten, daß die ENTER Taste nur die Eingabe auf mehrere Zeilen aufteilt, erst Ctrl - ENTER führt zur Auswertung der Eingaben. In Mathematica wird ebenso wie bei Maple zwischen Groß- und Kleinschreibung unterschieden. In der Regel sind alle vorgefertigten Funktionen mit großem Anfangsbuchstaben zu schreiben. Eine weitere Besonderheit ist die Verwendung eckiger Klammern anstelle runder für die Argumentübergabe: In[1]:= Sin[Pi] Out[1]= 0 112 KAPITEL 5. COMPUTER ALGEBRA SYSTEME Als Beispiel für die Ausgabe in Terminalgrafik wieder In[2]:= Integrate[Sin[x]^3,x] -3 Cos[x] Cos[3 x] Out[2]= --------- + -------4 12 Die Notebook Oberfläche ist Abbildung 5.5 zu entnehmen. Abbildung 5.5: Mathematica Notebook 5.1.6 MuPAD MuPAD ist eines der jüngsten Computer Algebra Systeme. Es entstand als Forschungsprojekt an der Universität Paderborn, die erste Version erschien 1992. Die Basisversion stand für universitären 5.1. ÜBERBLICK 113 Einsatz kostenfrei zur Verfügung, auch die aktuelle Version kann man für persönlichen Einsatz frei registrieren lassen. Die erweiterte Windowsversion MuPAD Pro ist nur kommerziell erhältlich. Sie bietet zusätzlich ein Notebook Interface ähnlich zu Mathematica und Maple. Die Kommandozeilenvariante unter UNIX meldet sich mit *----* /| /| *----* | | *--|-* |/ |/ *----* MuPAD 2.0.0 -- The Open Computer Algebra System Copyright (c) 1997 - 2000 by SciFace Software All rights reserved. Licensed to: Albrecht Gebhardt >> Ein Screenshot der grafischen Oberfläche ist in Abbildung 5.6 dargestellt. Kommandos und Funktionsnamen werden im Allgemeinen klein geschrieben, Befehle müssen mit ; abgeschlossen werden. Formelausgaben erfolgen ausschließlich im ASCII Modus: >> int(sin(x)^3,x); / PI \3 sin| -- - x | \ 2 / / PI \ -------------- - sin| -- - x | 3 \ 2 / Vergleicht man die Resultate für dieses Beispiel unter MAXIMA, 114 KAPITEL 5. COMPUTER ALGEBRA SYSTEME Maple, Mathematica und MuPAD, wird man bemerken, daß alle System unterschiedliche Regeln zur Vereinfachung bei der Darstellung verwenden. Abbildung 5.6: XMupad 5.1.7 Yacas Ein weiteres OpenSource CAS ist Yacas6 (Yet Another Computer Algebra System) welches erst seit 1999 entwickelt wird. Das System an sich ist wiederum kommandozeilenorientiert, kann aber im TEXmacs mit Formelausgabe in LATEX-Qualität verwendet werden. Der Start erfolgt mit yacas und liefert 6 http://yacas.sf.net 5.1. ÜBERBLICK 115 [editvi.ys] [unix.ys] True; This is Yacas version '1.0.57'. Yacas is Free Software--Free as in Freedom--so you can redistribute Yac modify it under certain conditions. Yacas comes with ABSOLUTELY NO WARR See the GNU General Public License (GPL) for the full conditions. Type ?license or ?licence to see the GPL; type ?warranty for warranty i See http://yacas.sf.net for more information and documentation on Yacas Numeric mode: "Internal" To exit Yacas, enter Exit(); or quit or Ctrl-c. Type ?? for help. Or type ?function for help on a function. Type 'restart' to restart Yacas. To see example commands, keep typing Example(); In> Funktionsnamen sind ähnlich zu Mathematica (großer Anfangsbuchstabe), Argumente werden in runde Klammern gesetzt: In> Sin(Pi) Out> 0 Operationen wie Differenzieren und Integrieren werden in einer Operatorschreibweise vor den jeweiligen Ausdruck gesetzt: In> Integrate(x)(Sin(x)^3) Out> ((-3)*Cos(x)+Cos((-3)*x)/3)/4 Für Plots verwendet Yacas per Default gnuplot als externes Programm: In> Plot2D(x^2,0:1) Out> True 116 KAPITEL 5. COMPUTER ALGEBRA SYSTEME Abbildung 5.7: Yacas im TEXmacs Neben der Einbettung im TEXmacs gibt es auch einen yacas Emacsmode, der sich vor allem durch eine Menüführung zu den einzelnen CAS Funktionen auszeichnet. 5.2 Einfache Arithmetik Im einfachsten Fall lassen sich Computer Algebra System als bessere Taschenrechner verwenden. Dafür gelten die üblichen Schreibweisen und Klammerungsregeln. Bei der Eingabe von Zahlenwerten ist zu beachten, daß ein CAS entweder symbolisch oder numerisch rechnen kann. Verwendet man Dezimalpunkte, bedeutet dies numerisches Rechnen, verbunden mit den Rundungsfehlern die bei der internen Umwandlung in Maschinenzahlen auftreten. Schreibt man dagegen Brüche aus, wird symbolisch gerechnet und ein entsprechend gekürztes Ergebnis geliefert. Meist existieren auch Funktionen die ein symbolisches Ergebnis in ein numerisches umwandeln. Das folgende einfache Beispiel demonstriert dies in MAXIMA: 5.2. EINFACHE ARITHMETIK 117 (%i6) 1+3/10; (%o6) (%i7) 1+0.3; (%o7) (%i8) sqrt(2); (%o8) (%i9) sqrt(2.0); (%o9) (%i11) sqrt(3/4); (%o11) (%i12) sqrt(0.75); (%o12) (%i13) %pi; (%o13) (%i15) float(%pi); (%o15) 13 -10 1.3 sqrt(2) 1.414213562373095 sqrt(3) ------2 0.86602540378444 %pi 3.141592653589793 Ausdrücke die sich nicht weiter vereinfachen lassen, werden bei symbolischem Rechnen, wie oben zu sehen, einfach stehen gelassen (z.B. √ 2). Im Gegensatz zum gewöhnlichen Taschenrechner können CAS aber auch mit symbolischen Ausdrücken umgehen, die beliebige Variablenbezeichnungen enthalten7 . In MAXIMA enthält die spezielle Variable % den zuletzt zurückgelieferten Wert, dies gilt genauso in Maple und MuPAD. In Mathematica (und MAXIMA) kann man 7 Natürlich muß man darauf achten, keine schon reservierten Funktions- und Variablennamen (in MAXIMA z.B. %PI oder integrate) zu verwenden. Tabelle 5.1 enthält die gebräuchlichsten vordefinierten Konstanten. 118 KAPITEL 5. COMPUTER ALGEBRA SYSTEME hierfür (auch) die Bezeichnung der Ausgabezeile verwenden. (%i16) sqrt(-1); (%o16) (%i17) %; (%o17) In[2]:= Out[2]= In[3]:= Out[3]= %i %i Sqrt[-1] I Out[2] I Konstante i e π MAXIMA %i %e %pi Maple I E Pi Mathematica I E Pi Tabelle 5.1: Konstanten (%i18) (a+b)^2; (%o18) (%i19) expand((a+b)^2); (%o19) (%i20) a:1; (%o20) (%i21) (a+b)^2; (%o21) 2 (b + a) 2 2 b + 2 a b + a 1 2 (b + 1) Diesen Variablen lassen sich numerische Werte zuordnen (in MAXIMA ist : der Zuordnungsoperator, in Mathematica = und in Maple 5.2. EINFACHE ARITHMETIK 119 und MuPAD :=). Auch symbolische Terme können in Variablen gespeichert werden: (%i22) b:(c-d)^3; 3 (c - d) (%o22) (%i23) (a+b)^2; (%o23) 3 2 ((c - d) + 1) Matrizen werden zeilenweise angegeben: (%i1) M:matrix([1,2,3],[1,1,1],[0,0,1]); [ 1 2 [ (%o1) [ 1 1 [ [ 0 0 3 ] ] 1 ] ] 1 ] Eine Liste wichtiger Operatoren und Funktionen ist Tabelle 5.2 zu entnehmen. Symbolische Ausdrücke lassen sich auf verschiedene Weise manipulieren, die häufigsten Anwendungen sind • Ausmultiplizieren MAXIMA Maple expand(expr) expand(expr) Mathematica Expand[expr] (%i1) expand((x+5)*(x-5)*(x+b)); 3 2 (%o1) x + b x - 25 x - 25 b • in Faktoren zerlegen MAXIMA Maple factor(expr) factor(expr) Mathematica Factor[expr] 120 KAPITEL 5. COMPUTER ALGEBRA SYSTEME Operation +, −, ·, : Matrixmultiplikation A·B Exponent xa Zuweisung x = term Definition x := term Variable löschen ganzz. Division a ÷ b a modulo b Umwandlung in numerischen Wert MAXIMA A . B x:term; x:’term; kill(x) entier(a/b) mod(a,b) float(), bfloat(), fpprec Maple +, -, * 8 , / with(linalg); multiply(A,B); x^ a x:=term; x:=’term’; x:=’x’ iquo(a,b) a mod b evalf() Mathematica A . B Dot[A,B] oder x=term x:=term Clear[x] Quotient[a,b] Mod[a,b] N[] Tabelle 5.2: Operationen (%i2) factor(x^3+b*x^2-25*x-25*b); (%o2) (x - 5) (x + 5) (x + b) In MAXIMA muß bei komplexwertigen Termen manchmal gfactor() angewendet werden um ein Ausmultiplizieren zu erzwingen. • Vereinfachen MAXIMA Maple Mathematica ev(expr), simplify(expr) Simplify[expr] ratsimp divide(p1,p2,var) divide(p1,p2,’v2) PolynomialQuotientRemainder[] partfrac(term,var) convert(t,parfrac,v) Apart[term, var] (%i4) ev(a+3*a-b); (%o4) 4 a - b Maxima fasst gebrochen rationale Terme mit ratsimp zusammen: 5.2. EINFACHE ARITHMETIK 121 (%i5) (2*x^3-x+1)/(x^2-1)+1/(x+1); (%o5) 3 1 2 x - x + 1 ----- + -----------x + 1 2 x - 1 (%i6) ratsimp((2*x^3-x+1)/(x^2-1)+1/(x+1)); 3 2 x (%o6) -----2 x - 1 Polynomdivision wird mit divide erzwungen: (%i7) divide(2*x^3-x+1,x^2-1,x); (%o7) [2 x, x + 1] Partialbruchdarstellungen erzeugt man mit partfrac: (%i10) partfrac((3*x^3-x+1)/(x^2-1),x); 1 3 (%o10) --------- + 3 x + --------2 (x + 1) 2 (x - 1) Die Ausgaben lassen sich auch direkt in LATEX Format ausgeben: (%i5) expand(x-2)*(x+3); (%o5) (x - 2) (x + 3) (%i6) tex(%o5); $$\left(x-2\right)\,\left(x+3\right)\leqno{\tt (\%o5)}$$ (%o6) (\%o5) 122 KAPITEL 5. COMPUTER ALGEBRA SYSTEME dies würde die LATEX-Ausgabe (x − 2) (x + 3) (%o5) erzeugen. Dies funktioniert auch in den anderen CAS: MAXIMA Maple Mathematica tex(expr) latex(expr) TeXForm[expr] Alle CAS sind mit externen Libraries oder Packages erweiterbar: MAXIMA Maple Mathematica load(package) with(library) Get[package] Meist sind standardmäßig zu Beginn einer CAS Sitzung schon mehrere Pakete geladen. Manchmal muß die sofortige Ausführung einer Anweisung unterbunden werden, z.B. um zu vermeiden, daß bei der Definition einer Funktion das Argument x schon einen möglicherweise vorher auf x zugewiesenen Wert annimmt. In MAXIMA geschieht dies durch Vorstellen eines Apostroph ’ vor den entsprechenden Term, in Maple wird dazu der gesamte Ausdruck in Hochkommas gesetzt. Mathematica verwendet ein spezielles Zuweisungssymbol (:=). 5.3 Funktionen Die gebräuchlichen Funktionen sind in allen Systemen schon vordefiniert, siehe Tabelle 5.3. sin(x) cos(x) tan(x) usw. MAXIMA sin(x) cos(x) tan(x) Maple sin(x) cos(x) tan(x) Mathematica Sin[x] Cos[x] Tan[x] Tabelle 5.3: CAS Funktionen 5.3. FUNKTIONEN 123 Ein weiterer häufig auftretender Anwendungsfall sind selbstdefinierte Funktionen. Hier existieren wiederum unterschiedliche Schreibweisen, siehe Tabelle 5.4. Die so definierten eigenen Funktionen sind genauso wie die vordefinierten benutzbar. Unter Umständen muß allerdings das Argument durch Substitution eingesetzt werden, so z.B. wenn eine Ableitung einer Funktion wiederum als Funktion definiert wird: (%i7) f(x):=x^2; (%o7) (%i8) f(2); (%o8) (%i9) g(x):=diff(f(x),x); (%o9) (%i10) g(1); 2 f(x) := x 4 g(x) := diff(f(x), x) diff: second argument must be a variable; found 1 #0: g(x=1) -- an error. To debug this try: debugmode(true); (%i11) subst(1,x,g(x)); (%o11) 2 MAXIMA f(x):=x^2 Maple f:=x->x^2 Mathematica f[x_]=x^2 Tabelle 5.4: Funktionsdefinition Ähnliches gilt für Maple: > f:=x->x^2; 2 f := x -> x 124 KAPITEL 5. COMPUTER ALGEBRA SYSTEME > f(2); 4 > g:=x->diff(f(x),x); g := x -> diff(f(x), x) > g(2); Error, (in g) wrong number (or type) of parameters in function dif > subs(x=2,g(x)); 4 In Mathematica findet der Substitutionsoperator /. Anwendung (eine Kurzschreibweise für ReplaceAll[]) durch den eine oder mehrere Ersetzungsregeln der Form var -> wert mittels ./ auf den linkstehenden Term angewendet wird: In[1]:= f[x_]:=x^2 In[2]:= f[2] Out[2]= 4 In[3]:= g[x_]:=D[f[x],x] In[4]:= g[2] General::ivar: 2 is not a valid variable. Out[4]= D[4, 2] 5.4. GLEICHUNGEN 125 In[5]:= g[x]/.{x->2} Out[5]= 4 MAXIMA subst(eqn,term) subst(wert,var,term) Maple subs(eqn,term) Mathematica ReplaceAll[term,rule] bzw. term /. rule Tabelle 5.5: Substitution 5.4 Gleichungen Gleichungen werden in MAXIMA und Maple in der Form term1 = term2; formuliert. In Mathematica wird statt = der Operator == verwendet. Gleichungen können wiederum Variablen zugeordnet werden. (%i12) g1:3*x+4*y=1; (%o12) 4 y + 3 x = 1 Damit läßt sich dann später wieder auf schon formulierte Gleichungen zurückgreifen, z.B. um einzelne Variablen zu eliminieren: (%i13) solve(g1,x); (%o13) 4 y - 1 [x = - -------] 3 Die solve Funktion erwartet als erstes Argument einen symbolischen Term oder eine Gleichung und als zweites Argument die Variable 126 KAPITEL 5. COMPUTER ALGEBRA SYSTEME nach der aufgelöst werden soll. Ist das erste Argument ein einfacher Term wird angenommen, daß dessen Nullstellen bestimmt werden sollen. D.h. folgende Schreibweisen sind äquivalent: (%i14) solve(x^3-x^2+x-1,x); (%o14) [x = - %i, x = %i, x = 1] (%i15) lsg:solve(x^3-x^2+x-1=0,x); (%o15) [x = - %i, x = %i, x = 1] Die Lösung ist eine Liste von Gleichungen auf deren Elemente auch einzeln zugegriffen werden kann: (%i16) lsg[1]; (%o16) x = - %i Dies ist z.B. nötig um das Ergebnis in andere Terme einsetzen zu können: (%i10) subst(lsg[1],3*x+y); (%o10) y - 3 %i Mehrere Gleichungen lassen sich zu Gleichungsystemen zusammenfassen und (wenn möglich) lösen, in MAXIMA (die Gleichung g1 aus einer Eingabe weiter oben wird hier wiederverwendet!): (%i20) g2:-2*x-y=0; (%o20) (%i23) algsys([g1,g2],[x,y]); (%o23) in Maple: - y - 2 x = 0 1 2 [[x = - -, y = -]] 5 5 5.5. GRENZWERTE 127 > solve({4*y+3*x=1,-2*x-y=0},{x,y}); {x = -1/5, y = 2/5} in Mathematica: In[2]:=Solve[{4y+3x==1,-2x-y==0}, {x,y}] Out[2]={x -> -1/5, y -> 2/5} Hier ist das Ergebnis wieder eine Liste von Ersetzungsregeln die mit -/.- auf andere Terme angewendet werden kann. MAXIMA solve, algsys Maple solve Mathematica Solve Tabelle 5.6: Gleichungen lösen 5.5 Grenzwerte Grenzwerte lim g(x) x→x0 werden in MAXIMA mit der limit Funktion bestimmt, im ersten Argument steht der Ausdruck g(x), dann wird die Variable x sowie der Wert x0 angegeben und optional noch mittels plus oder minus der rechst- oder linksseitige Grenzwert ausgewählt. (%i24) limit(x/(x-1),x,1); (%o24) (%i25) limit(x/(x-1),x,1,plus); (%o25) (%i26) limit(x/(x-1),x,1,minus); (%o26) infinity inf minf 128 KAPITEL 5. COMPUTER ALGEBRA SYSTEME (%i31) limit((-1)^x,x,inf); (%o31) ind In diesem Beispiel tauchen als Ergebnis die Ausdrücke inf (=∞), minf (=−∞), infinite (=komplex Unendlich, d.h. der Grenzwert des Betrags ist ∞ stimmt aber nicht mit rechts- und linksseitigem Grenzwert überein) und ind (unbestimmt aber beschränkt) auf. MAXIMA limit Maple limit Mathematica Limit Tabelle 5.7: Grenzwerte In Mathematica wird der Grenzübergang für x → a mit x -> a als zweites Argument zu Limit angegeben, in Maple als x=a. 5.6 Differentiation Mittels diff wird der als erster Operand angegebene Ausdruck nach der Variablen die als zweiter Operand übergeben wird abgeleitet, im dritten Parameter wird angegeben wie oft differenziert werden soll. einfach: (%i27) diff(3*x^2-5,x); (%o27) (%i28) diff(3*x^2-5,x,2); (%o28) 6 x 6 Nach dem selben Schema lassen sich partielle Ableitungen bestimmen: (%i29) diff(3*x^3*y-5*y^2*x+x^2*y^2,x,2); 2 5.6. DIFFERENTIATION 129 (%o29) 2 y + 18 x y (%i30) diff(3*x^3*y-5*y^2*x+x^2*y^2,x,2,y,1); (%o30) 4 y + 18 x In Maple heisst die entsprechende Funktion ebenfalls diff, in Mathematica D. Dort ist auch die Kurzschreibweise mit dem ' Operator erlaubt. Differentialgleichungen werden ebenfalls mit der diff Funktion formuliert, hier muss aber über das vorangestellte Apostroph die sofortige Ausführung der Differentiation unterbunden werde. Für Randwertprobleme werden mit atvalue die Startbedingungen angegeben. Anschliessend löst desolve die Differentialgleichung. (%i7) dg:'diff(g(x),x)=k*x; (%o7) d -- (g(x)) = k x dx (%i9) atvalue(g(x),x=0,1)$ (%i10) desolve(dg,g(x)); (%o10) 2 k x g(x) = ---- + 1 2 Es könnne auch Systeme von Differentialgleichungen gelöst werden: (%i11) dg1:'diff(f(x),x)='diff(g(x),x)+sin(x); d d (%o11) -- (f(x)) = -- (g(x)) + sin(x) dx dx (%i12) dg2:'diff(g(x),x,2)='diff(f(x),x)-cos(x); 2 130 KAPITEL 5. COMPUTER ALGEBRA SYSTEME d d --- (g(x)) = -- (f(x)) - cos(x) 2 dx dx (%i13) atvalue('diff(g(x),x),x=0,a); (%o13) a (%i14) atvalue(f(x),x=0,1); (%o14) 1 (%i15) desolve([dg1,dg2],[f(x),g(x)]); x x (%o15) [f(x) = a %e - a + 1, g(x) = cos(x) + a %e - a] (%o12) Die Lösung lautete hier also f (x) = a ex − a + 1 g (x) = cos x + a ex − a In Maple finden die diff und dsolve Funktion Anwendung: > ode1 := diff(y(x),x)-y(x)^2+y(x)*sin(x)-cos(x); /d \ 2 ode1 := |-- y(x)| - y(x) + y(x) sin(x) - cos(x) \dx / > dsolve(ode1); exp(-cos(x)) y(x) = - ------------------------- + sin(x) / | _C1 + | exp(-cos(x)) dx | / 5.7. INTEGRALE 131 Ähnliches gilt für Mathematica, dort wird der Ableitungsoperator ' (oder die Funktion D) sowie DSolve verwendet: In[4]:= DSolve[ y'[x] == a y[x] + 1, y[x], x ] 1 a x Out[4]= {{y[x] -> -(-) + E C[1]}} a MAXIMA diff desolve Maple diff dsolve Mathematica D DSolve Tabelle 5.8: Differenzieren, Differentialgleichungen 5.7 Integrale Integration erfolgt mit der Funktion integrate, für unbestimmte Integrale sind der Integrand und die Integrationsvariable anzugeben: (%i16) integrate(x^2+a*x,x); (%o16) 3 2 x a x -- + ---3 2 Bei bestimmten Integralen wird zusätzlich der Bereich mit übergeben: (%i17) integrate(x^2+a*x,x,0,10); 132 KAPITEL 5. COMPUTER ALGEBRA SYSTEME 150 a + 1000 -----------3 (%o17) MAXIMA integrate Maple integrate, int Mathematica Integrate Tabelle 5.9: Integration 5.8 Plots Plots in MAXIMA werden in neueren Versionen standardmäßig mit Gnuplot dargestellt, ältere Versionen verwendeten das OpenMath Format. Bei 3D-Plots kann über Mausinteraktion der Plotinhalt rotiert werden. x-y-Plots werden mit der Funktion plot2d erstellt. Das erste Argument ist ein Funktionsterm, das zweite eine Bereichsangabe für die Variable. (%i18) plot2d(x^2,[x,-1,1]); (%o18) Durch Anhängen der Option [gnuplot_term,postscript] wird die Grafik in eine Datei "maxplot.postscript" gespeichert, die mit Grafiktools (z.B. ps2eps, hier ist speziell der Postscript Preview mit der Option -P zu unterdrücken, sonst stimmt die Seitenorientierung eventuell nicht!) in weitere Formate umgewandelt werden kann. Mit der Option [gnuplot_out_file,"datei.ps"] lässt sich die Ausgabedatei benennen um nicht den Vorgabenamen "maxplot.postscript" verwenden zu müssen. 5.9. AUFGABEN 133 3D-Plots lassen sich ebenfalls mit OpenMath darstellen, über die Option plot_format kann aber auch die Ausgabe über GeomView erfolgen. Im imaxima Mode innerhalb des Emacs erscheinen die Plots direkt im Ausgabefile durch Verwendung der Plotbefehle wxplot2d und wxplot3d. (%i20) plot3d(sin(x*y),[x,-%pi,%pi],[y,-%pi,%pi]); (%o20) false (%i21) plot3d(sin(x*y),[x,-%pi,%pi],[y,-%pi,%pi], [plot_format,geomview]); (%o21) false MAXIMA plot2d, plot3d Maple plot, plot3d Mathematica Plot, Plot3D Tabelle 5.10: Funktionsdarstellungen 5.9 5.9.1 Aufgaben Einfache Anwendungen 1. Vereinfachen Sie (a) (x2 − y 2 ) 3x − 2y − 3x2 x−y ( % i 1) ( x ^2 - y ^2)*(3* x -2* y )/( x - y ) -3* x ^2; 2 (3 x - 2 y ) ( x 2 2 - y ) 134 KAPITEL 5. COMPUTER ALGEBRA SYSTEME ( % o 1) --------------------- - 3 x x - y ( % i 2) ev (( x ^2 - y ^2)*(3* x -2* y )/( x - y ) -3* x ^2); 2 2 (3 x - 2 y ) ( x - y ) 2 ( % o 2) --------------------- - 3 x x - y ( % i 3) ratsimp (( x ^2 - y ^2)*(3* x -2* y )/( x - y ) -3* x ^2); 2 ( % o 3) x y - 2 y x y − 2 y2 Hier gibt ratsimp das beste Ergebnis. (b) e3x(y−x)+ln x ( % i 4) exp (3* x *( y - x )+ log ( x )); 3 x (y - x) ( % o 4) x %e ( % i 5) ev ( exp (3* x *( y - x )+ log ( x ))); 3 x (y - x) ( % o 5) x %e ( % i 6) ratsimp ( exp (3* x *( y - x )+ log ( x ))); 2 3 x y - 3 x ( % o 6) x %e x e3 x y−3 x 2 Die offensichtliche Vereinfachung von elog(x) zu x wird automatisch ausgeführt, weil der Schalter logsimp defaultmäßig auf true steht, sonst: ( % i 1) exp (3* x *( y - x )+ log ( x )) , logsimp : false ; 3 x ( y - x ) + log ( x ) ( % o 1) %e e3 x (y−x)+log x 5.9. AUFGABEN 135 2. Differenzieren Sie nach x (a) cos 3 · x2 ( % i 10) diff ( cos (3* x ^2) , x ); 2 - 6 x sin (3 x ) ( % o 10) −6 x sin 3 x2 (b) r 3 1 +x x ( % i 11) diff ((1/ x + x )^(1/3) , x ); 1 1 - -2 x ( % o 11) -----------1 2/3 3 ( x + -) x ( % i 12) ratsimp ( diff ((1/ x + x )^(1/3) , x )); 2 x - 1 ( % o 12) -----------------4/3 2 2/3 3 x ( x + 1) x2 − 1 4 2 3 x 3 (x2 + 1) 3 ratsimp vereinfacht hier den Zähler etwas. (c) x2 − 3x − 1 1−x 136 KAPITEL 5. COMPUTER ALGEBRA SYSTEME ( % i 13) diff (( x ^2 -3* x -1)/(1 - x ) , x ); 2 x - 3 x - 1 2 x - 3 ( % o 13) ------------ + ------2 1 - x (1 - x ) ( % i 14) ratsimp ( diff (( x ^2 -3* x -1)/(1 - x ) , x )); 2 x - 2 x + 4 ( % o 14) - -----------2 x - 2 x + 1 x2 − 2 x + 4 x2 − 2 x + 1 Wieder ist der Output mit ratsimp etwas kompakter. − 3. Bestimmen Sie alle partiellen Ableitungen bis Ordnung 2 von (a) x+y x2 − y 2 ( % i 15) diff (( x + y )/( x ^2 - y ^2) , x ,2); 2 2 (y + x) (y + x) ( % o 15) 2 4 x 8 x - ---------- - ---------- + -----------2 2 2 2 2 2 2 3 (x - y ) (x - y ) (x - y ) ( % i 16) ratsimp ( diff (( x + y )/( x ^2 - y ^2) , x ,2)); 2 ( % o 16) - ------------------------3 2 2 3 y - 3 x y + 3 x y - x ( % i 17) ratsimp ( diff (( x + y )/( x ^2 - y ^2) , y ,2)); 2 5.9. AUFGABEN 137 ( % o 17) - ------------------------3 2 2 3 y - 3 x y + 3 x y - x ( % i 18) ratsimp ( diff (( x + y )/( x ^2 - y ^2) , x ,1 , y ,1)); 2 ( % o 18) ------------------------3 2 2 3 y - 3 x y + 3 x y - x − − y3 y3 y3 − 3 x y2 2 + 3 x2 y − x3 − 3 x y2 2 + 3 x2 y − x3 − 3 x y2 2 + 3 x2 y − x3 Gleich alles von vornherein mit ratsimp weitervereinfacht. (b) ex−y − x2 − y 2 2 ( % i 19) ratsimp ( diff ( exp (x - y ) -( x ^2 - y ^2)/2 , x ,2)); - y y x ( % o 19) - %e (% e - % e ) ( % i 20) expand ( diff ( exp (x - y ) -( x ^2 - y ^2)/2 , x ,2)); x - y ( % o 20) %e - 1 ( % i 21) expand ( diff ( exp (x - y ) -( x ^2 - y ^2)/2 , y ,2)); x - y ( % o 21) %e + 1 ( % i 22) expand ( diff ( exp (x - y ) -( x ^2 - y ^2)/2 , x ,1 , y ,1)); x - y ( % o 22) - %e 138 KAPITEL 5. COMPUTER ALGEBRA SYSTEME ex−y − 1 ex−y + 1 −ex−y Hier ist expand besser als ratsimp. 4. Bestimmen Sie die unbestimmten Integrale (a) Z x2 − x dx a ( % i 23) i n t e g r a t e (( x ^2 - x )/ a , x ); 3 2 x x -- - -3 2 ( % o 23) ------a ( % i 24) ratsimp ( i n t e g r a t e (( x ^2 - x )/ a , x )); 3 2 2 x - 3 x ( % o 24) ----------6 a 2 x3 − 3 x2 6a (b) Z x2 − 3x + 1 dx 1−x ( % i 25) ratsimp ( i n t e g r a t e (( x ^2 -3* x +1)/(1 - x ) , x )); 2 2 log ( x - 1) - x + 4 x ( % o 25) ----------------------2 5.9. AUFGABEN 139 2 log (x − 1) − x2 + 4 x 2 (c) Z 4x4 − 2x3 + 4 dx 3x2 − 2 ( % i 26) ratsimp ( i n t e g r a t e ((4* x ^4 -2* x ^ 3 + 4 ) / ( 3 * x ^2 -2) , x )); 3 x - sqrt (6) 2 3 ( % o 26) (26 log ( - - - - - - - - - - - - -) - 2 sqrt (6) log (3 x - 2) + 4 sqrt (6) x 3 x + sqrt (6) 2 - 3 sqrt (6) x + 8 sqrt (6) x )/(9 sqrt (6)) ( % i 27) expand ( i n t e g r a t e ((4* x ^4 -2* x ^ 3 + 4 ) / ( 3 * x ^2 -2) , x )); 6 x 2 sqrt (6) 26 log ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -) 2 3 2 6 x + 2 sqrt (6) 6 x + 2 sqrt (6) 2 log (3 x - 2) 4 x x ( % o 27) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 9 sqrt (6) 9 9 3 8 x + --9 ( % i 28) factor ( i n t e g r a t e ((4* x ^4 -2* x ^ 3 + 4 ) / ( 3 * x ^2 -2) , x )); 3 x - sqrt (6) 2 3 ( % o 28) (26 log ( - - - - - - - - - - - - -) - 2 sqrt (6) log (3 x - 2) + 4 sqrt (6) x 3 x + sqrt (6) 2 - 3 sqrt (6) x + 8 sqrt (6) x )/(9 sqrt (6)) 140 KAPITEL 5. COMPUTER ALGEBRA SYSTEME Das läßt sich wohl automatisch nicht gescheit weiter vereinfachen, händisch würde man natürlich die Wurzel aus 6 nur im ersten Term im Zähler reziprok stehen lassen und sonst herauskürzen. √ √ √ √ √ √6 − 2 6 log 3 x2 − 2 + 4 6 x3 − 3 6 x2 + 8 6 x 26 log 33 x− x+ 6 √ 9 6 5.9.2 Funktionen In MAXIMA kann man auch umfangreichere Funktionen schreiben, diese werden in *.mac Files abgelegt. Sie entstehen ähnlich zu den in 5.3 eingeführten Funktionen mit dem := Operator, bestehen aber aus einer block() Anweisung. Diese beginnt mit der Deklaration lokaler Variablen in eckiger Klammer, danach folgen MAXIMA Befehle mit Komma getrennt. Der return Befehl bestimmt den Rückgabewert. Die folgende Funktion (abglegt in regulafalsi.mac) implementiert die regula falsi Methode zur Nullstellenbestimmung. Beim Aufruf kann man wählen ob symbolisch oder numerisch gerechnet werden soll. /* Regula Falsi in Maxima Code. */ regulafalsi(f,unten,oben,symbolic) := block([eps:float(10^-6),maxi if(sign(f(unten))=sign(f(oben))) then error("keine unterschied iter:0, mitte:unten, while(abs(float(f(mitte)))>eps and iter<=maxiter) do ( iter:iter+1, /* fuer Verfolgung Kommentar deaktivieren: 5.9. AUFGABEN 141 disp(iter), disp(abs(float(f(mitte)))), */ if (symbolic) then mitte:(unten*f(oben)-oben*f(unten))/(f(oben)-f(unten)) else mitte:float((unten*f(oben)-oben*f(unten))/(f(oben)-f(unten))) if(sign(f(mitte))=sign(f(unten))) then unten:mitte else if(sign(f(oben))=sign(f(mitte))) then oben:mitte ), if(iter<maxiter) then return(mitte) else error("maximale Anzahl Iterationen erreicht") )$ Mit load wird die externe Funktion geladen, eine Beispielfunktion f mit Nullstelle -3 wird definiert: ( % i 2) load (" r e g u l a f a l s i . mac ")£ ( % i 3) f ( x ):=( x -3)*( x +3)*( x -1); ( % o 3) f ( x ) := ( x - 3) ( x + 3) ( x - 1) Falls man symbolisch rechnet, braucht es für eine Genauigkeit von 10− 5 15 Iterationen die auf aktueller (2013) Hardware schon fast eine Minute dauern. Die Ausgabe des Ergebnisses, gerundet -2.999999865986904, statt exakt -3, als Bruch ganzer Zahlen verbraucht einige Bildschirmseiten (und wird hier deshalb mit $) unterdrückt 142 KAPITEL 5. COMPUTER ALGEBRA SYSTEME ( % i 4) x : r e g u l a f a l s i (f , -4 , -2 , true )£ ( % i 10) float ( x ); ( % o 10) - 2.999999986762787 Rechnet man numerisch duch Einsatz der Funktion float, d.h. anstelle von mitte :( unten * f ( oben ) - oben * f ( unten ))/( f ( oben ) - f ( unten )) wird nun mitte : float (( unten * f ( oben ) - oben * f ( unten ))/( f ( oben ) - f ( unten ))) verwendet, so dauert es nur mehr den Bruchteil einer Sekunde. float angewendet): ( % i 8) r e g u l a f a l s i (f , -4 , -2 , false ); ( % o 8) - 2.999999986762787 Kapitel 6 R 6.1 Geschichte von S und R S entstand 1976 in den BELL Labs1 von AT&T. Es stellt ein System zur Datenanalyse mit umfangreichen statistischen und grafischen Funktionen dar. Die Autoren von S Version 1 waren Rick Becker, John Chambers, Doug Dunn, Paul Tukey und Graham Wilkinson. Nachdem S Version 1 nur auf Honeywell Grossrechnern verfügbar war, wurde Version 2 schon auf die damaligen UNIX Rechner portiert (UNIX entstand ja im selben Gebäude nur in einem anderen Stockwerk). Version 3 fand erstmal weitere Verbreitung und war Grundlage für die kommerzielle und erweiterte Version S-PLUS, diese wurde von StatSci (später MathSoft, Insightful und heute TIBCO) vermarktet. S Version 4 ist erst Ende der 90er Jahre entstanden. R entstand an der University of Auckland in den frühen 90er Jahren. Die Autoren Robert Gentleman und Ross Ihaka wollten lediglich 1 http://netlib.bell-labs.com/cm/ms/departments/sia/S/index.html 143 144 KAPITEL 6. R ein Statistikprogramm für ihr dortiges (Macintosh) Computerlabor schreiben. Sie implementierten einen Scheme Interpreter und statteten ihn mit einer S ähnlichen Syntax aus2 . 1993 wurde die erste Version auf der s-news Mailingliste vorgestellt. Ab 1995 steht R unter der GPL Lizenz und wird in Quelltextform verbreitet. Anfang 2000 erscheint Version 1.0. R ist in wesentlichen Teilen mit S Version 3 kompatibel (so wie S-PLUS 3.x und 4.x). 6.2 Erste Schritte mit R Wir verwenden R unter Linux. Um auch später wieder auf die bereits verwendeten Daten zugreifen zu können, erzeugen Sie am besten ein Unterverzeichnis, das für Ihre Arbeiten mit R reserviert ist: geben Sie dazu in einem Kommando-Fenster mkdir R-Daten ein, wechseln Sie dann mit cd R-Daten in dieses Verzeichnis. R legt im jeweils aktuellen Verzeichnis ein .RData- und ein .RhistoryFile an. In der ersten Datei werden die in R erzeugten oder eingelesenen Datensätze, in der zweiten die jeweils letzten (100) Befehle gespeichert. Der Start auf der Kommandozeile erfolgt einfach durch Eingabe von 2 http://cran.r-project.org/doc/html/interface98-paper/paper_1.html 6.2. ERSTE SCHRITTE MIT R 145 R Komfortabler ist es, R im Emacs laufen zu lassen. Starten Sie dazu den Emacs, wie Sie es bereits gelernt haben: geben Sie in einem Kommando-Fenster emacs & ein. R wird im Emacs durch Eingabe von Alt-X R gestartet. R meldet sich daraufhin wie folgt: R : Copyright 2003 , The R Development Core Team Version 1.7.0 (2003 -04 -16) R is free software and comes with ABSOLUTELY NO WARRANTY . You are welcome to redistribute it under certain conditions . Type ` license () ' or ` licence () ' for distribution details . R is a collaborative project with many contributors . Type ` contributors () ' for more information . Type ` demo () ' for some demos , ` help () ' for on - line help , or ` help . start () ' for a HTML browser interface to help . Type `q () ' to quit R . > options ( STERM = ' iESS ' , editor = ' emacslient ') > Am Anfang jeder Eingabezeile steht standardmäßig das ’>’-Zeichen; jede Eingabe in der Befehlszeile muß durch [return] abgeschlossen werden. Mit 146 KAPITEL 6. R > ? befehl bekommen Sie Hilfe zum Kommando befehl. Probieren Sie einmal > ? quit oder > ?q Mit > quit () oder > q () können Sie also R beenden. Die Klammern müssen Sie setzten, da q eine Funktion (von eventuell einigen Variablen) ist. Der Aufruf von > q bewirkt die Ausgabe der Funktion selber. 6.3 Arithmetik mit R R kann zur Berechnung einfacher Ausdrücke verwendet werden, z.B. bringt die Eingabe von > 1+1 das Ergebnis 6.3. ARITHMETIK MIT R 147 [1] 2 Probieren Sie z.B. > 3 / 2+1 [1] 2.5 oder auch Audrücke mit Wurzel, Quadrat, Logarithmus: > log (3) [1] 1.098612 > sqrt (16) [1] 4 Frage: welcher Logarithmus wird angewandt? Zur Basis 10 oder der natürliche? Wenn Sie [return] drücken, bevor die Eingabe richtig abgeschlossen wurde (etwa, bevor die Klammer wieder geschlossen wurde), dann wartet R darauf, daß Sie die Eingabe ordentlich beenden: anstelle des >-Zeichens steht ein +-Zeichen. > log (3 + ) [1] 1.098612 R kann natürlich nicht bloß einen Taschenrechner ersetzen, sondern ist ein System zur Datenanalyse. Daten können auf unterschiedliche Weise eingelesen, aber auch einfach in R erzeugt werden. 148 6.4 KAPITEL 6. R Vektoren Durch > x <- 3 wird der Variablen x der Wert 3 zugewiesen. Dabei wird der Wert nicht ausgegeben: das ist in R immer so bei Zuweisungen. Durch Eingabe ihres Namens erhalten wir dann den Wert zurück: > x [1] 3 Wir erzeugen nun einen Datenvektor y: > y <- c (10 , 11 , 13 ,14 ,17 ,17 ,20) und erhalten folgende Ausgabe: > y [1] 10 11 13 14 17 17 20 Der Befehl c (für concatenate) verbindet die durch Kommata getrennten Elemente zu einem Datenvektor. Der Variablen y wird also der Vektor (10, 11, 13,14,17,17,20) zugewiesen. Um eine Sequenz ganzer Zahlen zwischen zwei Werten zu erzeugen, wird ein Doppelpunkt verwendet; man kann sowohl auf- als auch abstiegende Sequenzen erzeugen: > z1 <- 1:10 > z1 6.4. VEKTOREN [1] 1 2 3 4 149 5 6 7 8 9 10 > z2 <- 100:1 > z2 [1] 100 [14] 87 [27] 74 [40] 61 [53] 48 [66] 35 [79] 22 [92] 9 99 86 73 60 47 34 21 8 98 85 72 59 46 33 20 7 97 84 71 58 45 32 19 6 96 83 70 57 44 31 18 5 95 82 69 56 43 30 17 4 94 81 68 55 42 29 16 3 93 80 67 54 41 28 15 2 92 79 66 53 40 27 14 1 91 78 65 52 39 26 13 90 77 64 51 38 25 12 89 76 63 50 37 24 11 88 75 62 49 36 23 10 Die Zahlen in eckigen Klammern sagen uns, wie weit im Vektor ” wir sind“. [19] sagt uns also, daß der Wert 82 an 19-ter Stelle im Vektor w steht. Eine weitere nützliche Funktion zum Erzeugen von Vektoren ist die rep()-Funktion. Sie erzeugt einen Vektor, bei dem das erste Element der Funktion so oft wiederholt wird, wie im zweiten Element angegeben worden ist: > # part -1 > u <- rep (2 ,9) > u [1] 2 2 2 2 2 2 2 2 2 oder auch: > v <-c ( rep (0 ,10) , rep (1 ,5)) > v [1] 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 150 KAPITEL 6. R Außerdem kann die scan-Funktion zum Einlesen über die Tastatur verwendet werden. Dazu müssen Sie lediglich scan() eingeben, Sie können dann so viele, durch Enter bestätigte Werte eingeben, wie Sie wollen. Indem Sie einmal zusätzlich Enter drücken, beenden Sie die Eingabe. > zahlen<-scan() 1: 3 2: 4 3: 2 4: 6 5: 7 6: 8 7: 2 8: 3 9: 3 10: 6 11: 7 12: 8 13: 8 14: 4 15: 0 16: 1 17: Read 16 items > zahlen [1] 3 4 2 6 7 8 2 3 3 6 7 8 8 4 0 1 Zugriff auf einzelne Werte eines Vektors Auf die Elemente des Vektors kann auch einzeln zugegriffen werden: > y <- c (10 , 11 , 13 ,14 ,17 ,17 ,20) > y 6.4. VEKTOREN 151 [1] 10 11 13 14 17 17 20 > y [4] [1] 14 > y [2:5] [1] 11 13 14 17 > y [ -3] [1] 10 11 14 17 17 20 So kann man sich die Werte des Vektors y ausgeben lassen, die größer 11 sind: > y [y >11] [1] 13 14 17 17 20 Versuchen Sie weitere Abfragen! Auch Vektoren mit logischen Elementen können durch eine Abfrage erzeugt werden, z.B.: > wahr <- y > 14 > wahr [1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE 152 KAPITEL 6. R Genauso funktionieren ’UND’- und ’ODER’-Operationen: > y > 2 & y < 7 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE > y < 2 | y > 7 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE Einfache arithmetische Berechnungen werden pro Element des Vektors angewandt, so z.B.: > y <- 1:10 > y +3 [1] 4 5 6 7 8 9 10 11 12 13 > y/2 [1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 > sqrt ( y ) [1] 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490 [7] 2.645751 2.828427 3.000000 3.162278 6.5. MATRIZEN 6.5 153 Matrizen Es gibt verschiedene Möglichkeiten, eine Matrix zu konstruieren. Der Befehl matrix() wandelt einen Vektor in eine Matrix um: > y <- 1:12 > ymat <- matrix (y , ncol =3) > ymat [1 ,] [2 ,] [3 ,] [4 ,] [ ,1] [ ,2] [ ,3] 1 5 9 2 6 10 3 7 11 4 8 12 Wir müssen also angeben, welcher Vektor umgewandelt werden soll, und aus wievielen Spalten die Matrix bestehen soll. Standardmäßig wird die Matrix spaltenweise aufgefüllt. Das zeilenweise Auffüllen geschieht so: > y2mat <- matrix (y , ncol =3 , byrow = T ) > y2mat [1 ,] [2 ,] [3 ,] [4 ,] [ ,1] [ ,2] [ ,3] 1 2 3 4 5 6 7 8 9 10 11 12 Zugriff auf einzelne Werte einer Matrix Auf die einzelnen Zeilen bzw. Spalten einer Matrix kann analog wie bei den Vekoren zugegriffen werden. Beispiele: Es soll das Element 1. Zeile, 3.Spalte ausgegeben werden: 154 KAPITEL 6. R > y2mat [1 ,3] [1] 3 Es soll die erste Zeile der Matrix ausgegeben werden: > y2mat [1 ,] [1] 1 2 3 Die dritte Spalte der Matrix soll ausgegeben werden: > y2mat [ ,3] [1] 3 6 9 12 Wie Sie sehen, wird diese allerdings nicht als Spalten-, sondern als Zeilenvektor ausgegeben. Wir wollen mehrere Zeilen ausgeben lassen: > y2mat [ c (1 ,4) ,] [1 ,] [2 ,] [ ,1] [ ,2] [ ,3] 1 2 3 10 11 12 Matrizenrechnung erfolgt in R so: Elementeweises Addieren: > y2mat +3 6.5. MATRIZEN [1 ,] [2 ,] [3 ,] [4 ,] 155 [ ,1] [ ,2] [ ,3] 4 5 6 7 8 9 10 11 12 13 14 15 > y2mat - 4 [1 ,] [2 ,] [3 ,] [4 ,] [ ,1] [ ,2] [ ,3] -3 -2 -1 0 1 2 3 4 5 6 7 8 Elementeweises Subtrahieren, Dividieren und Multiplizieren erfolgt genau so. Es können auch zwei Matrizen gleicher Dimension elementweise addiert, subtrahiert, dividiert, multipliziert oder potenziert werden: > mat1 <- matrix ( c (2 ,3 ,6 ,4 ,2 ,8) , 2 ,3) > mat1 [1 ,] [2 ,] [ ,1] [ ,2] [ ,3] 2 6 2 3 4 8 > mat2 <- matrix ( c (9 ,6 ,7 ,2 ,3 ,4) , 2 ,3) > mat2 [1 ,] [2 ,] [ ,1] [ ,2] [ ,3] 9 7 3 6 2 4 156 KAPITEL 6. R > mat2 - mat1 [1 ,] [2 ,] [ ,1] [ ,2] [ ,3] 7 1 1 3 -2 -4 Die Dimension einer Matrix wird mit der Funktion dim() ermittelt: > dim ( mat1 ) [1] 2 3 Richtige“ Matrix-Multiplikation funktioniert so: ” > mat1 % * % t ( mat2 ) [1 ,] [2 ,] [ ,1] [ ,2] 66 32 79 58 > t ( mat1 ) % * % mat2 [1 ,] [2 ,] [3 ,] [ ,1] [ ,2] [ ,3] 36 20 18 78 50 34 66 30 38 Bei der Matrizenmultiplikation müssen Spaltenzahl der ersten Matrix und Zeilenzahl der zweiten Matrix übereinstimmen. Die Funktion t() transponiert Matrizen. Invertierung quadratischer Matrizen mit vollem Rang (regulärer Matrizen) erfolgt mittels der Funktion solve(): 6.5. MATRIZEN 157 > mat3 <- matrix ( c (2 ,0 ,0 ,2) ,2 ,2) > mat3 [1 ,] [2 ,] [ ,1] [ ,2] 2 0 0 2 > mat3inv <- solve ( mat3 ) > mat3inv [1 ,] [2 ,] [ ,1] [ ,2] 0.5 0.0 0.0 0.5 Probe: > mat3 % * % mat3inv [1 ,] [2 ,] [ ,1] [ ,2] 1 0 0 1 > mat3inv % * % mat3 [1 ,] [2 ,] [ ,1] [ ,2] 1 0 0 1 cbind() und rbind() erlauben es, zusätzliche Spalten bzw. Zeilen an eine existierende Matrix anzufügen. > x . mat <- matrix (10:1 , ncol =2) > x . mat 158 [1 ,] [2 ,] [3 ,] [4 ,] [5 ,] KAPITEL 6. R [ ,1] [ ,2] 10 5 9 4 8 3 7 2 6 1 > y . mat <- cbind ( x . mat ,1:5) > y . mat [1 ,] [2 ,] [3 ,] [4 ,] [5 ,] [ ,1] [ ,2] [ ,3] 10 5 1 9 4 2 8 3 3 7 2 4 6 1 5 > z . mat <- rbind ( y . mat , c (99 ,99 ,99)) > z . mat [1 ,] [2 ,] [3 ,] [4 ,] [5 ,] [6 ,] [ ,1] [ ,2] [ ,3] 10 5 1 9 4 2 8 3 3 7 2 4 6 1 5 99 99 99 Ein Wert in der Matrix kann verändert werden, indem ihm einfach ein neuer Wert zugewiesen wird; ebenso kann auch eine ganze Zeile bzw. Spalte ausgetauscht werden: > z . mat [6 ,3] <-0 > z . mat 6.6. LISTEN UND DATAFRAMES [1 ,] [2 ,] [3 ,] [4 ,] [5 ,] [6 ,] 159 [ ,1] [ ,2] [ ,3] 10 5 1 9 4 2 8 3 3 7 2 4 6 1 5 99 99 0 > z . mat [6 ,] <-c (2 ,11 ,44) > z . mat [1 ,] [2 ,] [3 ,] [4 ,] [5 ,] [6 ,] [ ,1] [ ,2] [ ,3] 10 5 1 9 4 2 8 3 3 7 2 4 6 1 5 2 11 44 > z . mat [ ,3] <- rep (1.7 ,6) > z . mat [1 ,] [2 ,] [3 ,] [4 ,] [5 ,] [6 ,] 6.6 [ ,1] [ ,2] [ ,3] 10 5 1.7 9 4 1.7 8 3 1.7 7 2 1.7 6 1 1.7 2 11 1.7 Listen und dataframes Im Gegensatz zu Vektoren können Listen Elemente unterschiedlichen Typs aufnehmen, Sie werden mit dem list() Befehl erzeugt: 160 KAPITEL 6. R > mylist <- list ( c (1 ,2 ,3 ,4) , el2 = " ein text " , m = matrix ( c (1 ,2 ,3 ,4 ,2 ,2) > mylist [[1]] [1] 1 2 3 4 $ el2 [1] " ein text " $m [1 ,] [2 ,] [3 ,] [4 ,] [5 ,] [6 ,] [ ,1] 1 2 3 4 2 2 Die Elemente von Listen können benannt werden und dann mittels dem $ Operator auf sie zugegriffen werden, ansonsten muss der Listenelementindex in doppelten eckigen Klammern verwendet werden: > mylist $ el2 [1] " ein text " > mylist [[1]] [1] 1 2 3 4 Die Elemente von Listen sind i.A. nicht nur von unterschiedlichem Typ sondern auch unterschiedlich lang. Schränkt man die Listenelemente auf Vektoren unterschiedlichen Typs gleicher Länge ein (das entspricht einer Tabelle mit Spalten gleicher Länge deren Spalten jeweils einheitliche Datentypen enthalten) so gelangt man zum sog. dataframe, die Spaltenbezeichnung und der Spaltenzugriff erfolgt wie bei den Elementen von Listen: 6.7. EINLESEN EXTERNER DATEN 161 > df <- data . frame ( Sp1 = c (1 ,2 ,3) , Sp2 = c ( " a " ," b " ," a " ) , Sp3 = c (1.2 ,3.4 ,4.5)) > df 1 2 3 Sp1 Sp2 Sp3 1 a 1.2 2 b 3.4 3 a 4.5 > df $ Sp1 [1] 1 2 3 Die Funktionen as.data.frame und as.matrix wandlen solche Tabellen zwischen Matrizen- und dataframe-Typ um. 6.7 6.7.1 Einlesen externer Daten Verwenden der scan-Funktion Erste Möglichkeit: Verwenden der scan-Funktion, z.B. für ein txtFile (im selben Verzeichnis gespeichert, in dem auch das .RDataVerzeichnis ist) in dem nur Zahlen, getrennt durch Leerzeichen, stehen: > x <- scan ( " file1 . txt " ) > x [1] [12] 1 22 1908 11 1293 482 33 4829 1112 483 2883 95 990 3848 31 31 89 Wenn die Zahlen etwa durch Kommata getrennt sind, muß diese Information von Ihnen angegeben werden: 162 KAPITEL 6. R > y <- scan ( " file2 . txt " , sep = " ," ) > y [1] 32 45 11 21 41 67 88 96 96 57 44 25 52 16 77 Weiter Informationen erhalten Sie wieder mit > ?scan 6.7.2 Verwenden der read.table-Funktion Weitere Möglichkeit: Verwenden der read.table-Funktion, die das Einlesen von Daten in Tabellenform ermöglicht. Das File sollte so gespeichert sein, dass in den Spalten die Variablen stehen und die Zeilen den einzelnen Fällen entsprechen. Wenn in der Kopfzeile die Variablennamen stehen, muß dies beim Einlesen angegeben werden, da sonst die Kopfzeile als erste Datenzeile interpretiert wird. Rückgabewert der Funktion ist ein dataframe, der Datentyp der Spalten richtet sich dabei nachderen Inhalt im File, d.h. sollte in einer ansonsten mit Zahlen gefüllten Spalte ein Text stehen, wird die ganze Spalte als Text aufgefasst werden. Beispiele: • Das File file3.txt besteht aus einer Kopfzeile mit den Variablennamen und aus fünf Datensätzen. Es wird folgend eingelesen und unter dem Namen file3 gespeichert: > file3 <- read . table ( " file3 . txt " , header = T ) > file3 1 2 Laenge Breite Hoehe 12 2 3 13 5 6 6.7. EINLESEN EXTERNER DATEN 3 4 5 23 10 8 20 9 3 163 20 9 4 • Bei einer Umfrage (13. Mai 2003, Umfrage von Studierenden des Kurses Stochastik II) an der Universität wurden an Studiere folgende Fragen gestellt: – Was studierst du? – In welchem Semester befindest du dich? – Wie alt bist du? – Hast du vor, zur ÖH-Wahl zu gehen? Das Ergebnis dieser Umfrage ist im Datensatz fragebogen enthalten. Dabei wurde aus der Frage: “Was studierst du?” die Zugehörigkeit zu einer der beiden Fakultäten abgeleitet (w: WiINFO, k: KUWI), als antwort auf die Frage “Hast du vor, zur ÖH-Wahl zu gehen?” konnte mit “ja” (j)), “vielleicht” (v) oder “nein” (n) geantwortet werden. Einlesen des Fragebogens “Fragebogen” > fragebogen <- read . table ( " Fragebogen . txt " , header =T , sep = " ; " ) > fragebogen 1 2 3 4 5 6 7 8 9 10 Geschlecht Fakultaet Semester Alter OeH . Wahl w w 4 20 n w w 6 25 j m k 2 21 j w w 8 25 n w w 6 23 v m w 6 23 j m w 10 23 n w w 8 24 j w k 4 20 v w k 3 20 n 164 KAPITEL 6. R 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 w w w w m w w w m m w m m w w m w m w w m m w m w w w w w w w w w w w w w m m w k k k k w w k k w w k k k w w w w w w k w w w w w w w w k k k k k k k k k k k k 3 3 1 3 4 4 10 2 10 10 NA 7 6 4 8 2 2 2 2 6 4 4 4 4 2 2 2 2 2 1 3 4 4 4 4 4 4 4 6 4 20 23 21 20 22 20 27 21 26 25 36 25 22 21 23 19 21 25 19 21 22 21 20 20 19 19 20 20 20 22 19 23 22 20 21 21 20 22 23 20 v v n n j v j j j j j j j n v n v v v n v v j n n v n j v v j j n n n n n j j j 6.7. EINLESEN EXTERNER DATEN 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 w w w w m m m w w w w w w m w w w w m w w w w w w w w w w m m w m m w w w m w w k k k k w w w w w k w w w w w w w w k k k k k k k k k k w w w w w w w k k k k 165 4 6 4 6 4 6 6 8 8 6 4 2 2 2 4 4 10 2 4 8 2 2 2 2 2 2 1 2 2 7 6 6 4 2 2 2 4 4 4 4 21 22 22 22 22 23 23 23 22 31 22 20 21 20 21 19 23 19 22 22 19 20 20 20 20 28 26 21 20 29 24 21 22 21 20 21 21 28 21 20 v j j v n j j v v j n n n n n n v v v j v v n n j j n n v j j j n j n n n n n n 166 KAPITEL 6. R 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 6.7.3 m w w m w w w m m w w w w w w m m w m m w w w m m m m w m m m m w k w w k k w w w k w k w w w k w k k k w w w k w w w k k w w w 4 5 2 1 2 2 4 4 4 4 6 4 4 4 2 10 4 2 14 10 2 8 12 8 12 4 2 4 4 4 16 7 22 22 20 20 20 20 21 27 22 20 22 19 20 19 26 26 25 19 24 26 18 22 25 25 40 21 21 22 36 21 27 22 j n j j j j n n j v v v n n j n n v j n j j j j j j j v j j j j Laden von Daten aus anderen R-Paketen In R sind einige Funktionen und Datensätze enthalten, einige mehr sind als sogenannte Standard-Pakete (Base-Packages) vor ihrer Ver- 6.7. EINLESEN EXTERNER DATEN 167 wendung in R zu laden, und eine ständig wachsende Zahl von Paketen zu speziellen Problemen sind über das Netz zu holen, lokal zu speichern und in R zu laden (Add-On-Packages). Mit dem Aufruf von library() erhalten Sie die Liste aller in R enthaltenen Pakete, mit help(package= name.des.pakets) oder library(help= name.des.pakets) bekommen Sie Informationen zum gewünschten Paket und eine Auflistung aller enthaltenen Funktionen. Wollen Sie nun z.B.das Paket MASS verwenden, so müssen Sie es mit > library ( MASS ) verfügbar machen. Der in diesem Paket enthaltene Datensatz hills wird mit > data ( hills ) geladen. Mit > help ( package = MASS ) bekommen Sie Inforamtionen über das Paket. Hilfe zur Installation der Add-On-Packages gibt es auf der Startseite für den Download von Software rund um R: 168 KAPITEL 6. R http://cran.r-project.org/ Dort sind auch Listen der aktuell verfügbaren Pakete abfragbar. Zu einzelnen Themengebieten gibt es sogenannte Taskviews, dort werden Pakete vorgestellt die Funktionen zu dem jeweiligen Thema anbieten. Ein Paket dass z.B. eine Art grafischer Oberfläche implementiert, ist der R Commander, der mittels > library ( Rcmdr ) geladen wird. Beim ersten Start nach der Installation versucht dieser gleich noch eine gewisse Teilmenge häufig benutzter Pakete nachzuinstallieren. Anschließend ist ein Dataframe zur “aktiven Datenmatrix” zu erklären und dann können in der Menüstruktur vom R Commander passende statistische Methoden und Plots ausgewählt und deren Parameter spezifiziert werden. 6.8 6.8.1 Datenanalyse mit R Einfache Grafiken Graphiken erlauben meist einen raschen Überblick über die Daten und einen schnellen optischen Größenvergleich zwischen einzelnen Werten. Globale Muster können manchmal mit einem Blick erfaßt werden, was in Tabellen kaum möglich ist. Allerdings sind Graphiken etwas aufwendiger zu erstellen, sie erfordern auch meist mehr Platz. Trotzdem ist ein gewisser Informationsverlust unvermeidlich. Darüberhinaus sind Graphiken auch anfälliger gegen Fehlinterpretationen und Manipulationen. 6.8. DATENANALYSE MIT R 6.8.1.1 169 Balken- oder Stabdiagramme Das Balken- oder Stabdiagramm eignet sich zur Abbildung von Größenverhältnissen kategorialer oder diskreter Merkmale, wenn die Anzahl K der verschiedenen Merkmalsausprägungen nicht zu groß ist. Beim Stabdiagramm wird die Häufigkeit der einzelnen Merkmale als Strecke oder Stab dargestellt. Wird zu jedem Stab der zugehörige Meßwert dazugeschrieben, dann wird sowohl die skalierte Achse wie auch die gesonderte Angabe der Tabelle der Werte überflüssig. Auf einer der beiden Achsen werden die Variablenwerte aufgetragen, wobei die Reihenfolge beliebig ist; oft werden die Merkmale nach ihrer Häufigkeit geordnet oder nach anderen, sinnvoll erscheinenden Kriterien (bei der Schulbildung z.B. aufsteigend von Hauptschulabschluß bis Hochschulabschluß). Es ist darauf zu achten, daß die Abstände zwischen den Werten gleich breit gezeichnet werden. Auf der zweiten Achse werden die absoluten oder die relativen Häufigkeiten für die Stabhöhen abgetragen, d.h. die Stablänge veranschaulicht die absolute (bzw. relative) Häufigkeit. Wichtig: beim Balkendiagramm berühren einander die Balken (desselben Merkmals) nicht und die Stäbe sind gleich breit zu zeichnen! Weiters ist beim Balkendiagramm zu beachten, daß eindimensionale Balken verwendet werden sollen, da zweidimensionale Balken die Größenverhältnisse verzerren. Da die y-Achse skaliert werden kann, ist die Graphik für absolute und relative Häufigkeiten nicht verschieden. Stabdiagramme werden in R mit dem Befehl barplot() erzeugt. Beispiel 6.8.1 Auf fünf Biobauernhöfen wurden zum Stichtag 31.12.1999 der Tierbestand aufgenommen. Auf dem Biohof B1 wurden folgende Tiere gezählt: 170 KAPITEL 6. R Tiere Anzahl Rinder 20 Schweine 25 Schafe 11 Ziegen 3 Ein Stabdiagramm zu den Biohöfen kann folgend in R erstellt werden (dazu wird der ganze Datensatz eingelesen, aber nur für Bauernhof B1 ein Diagramm erstellt): > tiere <- read . table ( " tiere . txt " , header = T ) > tiere B1 B2 B3 B4 B5 Rinder 20 0 12 6 2 Schweine 25 34 3 28 19 Schafe 11 29 23 3 5 Ziegen 3 2 0 0 20 > tiere $ B1 [1] 20 25 11 3 > barplot ( tiere $ B1 , col = c ( " red " , " green " , + " blue " , " yellow " )) und ergibt Abbildung 6.1. Die Erzeugung eines Postscriptfiles erfolgt mittels > > + > postscript ( " stabdiagramm1 . eps " , width = 7 , height = 7 , horizontal = barplot ( tiere $ B1 , col = c ( " red " , " green " , " blue " , " yellow " )) dev . off () pdf 2 171 0 5 10 15 20 25 6.8. DATENANALYSE MIT R Abbildung 6.1: Stabdiagramm der Tiere eines Bauernhofes Bei Balkendiagrammen können auch mehrere Merkmale gemeinsam in einem Diagramm dargestellt werden, dazu wird wieder der Befehl barplot() verwendet, die Option beside= muß auf T gesetzt werden. Beispiel 6.8.2 In der folgenden Tabelle und im Diagramm sind die Tierbestände aller fünf Höfe (vergl. Bsp 6.8.1) wiedergegeben: Bauernhof Rinder Schweine Schafe Ziegen B1 20 25 11 3 B2 0 34 29 2 B3 12 3 23 0 B4 6 28 3 0 B5 2 19 5 20 Abbildung 6.2 zeigt das dazugehörige Stabdiagramm, die Befehle dazu in R lauten: 172 KAPITEL 6. R > tiere1 <- as . matrix ( tiere ) > barplot ( tiere1 , beside =T , col = c ( " red " , " green " ," blue " , + " yellow " ) , legend = row . names ( tiere1 )) 0 5 10 15 20 25 30 Rinder Schweine Schafe Ziegen B1 B2 B3 B4 B5 Abbildung 6.2: Stabdiagramm mit mehreren Merkmalen: Tiere von fünf Bauernhöfen Beispiel 6.8.3 Die Umfrage zur ÖH-Wahl 2003 ergab das in 6.3 veranschaulichte Ergebnis. > > > > > > fragebogen <- read . table ( " Fragebogen . txt " , header =T , sep = " ; " ) ja <- fragebogen [ fragebogen $ OeH . Wahl == " j " ,5] viell <- fragebogen [ fragebogen $ OeH . Wahl == " v " ,5] nein <- fragebogen [ fragebogen $ OeH . Wahl == " n " ,5] auswertung <-c ( length ( ja ) , length ( viell ) , length ( nein )) auswertung [1] 50 29 43 6.8. DATENANALYSE MIT R 173 > # oder kuerzer : > auswertung <- summary ( fragebogen $ OeH . Wahl ) > auswertung j n v 50 43 29 > barplot ( auswertung , names . arg = c ( " ja " , " vielleicht " , " nein " ) , + main = " OeH - Wahl - Umfrage " ) 0 10 20 30 40 50 OeH−Wahl−Umfrage ja vielleicht nein Abbildung 6.3: Ergebnis der Umfrage zur ÖH-Wahl 2003, Uni Klagenfurt Schauen Sie sich die Hilfe zum Befehl barplot an und erzeugen Sie dann unterschiedliche Grafiken zum Datensatz! 174 6.8.1.2 KAPITEL 6. R Kreisdiagramme Das Kreisdiagramm eignet sich – wieder bei nicht zu großer Anzahl von Klassen – recht gut, um die Gesamtaufteilung und den Anteil einzelner Meßwerte an der Gesamtheit zu erkennen. Ein Vergleich zweier Merkmale ist aber schwieriger als beim Stabdiagramm. Außerdem ist die händische Erstellung etwas aufwendiger: zur Darstellung wird der volle Winkel durch Zentriwinkel unterteilt, deren Größen den darzustellenden Meßwerten (meist prozentuelle Anteile) entsprechen. Den Meßwerten entsprechen somit Winkelmaße bzw. die Inhalte der zugehörigen Kreissektoren. Als Faustregel kann gelten: maximal in 5-6 Segmente einteilen (ggf. eine Kategorie Sonstiges“ anlegen). Die ganze Kreisfläche muß im” mer 100% der Daten entsprechen. Kreisdiagramme werden in R mit dem Befehl pie() erzeugt. Bei Eingabe von > tiere <- read . table ( " tiere . txt " , header = T ) > pie ( tiere $ B5 ) erhalten wir die Graphik in Abbildung 6.4. Die Darstellung kann durch Angabe von verschiedenen optionalen Werten verändert werden. Probieren Sie aus, wie ein farbiges Tortendiagramm erstellt werden kann! Achtung: das Tortendiagramm läßt sich nur erstellen, wenn alle Werte echt größer Null sind! Sonst bekommt man eine Fehlermeldung: pie(tiere$B4) Error in pie(tiere$B4) : pie: `x' values must be positive. 6.8. DATENANALYSE MIT R 175 2 1 3 4 Abbildung 6.4: Tortendiagramm, Tiere von Bauernhof Nr. 5 6.8.1.3 Streifendiagramme Das Streifendiagramm hat ähnliche Vorteile wie das Kreisdiagramm, ist aber leichter zu zeichnen und erlaubt, vor allem bei benachbarten Werten, eher einen Größenvergleich als das Kreisdiagramm. Die Merkmalswerte je Variable werden dazu einfach der Reihe nach übereinandergeschichtet. Bei einer gemeinsamen Darstellung mehrere Variablen gibt zwei Varianten des Streifendiagrammes: es werden die Absolutzahlen dargestellt (siehe Bsp. 6.8.4), oder die Prozente je Variablen werden im Block dargestellt. Dadurch kann zwar ein Vergleich zwischen den Variablen vorgenommen werden, aber die Information, aus wie vielen Daten jeweils eine Variable besteht, geht verloren. Streifendiagramme werden in R ebenfalls mit dem Befehl barplot() 176 KAPITEL 6. R erzeugt. Achtung: die Daten müssen als Matrix vorliegen! (Umwandlung mit as.matrix()). Beispiel 6.8.4 Die Tierbestandsdaten aus Bsp. 6.8.1 werden nun als Streifendiagramme dargestellt (siehe Abbildung 6.5). Die Eingabe in R lautet: 60 > tiere <- read . table ( " tiere . txt " , header = T ) > tiere1 <- as . matrix ( tiere ) > barplot ( tiere1 , legend = row . names ( tiere1 ) , + col = c ( " red " , " green " , " blue " , " yellow " )) 0 10 20 30 40 50 Ziegen Schafe Schweine Rinder B1 B2 B3 B4 B5 Abbildung 6.5: Streifendiagramm 6.8.1.4 Liniendiagramme Für die graphische Darstellung von Zeitreihen (diese geben an, wie sich ein bestimmter Untersuchungsgegenstand im Laufe der Zeit ver- 6.8. DATENANALYSE MIT R 177 ändert) eignen sich Stab-, aber auch Liniendiagramme. Diese werden erstellt, indem man zu jedem Beobachtungszeitpunkt (Jahr, Monat etc.) auf der x-Achse den dazugehörigen Wert auf der y-Achse als Punkt einträgt. Benachbarte Punkte werden dann durch Strecken miteinander verbunden. Dadurch soll der Verlauf der Veränderungen optisch verdeutlicht werden. Die Verbindungslinien lassen sich jedoch nur dann sinnvoll interpretieren, wenn zwischen zwei Meßwerten eine gleichmäßige (d.h. lineare) Entwicklung angenommen werden kann. Das Liniendiagramm eignet sich auch zum Vergleich mehrerer Reihen - so kann etwa die Niederschlagsmenge in einem Jahr in verschiedenen Städten in einem Diagramm dargestellt werden. Es ist zu beachten, daß 1. maximal 3 - 4 Linien verwendet werden sollen (sonst geht die Übersichtlichkeit verloren), 2. Linien in verschiedenen Farben oder Schraffuren dargestellt werden sollen, 3. der Nullpunkt eingezeichnet werden muß, 4. keine gesonderte Legende angelegt werden soll, wenn es sich vermeiden läßt. In R wird zur Erzeugung der sehr allgemeine Befehl plot() verwendet, um Liniendiagramme zu erstellen. Dieser Befehl wird im weiteren noch besprochen. Beispiel 6.8.5 Die folgende Tabelle und das dazugehörende Liniendiagramm enthalten die Bevölkerungszahlen der unter 15-jährigen Personen Österreichs für die Jahre 1982 bis 1992 (Quelle: Bevölkerungsfortschreibung auf der Basis der Volkszählung 1981): 178 KAPITEL 6. R Jahr 1982 1477603 1983 1439068 1984 1404723 1985 1378120 1986 1356534 Jahr 1988 1330843 1989 1328966 1990 1343555 1991 1365772 1992 1382203 1987 1339114 Die Daten sind als zwei Vektoren in jahre.txt und bev.txt gespeichert (können von Claroline heruntergeladen werden). Die Erstellung in R erfolgt so: > jahre <- scan ( " jahre . txt " ) > bev <- scan ( " bev . txt " ) > plot ( jahre , bev , type = " o " , + pch =19 , xlab = " Jahre " , ylab = " Bevoelkerung unter 15 Jahren " , + main = " B e v o e l k e r u n g s e n t w i c k l u n g der unter 15 - Jaehrigen " ) Die Option type= erlaubt es, das Aussehen des Plots zu verändern: mit type="l" bekommt man ein Liniendiagramm, bei type=ö" werden sowohl die Beobachtungspunkte als auch Verbindungslinien eingetragen (“overplottet”). Bei Zeitreihen ist es möglich, diese mit der Funktion ts() auch als solche zu kennzeichnen; dadurch hat man mehr Möglichkeiten der Analyse. > zeitreihe <- ts ( bev , start =1982 , end =1992) > zeitreihe Time Series : Start = 1982 End = 1992 Frequency = 1 [1] 1477603 1439068 1404723 1378120 1356534 1339114 1330843 1328966 [10] 1365772 1382203 6.8. DATENANALYSE MIT R 179 Bevoelkerungsentwicklung der unter 15−Jaehrigen 1450000 1400000 ● ● ● ● ● 1350000 Bevoelkerung unter 15 Jahren ● ● ● ● ● 1982 1984 1986 ● 1988 1990 1992 Jahre Abbildung 6.6: Zeitreihe 6.8.1.5 Weitere Graphikfunktionen Grundlegende Funktionen, um Punkte, Linien und Graphen zu zeichen und mit Achsen und Beschriftungen zu versehen, sind: plot(), curve(), lines(), text(), mtext(), axis(), identify(). plot() erlaubt es u.a., zweidimensionale Daten zu plotten, z.B. in Form eines sog. Scatterplots, auch Punktwolke oder Streudiagramm genannt. Durch die Befehle points() und lines() kann man nachträglich Punkte und Linien in die Graphik einfügen. Kurven lassen sich mit curves() zeichnen. Nachstehend finden Sie einige Beispiele zu den angeführten Funktionen. > jahre <- scan ( " jahre . txt " ) 180 KAPITEL 6. R > bev <- scan ( " bev . txt " ) > plot ( jahre , bev ) > plot ( bev ~ jahre ) # Streudiagramm # d a ss e lb e in F o r m e l s c h r e i b w e i s e ● 1400000 bev 1450000 ● ● ● ● 1350000 ● ● ● ● ● 1982 1984 1986 1988 ● 1990 1992 jahre Abbildung 6.7: Streudiagramm > x <- (0:40) * pi / 10 > plot (x , sin ( x ) , type = " l " ) > lines (x , cos ( x )) 6.8.2 # Sequenz von 0 bis 4 * pi # Sinusfunktion # fuegt zweiten Plot dazu Visualisieren der Verteilung der Daten Stamm-Blatt-Diagramme, Histogramme und Boxplots ermöglichen eine Darstellung des Datenmaterials, die der Entdeckung verschiedener Charakteristiken der Daten dient. All diese Darstellungen veranschaulichen die Verteilung der Daten auf unterschiedliche Weise. Daraus ablesbare Eigenschaften sind: 181 0.0 −1.0 −0.5 sin(x) 0.5 1.0 6.8. DATENANALYSE MIT R 0 2 4 6 8 10 12 x Abbildung 6.8: Sinus- und Kosinuskurve - Sind die Daten annähernd symmetrisch verteilt? - Wie groß ist die Spannweite der Daten? - Gibt es Ausreißer in den Daten? - Existieren Datenkonzentrationen (Cluster) um gewisse Werte? - Gibt es Lücken in den Daten? 6.8.2.1 Stamm-Blatt-Diagramme Weitere übliche Bezeichnungen neben Stamm-Blatt-Diagramm“ sind: ” Stengel-Blatt-Diagramm, Stamm-und-Blatt-Plan, stem-and-leaf plot, stem-and-leaf display (SLD). 182 KAPITEL 6. R Das Stamm-Blatt-Diagramm (kurz SLD) erlaubt uns, vorliegende Zahlen graphisch derart zu organisieren, daß unsere Aufmerksamkeit auf verschiedene Eigenschaften der Daten gelenkt wird. Diese Technik ist gut geeignet, um mehrere Datenmengen miteinander zu vergleichen. Das SLD übernimmt eine Vorsortierung der Daten, es ermöglicht ein schnelles Finden von Kenngrößen wie dem Median oder den Quartilen, und von Verteilungsmustern. Es geht auf ein Buch von Tukey [1970] zurück. Das SLD ist eine halbgraphische Darstellung, da die Datenwerte auch im Diagramm noch ablesbar sind. Das Basisdiagramm Um zu erklären, wie ein einfaches StammBlatt-Diagramm aus den Daten erzeugt wird, sehen wir uns ein Beispiel [Stoyan, 1993] an: Beispiel 6.8.6 Gegeben sind die Korndurchmesser von 30 Steinsalzkörnern in mm, die in der folgenden Tabelle enthalten sind. 3.5 3.0 2.4 3.0 2.1 2.4 3.5 2.9 1.5 2.7 1.8 4.0 3.3 3.0 2.6 3.2 1.8 2.6 2.4 4.0 2.4 2.9 2.6 3.9 2.9 3.5 3.5 1.6 2.3 1.1 Das einfache Stamm-Blatt-Diagramm besteht aus einer vertikalen Linie und Zahlen links der Linie, die die Stämme“ repräsentieren, ” sowie Zahlen rechts vom Stamm (die Blätter“). In unserem Fall ist ” es sinnvoll, die Zahlen an der Stelle des Dezimalpunktes in Stamm bzw. Blatt zu trennen. Der Korndurchmesser 3.5 wird also in 3|5 geteilt. Da nur Korndurchmesser von 1.1 bis 4.0 auftreten, gibt es als Stamm-Werte die Zahlen 1, 2, 3 und 4. Wenn wir uns die Tabelle 6.8. DATENANALYSE MIT R 183 anschauen, sehen wir, daß der Wert 3.5 viermal vorkommt, außerdem haben wir noch die Durchmesser 3.0 (dreimal), 3.2, 3.2 und 3.9 (je einmal) mit einer führenden Drei vor dem Komma. Wir gehen nun so vor, daß wir an den Stamm 3 alle Blätter (in aufsteigender Reihenfolge) schreiben, die zu diesem Stamm gehören, also: 3 | 0002355559 Dasselbe machen wir für die restlichen Zahlen, fügen noch eine Kopfzeile ein, damit die Leserin/der Leser weiß, daß die Einheit 0.1 mm beträgt und erhalten dieses Ergebnis: > sand <- scan ( " sandkorn . txt " ) > sand [1] 3.5 2.4 1.8 3.2 2.4 3.5 3.0 3.5 4.0 1.8 2.9 3.5 2.4 2.9 3.3 2.6 2.6 [20] 1.5 3.0 2.4 3.9 2.3 2.1 2.7 2.6 4.0 2.9 1.1 > stem ( sand , scale =0.5) The 1 | 2 | 3 | 4 | decimal point is at the | 15688 1344446667999 0002355559 00 Bei der Erstellung des Diagramms ist zu beachten, daß keine Lücken im Stamm auftreten dürfen. Gäbe es etwa bei unserem Beispiel keine Korndurchmesser mit 3.x mm, aber Durchmesser mit 4.x mm, dann muß im Stamm trotzdem 3 stehen. Bei mehr als einer Stelle nach dem Komma (wenn der Korndurchmesser etwa auf 100-stel mm genau gemessen worden wäre), hätten wir entweder runden oder die letzte Stelle einfach weglassen müssen. 184 KAPITEL 6. R Das Weglassen der letzten Stelle hat den Vorteil, daß die Zahlen weiterhin identifizierbar sind und daß es leichter durchführbar ist als das Runden. Der Vorteil beim Runden ist, daß die Genauigkeit höher ist: runden zentriert die Messung auf die Mitte des Urlistenintervalls und halbiert den Meßfehler. Ein abgeschnittener Wert von 3.7 bedeutet, daß bei einer zweistelligen Meßgenauigkeit jeder Wert von 3.70 bis unter 3.80 möglich war. Der maximale Fehler beträgt hier also 0.1. Ein gerundeter Wert von 3.7 hingegen bedeutet, daß der Wert vorher mindestens 3.65 und höchstens 3.75 war, der maximale Fehler beim Runden ist also 0.05. Ein SLD wird wertlos, wenn die Ziffern nicht gleich groß sind oder nicht genau übereinandergeschrieben werden. Wenn Sie also ein SLD per Hand erstellen, nehmen Sie am besten kariertes Papier und verwenden Sie für jede Zahl ein Kästchen. Im SLD stehen die Daten der Größe nach geordnet, beginnend mit dem kleinsten Wert am obersten Stamm ganz links bis zum größten Wert am untersten Stamm äußerst rechts. Was passiert bei Aufruf von stem(sand)? Verwenden Sie verschiedene Werte für die Option scale und interpretieren Sie das Ergebnis! 6.8.2.2 Histogramme Im Gegensatz zum SLD ist das Histogramm eine vollgraphische Darstellung, da die Werte hier nicht mehr abgelesen werden können. Gleich wie das SLD vermittelt das Histogramm einen optischen Eindruck von der Häufigkeitsverteilung. Bei der Konstruktion eines Histogrammes wird jede Beobachtung durch die Fläche eines Rechtecks repräsentiert. Innerhalb der Grenzen eines Intervalls werden diese Flächen so aufsummiert, daß die 6.8. DATENANALYSE MIT R 185 gesamte Fläche proportional zur Anzahl der Beobachtungen, die in dieses Intervall fallen, ist (d.h. Fläche = Intervallbreite × totale Höhe). Ein einfaches Histogramm kann aus einem bestehenden SLD durch Kippen nach links um 90◦ und durch Ersetzen der Blätter durch Einheitsquadrate konstruiert werden. Dem Stamm-Blatt-Diagramm von oben entspricht das in Abbildung 6.9 dargestellte Histogramm. R-Code: > sand <- scan ( " sandkorn . txt " ) > hist ( sand , breaks = c (1 ,2 ,3 ,4 ,5) , right =F , freq =T , + main = " Histogramm der S a n d k o r n d u r c h m e s s e r " , + xlab = " S a n d k o r n d u r c h m e s s e r " , ylab = " absolute Haeufigkeit " ) 8 6 4 0 2 absolute Haeufigkeit 10 12 Histogramm der Sandkorndurchmesser 1 2 3 4 5 Sandkorndurchmesser Abbildung 6.9: Histogramm der Sandkorndurchmesser Das Argument breaks gibt die Klassengrenzen an und das Argu- 186 KAPITEL 6. R ment right=F bewirkt, daß die linken Klassengrenzen noch zu den Klassen gehören, das Argument freq=F bewirkt, daß die absoluten Häufigkeiten aufgetragen werden. In Abbildung 6.10 sind die relativen Häufigkeiten auf der y-Achse aufgetragen. R-Code: > sand <- scan ( " sandkorn . txt " ) > hist ( sand , breaks = c (1 ,2 ,3 ,4 ,5) , right =F , freq =F , + main = " Histogramm der S a n d k o r n d u r c h m e s s e r " , + xlab = " S a n d k o r n d u r c h m e s s e r " , ylab = " relative Haeufigkeit " , + ylim = c (0 ,0.5)) 0.3 0.2 0.0 0.1 relative Haeufigkeit 0.4 0.5 Histogramm der Sandkorndurchmesser 1 2 3 4 5 Sandkorndurchmesser Abbildung 6.10: Histogramm der Sandkorndurchmesser Nicht nur die Anzahl der Klassen kann in R variiert werden, auch unterschiedlich breite Klassen können durch Angabe der Klassengrenzen erzeugt werden, allerdings muß dann freq=F gesetzt werden, dh. es können nur die relativen Häufigkeiten und nicht die absoluten aufgetragen werden. 6.8. DATENANALYSE MIT R 187 R-Code: > hist ( sand , breaks = c (1 ,1.5 ,2.6 ,3 ,4.5) , right =F , freq =F , + main = " Histogramm der S a n d k o r n d u r c h m e s s e r " , + xlab = " S a n d k o r n d u r c h m e s s e r " , ylab = " " , + ylim = c (0 ,0.6)) 0.0 0.1 0.2 0.3 0.4 0.5 0.6 Histogramm der Sandkorndurchmesser 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 Sandkorndurchmesser Abbildung 6.11: Histogramm der Sandkorndurchmesser Wird in der Funktion hist das Argument plot=F gesetzt, wird keine Graphik gezeigt, statt dessen wird eine Liste mit den wichtigsten Größen zur Erstellung eines Histogramms - Klassengrenzen, absolute Häufigkeiten der Klasse, Klassenmittelpunkte . . . - erstellt. > hist ( sand , breaks = c (1 ,1.5 ,2.6 ,3 ,4.5) , plot = F ) $ breaks [1] 1.0 1.5 2.6 3.0 4.5 $ counts 188 [1] KAPITEL 6. R 2 12 7 9 $ density [1] 0.1333333 0.3636364 0.5833333 0.2000000 $ mids [1] 1.25 2.05 2.80 3.75 $ xname [1] " sand " $ equidist [1] FALSE attr ( , " class " ) [1] " histogram " 6.8.2.3 Das Boxplot Das Boxplot (auch: Box-and-Whiskers-Plot, Kastenschaubild) ist eine weitere graphische Möglichkeit, um die Häufigkeitsverteilung von Daten sichtbar zu machen. Das einfache Boxplot besteht aus - einer Skala, parallel zu Hauptachse des Boxplots, - einem Rechteck (der Box) von x̃0.25 bis x̃0.75 (im Bild mit Lower Quartile und Upper Quartile bezeichnet), - einem Querstrich in der Höhe des Medians x̃ und Querstrichen auf der Höhe der Extremwerte x1 und xn (Min und Max). - einer Verbindungsstrecke von den Box-Enden zu den Querstrichen der Extremwerte (das sind die Whisker“). ” Das einfache Boxplot ist somit eine Transformation eines FünfZahlenmaßes (Pentagrammes), das z.B. aus dem Minimum x(1) , dem 6.8. DATENANALYSE MIT R 189 Abbildung 6.12: Einfaches Boxplot unteren Quartil Q1 , dem Median x̃, dem oberen Quartil Q3 und dem Maximum x(n) besteht, in ein graphisches Verteilungssymbol. Beispiel 6.8.7 Bei 45 Feuerwehrleuten aus dem Bezirk Murau in der Steiermark wurde das Gewicht in kg erhoben. Die fünf Werte x(1) , Q1 , x̃, Q3 und x(n) sind: 0% 61 25% 72 50% 80 75% 100% 87 102 Daraus wird ein einfaches Boxplot nach obiger Anleitung gebildet: > > > > aimu <- read . table ( " aimu . asc " , header = T ) aimu . M <- aimu [ aimu $ reg == " M " ,] attach ( aimu . M ) quantile ( weight ) 0% 61 25% 72 50% 80 75% 100% 87 102 > boxplot ( aimu . M $ weight , range =0) Das einfache Boxplot bietet keine Möglichkeit, eventuelle Ausreißer zu erkennen, da man nicht feststellen kann, wie weit kleine bzw. KAPITEL 6. R 60 70 80 90 100 190 Abbildung 6.13: Boxplot des Gewichts von 45 Feuerwehrmännern große Beobachtungen von den anderen Beobachtungen entfernt liegen. Deswegen werden meistens Modifikationen des einfachen Boxplots verwendet, bei denen die Länge der Whisker vom interquartilen Abstand IQR abhängig ist. Dazu werden zunächst der untere und der obere cut-off“ bestimmt: ” cu = Q1 − κ · IQR co = Q3 + κ · IQR In der Regel wird κ aus dem Intervall [1, 3] gewählt; die Standardeinstellung bei R ist 1.5. Alle Beobachtungen, die kleiner als der untere bzw. größer als der obere cut-off sind, werden als Ausreißer markiert. Da diese durch die angeführte Formel bestimmten cut-offs selten genau einer Beobachtung entsprechen, werden die Whisker jeweils bis zum nächstgrößeren bzw. -kleineren Beobachtungswert wu 6.8. DATENANALYSE MIT R 191 bzw. wo gezeichnet: wu = wo = min {x(i) : x(i) ≥ cu } i=1,...,n max {x(i) : x(i) ≤ co } i=1,...,n Beispiel 6.8.8 Auf dem Gelände eines Industriestandortes wurden Bodenproben genommen und der Bleigehalt (in ppm) in 20 cm Tiefe gemessen. Das Boxplot dieser Bleimessungen zeigt deutlich, daß die Daten stark linkssteil sind: die natürliche untere Grenze für den Bleigehalt ist 0ppm, nach oben gibt es praktisch keine Grenze (mehr als 100% Blei in der Probe sind allerdings nicht möglich). Es gibt ein paar Ausreißer nach der obigen Definition (alles, was mehr als eineinhalb mal den IQR entfernt von Q3 ist, ist ein Ausreißer). > blei <- scan ( " blei . txt " ) > boxplot ( blei ) Werden zwei oder mehr Datenreihen unterschiedlichen Umfangs miteinander verglichen, so soll die Boxbreite an die jeweilige Anzahl von Beobachtungen je Datensatz angepaßt werden. In R existiert dazu die Option varwidth, die auf T gesetzt werden muß, wenn die Boxen unterschiedlich breit gezeichnet werden sollen. Versuchen Sie, diese Option für das Gewicht der Feuerwehrleute aus Murau und Aichfeld anzuwenden! Interpretieren Sie das Ergebnis! > > > > + aimu <- read . table ( " aimu . asc " , header = T ) aimu . M <- aimu [ aimu $ reg == " M " ,] aimu . A <- aimu [ aimu $ reg == " A " ,] boxplot ( aimu . A $ weight , aimu . M $ weight , varwidth =T , names = c ( " Aichfeld " , " Murau " )) 192 KAPITEL 6. R 3000 4000 ● 0 1000 2000 ● 60 70 80 90 100 Abbildung 6.14: Boxplot der ppm-Werte von Bleimessungen Aichfeld Murau Abbildung 6.15: Vergleich Aichfeld-Murau 6.8. DATENANALYSE MIT R 193 Eigenschaften des Boxplots: - Es ist graphischer“ als das Stamm-Blatt-Diagramm, ” - die Mitte der Verteilung wird betont, - extreme Beobachtungen werden markiert und können leichter identifiziert werden, - der interquartile Abstand (IQR) kann leicht abgelesen werden, - es eignet sich gut zum Vergleich mehrerer Stichproben, - die Schiefe der Verteilung ist leicht zu erkennen. 6.8.3 Zusammenhang zwischen Merkmalen 6.8.3.1 Streudiagramme Wir betrachten hier Daten in der Form von Zahlenpaaren (xi , yi ); i = 1, 2, . . . , n, wobei die beiden Komponenten in den Zahlenpaaren die Werte zweier Merkmale X, Y sind. Beispiele: • Hubraum X, Benzinverbrauch Y • Temperatur X, Ozonkonzentration Y • Dauer der Prüfungsvorbereitung X, Ergebnis Y , • Größe X und Gewicht Y von Personen, • Vitalkapazität in Litern X und Einsekundenkapazität Y • Durchschnittliche Außentemeratur in Grad Celsius X und Gasverbrauch in 1000 Kubikfuß Y . . . 194 KAPITEL 6. R Die graphische Darstellung der Daten im x-y-Koordinatensystem heißt Streudiagramm (scatterplot). Der Punkt M mit den Koordinaten (x̄, ȳ) ist der Mittelpunkt (physikalisch ist es der Schwerpunkt) der Punkte des Streudiagramms. Beispiel 6.8.9 Bei den gemessenen Merkmalen der Feuerwehrleute in Aichfeld (A) und Murau (M) kann man sich überlegen, welche Variablen in einem Zusammenhang stehen. Anleitung zur Erzeugung der Streudiagramme in R: > aimu <- read . table ( " aimu . asc " , header = T ) > plot ( aimu $ vc , aimu $ age , xlab = " Vi tal kapa zita et in ml " , + ylab = " Alter in Jahren " , type = " n " ) > text ( aimu $ vc , aimu $ age , labels = as . character ( aimu $ reg )) > plot ( aimu $ vc , aimu $ fev1 , xlab = " Vi talk apaz ita et in ml " , + ylab = " E i n s e k u n d e n k a p a z i t a e t in ml " , type = " n " ) > text ( aimu $ vc , aimu $ fev1 , labels = as . character ( aimu $ reg )) Die beiden Merkmale Vitalkapazität in ml“ und Alter“ zeigen ” ” anscheinend keinen ausgesprochenen linearen Zusammenhang, während die Merkmale Vitalkapazität in ml“ und Einsekundenkapazität ” ” in ml“ in einem hohen positiven linearen Zusammenhang zu stehen scheinen. 6.8.3.2 Korrelation zwischen zwei Merkmalen Die Stärke des linearen Zusammenhanges zweier Merkmale kann mittels des Korrelationskoeffizienten nach Bravais-Pearson gemessen werden: n P xi yi − n · x̄ȳ i=1 rxy = s n n P P 2 2 2 2 xi − n · x̄ yi − n · ȳ i=1 i=1 6.8. DATENANALYSE MIT R 195 50 A M A A A M MM M A 40 A M AM A MA M M A A M M M M 30 Alter in Jahren M MM M M A M M M M A M M M A M A M A 20 M M AA A MM M M A 400 AA A 500 M M M A M A A A A AA A A AA M M M M MM 600 700 Vitalkapazitaet in ml Abbildung 6.16: Streudiagramm Vitalkapazität gegen Alter Es gilt: −1 ≤ rxy ≤ +1; rxy = −1 entspricht einer perfekten linearen negativen, rxy = +1 einer perfekten positiven Korrelation, rxy = 0 bedeutet, daß keine (lineare) Korrelation existiert. Beispiel 6.8.10 Der bereits im Streudiagramm festgestellte lineare Zusammenhang zwischen Vitalkapazität in Liter“ und Einsekun” ” denkapazität in Liter“ wird durch den hohen Wert des Korrelationskoeffizienten bestätigt: > aimu <- read . table ( " aimu . asc " , header = T ) > cor ( aimu $ vc , aimu $ fev1 ) [1] 0.8336283 Der Korrelationskoeffizient der Merkmale Vitalkapazität in Liter“ ” und Alter“ dagegen ist sehr klein: ” 196 KAPITEL 6. R 600 M 550 MA M MM 450 500 A MM M M M AM M M A A M A AM AA M AA A AA A MM M MMM M AM A AM M A M AA MM MM M M A M AM M MM AA M AA A M M MA A 400 350 Einsekundenkapazitaet in ml M AA M A 400 A M 500 600 700 Vitalkapazitaet in ml Abbildung 6.17: Streudiagramm Vitalkapazität gegen Einsekundenkapazität 6.8. DATENANALYSE MIT R 197 > aimu <- read . table ( " aimu . asc " , header = T ) > cor ( aimu $ vc , aimu $ age ) [1] -0.2914085 Wenn, wie im obigen Beispiel, ein linearer Zusammenhang zwischen zwei assoziierten Variablen X und Y vermutet wird, dann soll die ideale“ Gerade gesucht werden, die die Beziehung zwischen den ” beiden Merkmalen am besten widerspiegelt. Dies wird im nächsten Kapitel beschrieben. 6.8.4 Lineare Regression - Methode der kleinsten Quadrate Die Lineare Regression ist ein Werkzeug, um den Wert einer Variablen durch den Wert von anderen, in Beziehung stehenden Variablen zu erklären oder vorherzusagen. Das gebräuchlichste Anpassungsprinzip ist die Methode der kleinsten Quadrate (MKQ, least squares method): Modellvorstellung: yi = |{z} Meßwert a + b · x + ei ; | {z }i |{z} Modellwert Fehler i = 1, 2, . . . , n Die Modellparameter a und b werden so geschätzt, daß n X i=1 e2i = n X (yi − a − bxi )2 → Min i=1 | {z f (a,b) } Die Minimierung erfolgt über a und b, es wird also die Summe der Abweichungsquadrate minimiert. 198 KAPITEL 6. R Die hier angeführte Konstruktion beruht auf der Annahme, daß das Merkmal X das unabhängige und Y das abhängige Merkmal ist. Eine notwendige Bedingung für die Existenz eines Extremwertes ist das Verschwinden der beiden partiellen Ableitungen nach a und b: ∂f (a,b) ∂a =0 und ∂f (a,b) ∂b = 0. Nach Ausführen der partiellen Differentation, Einsetzen in die obigen Gleichungen und Ausführen der Summation erhält man ein Gleichungssystem für a und b, die Normalgleichungen des Regressionsproblems mit den Lösungen Pn (x − x̄)(yi − ȳ) i=1 Pn i bLS = 2 i=1 (xi − x̄) aLS mit x̄ = 1 n P xi und ȳ − bLS · x̄ P ȳ = n1 yi . = Damit ergibt sich die nach der Methode der kleinsten Quadrate geschätzte onRegressionsgerade (LS-Gerade): yLS (x) = aLS + bLS · x In in R kann die Geradenanpassung durch Aufruf von lsfit(x,y) berechnet werden. Mittels abline wird die Gerade in das Streudiagramm eingetragen: > > + > > > aimu <- read . table ( " aimu . asc " , header = T ) plot ( aimu $ vc , aimu $ fev1 , xlab = " Vi talk apaz ita et in ml " , ylab = " E i n s e k u n d e n k a p a z i t a e t in ml " , type = " n " ) text ( aimu $ vc , aimu $ fev1 , labels = as . character ( aimu $ reg )) aimu . vc . fev1 . fit <- lsfit ( aimu $ vc , aimu $ fev1 ) abline ( aimu . vc . fev1 . fit ) 6.9. PROGRAMMIEREN MIT R 199 Wenn Sie nun aimu.vc.fev1.fit eingeben, bekommen Sie einige weitere Details zur Anpassung ausgegeben. M M 550 MM A MM MA 450 500 M M M AM M M A A M A AM AA M AA A AA A MM M MMM M AM A AM M A M AA MM MM M M A M AM M MM AA M AA A M M MA A 400 350 Einsekundenkapazitaet in ml 600 M AA M A 400 A M 500 600 700 Vitalkapazitaet in ml Abbildung 6.18: Regressionsgerade nach Methode der kleinsten Quadrate Als allgemeine Funktionsklasse existiert in R der Befehl lm (Linear Models), der die Funktion lm.fit aufruft. 6.9 Programmieren mit R 6.9.1 Steueranweisungen und Funktionen in R 6.9.1.1 Bedingte Ausführung: if R bietet die Möglichkeit einer bedingten Konstruktion in der Form if ( condition ) expression1 else expression2 200 KAPITEL 6. R wobei condition als Ergebnis einen logischen Wert haben muß und das else-Statement optional ist. Die Ausdrücke expression1 und expression2 können entweder einzelne oder Sammlungen mehrerer R-Ausdrücke sein; im zweiten Fall müssen diese in geschwungene Klammern gesetzt werden. Beispiel: Wir wollen einer Variablen xabs den Absolutbetrag einer Zahl x zuweisen, von der wir nicht wissen,ob sie positiv oder negativ ist:; > x <- -453 > if ( x > 0 ) xabs = x else xabs = -x > xabs [1] 453 6.9.1.2 Wiederholte Ausführung: for-Schleifen for-Schleifen haben die Form for ( name in liste ) expr Die folgende Anweisung erhöht die ersten 10 Stellen des Vektors vec um den Wert 3. > vec <-c (12 , 3 , 4 , 5 , 66 , 9 , 6 , 4 , 3 , 2 , 1) > length ( vec ) [1] 11 > for ( i in 1:10) vec [ i ] <- vec [ i ] + 3 > vec 6.9. PROGRAMMIEREN MIT R [1] 15 6 7 8 69 12 9 7 201 6 5 1 expr kann auch aus mehreren Anweisungen bestehen, diese müssen dann in geschwungenen Klammern stehen und werden durch Semikolen oder Zeilenumbrüche getrennt. Da die meisten Funktionen in R Vektoren als Argument zulassen, können Schleifen in R oft vermieden werden. Beide nachfolgenden Beispiele liefern dasselbe Ergebnis (Umrechnung der Temperatur von Fahrenheit in Celsius): Mit Schleife: > for ( fahrenheit in 77:86) print (5 / 9 * ( fahrenheit -32)) [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] 25 25.55556 26.11111 26.66667 27.22222 27.77778 28.33333 28.88889 29.44444 30 Ohne Schleife: > fahrenheit <- 77:86 > print (5 / 9 * ( fahrenheit -32)) [1] 25.00000 25.55556 26.11111 26.66667 27.22222 27.77778 28.33333 28.88 [9] 29.44444 30.00000 Weitere Befehle zur Konstruktion von Schleifen sind: while, break und repeat. 202 6.9.1.3 KAPITEL 6. R Einige eingebaute Funktionen print() summary() length() dim() sum() prod() min() max() mean() median() var() sd() IQR() quantile() sort() order() Übung: Was tun diese Funktionen? 6.9.1.4 Definieren einfacher Funktionen Funktionen können in R recht einfach selbst definiert werden: man muß dem Funktionsnamen einfach Anordnungen, die in geschweiften Klammern stehen müssen und Returns getrennt sind, zuweisen. Von einer Funktion wird immer der Wert des letzten Ausdrucks im Funktionskörper zurückgegeben. Wenn mehr als ein einzelner Ausdruck berechnet und ausgegeben werden soll, muß dies in der Funktion angegeben werden. Bsp: Umrechnung der Temperatur von Fahrenheit nach Celsius: 6.9. PROGRAMMIEREN MIT R 203 > fahrenheit . nach . celsius <- function ( fahrenheit ) 5 / 9 * ( fahrenheit -32) > fahrenheit . nach . celsius (0) [1] -17.77778 Die folgende Funktion berechnet den Median und den Interquartilabstand einer Stichprobe. Bei Aufruf der Funktion ohne Argument wird die Funktion auf den Vektor 1:10 angewandt. med . u . iqr <- function ( x =1:10) { md <- median ( x ) iqr <- IQR ( x ) c ( Median = md , I n t e r q u a r t i l a b s t a n d = iqr ) } > med . u . iqr () Median I n t e r q u a r t i l a b s t a n d 5.5 4.5 > stichprobe <- c (1 ,4 ,1 ,3 ,2 ,8 ,8 ,6 ,3 ,6 ,2 ,2 ,4) > med . u . iqr ( stichprobe ) Median I n t e r q u a r t i l a b s t a n d 3 4 6.9.2 Funktionen erstellen und editieren Werden immer wieder die selben Abfragen oder Berechnungen benötigt, kann man hierzu eigene Funktionen schreiben. Am einfachsten läßt sich dies im Emacs abwickeln, in dem auch eine R Session 204 KAPITEL 6. R läuft. Dazu klicken Sie in der Kopfleiste auf iESS und weiter auf Edit S Object . In der Fußzeile werden Sie gefragt, welches Objekt editiert werden soll. Wollen Sie eine neue Funktion schreiben, so geben Sie deren gewünschten Namen ein und drücken Return . Im unteren Fenster können Sie nun die Funktion erstellen (siehe ??). Wenn Sie fertig sind, wählen Si im Menü ESS den Punkt Eval and Go oder Eval Buffer . Bei Fehlern in der Funktion wird eine Fehlermeldung in der laufenden R Session ausgegeben. " ztrafo " <function ( x ){ y <- rep (0 , length ( x )); for ( i in 1: length ( x )) y [ i ] <-( x [ i ] - mean ( x )) / sqrt ( var ( x )) ; y } > ztrafo ( c (1 ,3 ,1.4)) [1] -0.7559289 1.1338934 -0.3779645 sumnm <function (n , m ){ x <- 1: n y <- 1: m z <- sum ( x )+ sum ( y ) z } > sumnm (3 ,5) [1] 21 6.10. INTERFACE ZU EXTERNEN ROUTINEN IN C ODER FORTRAN205 6.9.2.1 Einlesen von Funktionen aus und Speichern von Funktionen in eine Datei Wenn Sie eine Funktion nicht im Editor schreiben, sondern als exterene Datei (z.B sumnm.txt) gespeichert vorliegen haben, so können Sie sie folgendermaßen in R einlesen: > source ( " sumnm . txt " ) Falls die Datei nicht im selben Verzeichnis steht, in dem R läuft, muß der genaue Pfad angegeben werden, etwa: source("../sumnm.txt") Wenn Sie nicht wissen, in welchem Verzeichnis R läuft, können Sie das so abfragen: > system ( " pwd " ) Genauso können Sie auch selbstdefinierte Funktionen und Objekte in einer externen Datei speichern: > dump ( " ztrafo " , " ztrafo . txt " ) 6.10 Interface zu externen Routinen in C oder Fortran R verfügt über Interfaces zu externen Funktionen, die in C oder Fortran geschrieben sein können. Ziele der Einbettung von externen Funktionen in R sind • die Beschleunigung des entsprechenden Codes gegenüber der interpretierten Ausführung von R Funktionen. 206 KAPITEL 6. R • die Verwendung schon bestehender Funktionen die in Form von Fortran oder C Bibliotheken vorliegen. Große Teile der zentralen Funktionalität sind ebenfalls auf diese Weise implementiert. 6.10.1 Grundlagen • Variablen die zwischen R und den externen Routinen ausgetauscht werden sollen müssen vom Typ integer oder double sein, dies kann mit storage.mode() überprüft werden. (in alten S-PLUS Versionen wurde integer oder single verwendet) • Argumente werden mittels call-by-refererence übergeben (also Fortran kompatibel) Daraus ergibt sich: • Für C Funktionen: Es müssen alle Argumente als Zeiger deklariert werden, Rückgabewert ist void. • Fortran: Es müssen SUBROUTINE Unterprogramme verwendet werden. Die Funktionen müssen in einer “shared library” vorliegen (unter Unix i.d.R. eine Datei mit Endung .so, unter Windows .dll) Mittels dyn.load("libname.so") wird die externe Library geladen. Mit is.loaded("fname") kann das erfolgreiche Laden überprüft werden, vorausgesetzt die Library libname.so enthält eine Funktion mit Namen fname. Eine “shared library” wird unter Unix i.A. mit den zwei Schritten # C: 6.10. INTERFACE ZU EXTERNEN ROUTINEN IN C ODER FORTRAN207 cc -c -fPIC fname.c # Fortran: f77 -c -fPIC fname.f # Linking: ld -shared fname.o -o libname.so erstellt. R stellt dafür den Aufruf R CMD SHLIB -o libname.so fname1.c fname2.f zur Verfügung, dabei werden die für die jeweilige Plattform benötigten Compiler- und Linkeraufrufe generiert. 6.10.2 C Interface C Funktionen werden über .C() aufgerufen. Anwendung: .C("fname", arg1, arg2, ...) Rückgabewert: eine Liste mit Elementen entsprechend arg1, arg2, ... Simple Demonstration: Vektoraddition in C: void add(int *n, double *a, double *b, double *c){ int i; for(i=0;i<*n;i++) c[i]=a[i]+b[i]; } R CMD SHLIB -o libadd.so addc.c ... in R: > dyn.load("libadd.so") > is.loaded("add") [1] TRUE 208 KAPITEL 6. R Argumente vorbereiten: > v1<-c(1,2,3) > v2<-c(2,4,6) > n <- 3 Aufruf: > retval <- .C("add",as.integer(n),as.double(v1), + as.double(v2),double(3)) > retval [[1]] [1] 3 [[2]] [1] 1 2 3 [[3]] [1] 2 4 6 [[4]] [1] 3 6 9 retval[[4]] enthält das Ergebnis. 6.10.3 Fortran Interface Der Aufruf von Fortran Subroutinen erfolgt mittels .Fortran(), das analog zu .C() verwendet wird. Beispiel (Vektoraddition) SUBROUTINE ADD (N ,A ,B , C ) INTEGER N 6.10. INTERFACE ZU EXTERNEN ROUTINEN IN C ODER FORTRAN209 DOUBLE PRECISION A ( * ) , B ( * ) , C ( * ) 10 INTEGER I DO 10 I =1 , N C ( I )= A ( I )+ B ( I ) CONTINUE RETURN END Die Fortran Subroutine muss nun zur shared library hinzugefügt werden: R CMD SHLIB -o libadd.so addc.c addf.f ... in R: # alte shared library entfernen: > dyn.unload("libadd.so") # neu laden: > dyn.load("libadd.so") > is.loaded("add_") [1] TRUE Fortran Symbole unterscheiden sich (auf den meisten Unix Systemen) durch den angehängten Underscore von C Funktionen. Aufruf (hier mit benannten Listenelementen, dadurch vereinfacht sich später der Zugriff): > retval <- .Fortran("add",n=as.integer(n), + a=as.double(v1),b=as.double(v2), + c=double(3)) > retval $n [1] 3 $a 210 KAPITEL 6. R [1] 1 2 3 $b [1] 2 4 6 $c [1] 3 6 9 6.11 Pakete Eine der Stärken von R ist dessen Erweiterbarkeit, neue Funktionen können in Eweiterungspaketen, sog. packages, bereitgestellt werden. Anlaufpunkt zur Suche nach Paketen ist der ”PAckagesÄbschnitt von CRAN3 . Zur Zeit (2013) stehen dort über 4500 Pakete zu unterschiedlichsten Anwendungsgebieten zur Auswahl. Packages werden mit install.packages("paketname") installiert und mit library(paketname) geladen. Funktionen in Paketen sind i.d.R. gut dokumentiert, d.h. die help() bzw. example() Funktion helfen beim Einsatz der neu heruntergeladenen und installierten Pakete. Aber auch eigene Funktionen (einfache R Funktionen oder Funktionen mit Routinen in C und/oder Fortran), Datensätze sowie Hilfedateien zu den selbst geschriebenen Funktionen können in Erweiterungspakete zusammengepackt werden. Hierzu müssen die Funktio3 http://cran.r-project.org 6.11. PAKETE 211 nen, Datensätze, der C- oder Fortran Quelltext und die Hilfedateien lediglich in eine vorgegebene Dateistruktur einsortiert werden. 6.11.1 Filestruktur Die eigenen Funktionen, Datensätze, C- und/oder Fortran-Erweiterungen müssen in folgender Verzeichnisstruktur abgelegt werden: $ # $ # $ # $ # $ mkdir packagename hierher gehoeren die R Funktionen: mkdir packagename/R dort stehen C und Fortran Files: mkdir packagename/src die Hilfeseiten werden hier abgelegt: mkdir packagename/man da stehen Datensaetze: mkdir packagename/data Zusätzlich wird im Toplevel Verzeichnis des Paketes eine Datei namens DESCRIPTION angelegt in der verschiedene Feldnamen mit Werten befüllt werden müssen. Ein solches File kann z.B. so aussehen: Package: packagename Version: 0.1-1 Title: Einzeilige Paketbeschreibung Description: Mehrzeilige Beschreibung des Pakets, Folgezeilen mit Leerzeichen eingerueckt. Author: Name des Autors <email> Maintainer: Name des Maintainers <email> License: z.B. GPL 2 Depends: optionale kommagetrennte Liste anderer benoetigter Pakete 212 KAPITEL 6. R Beginnend mit R Version 2.15 ist zusätzlich ein NAMESPACE File wie folgt anzulegen: # Namen der dem Benutzer zugänglichen (zu exportierenden) # Funktionen, hier nicht aktiv: # export(func1,func2, ...) # folgendes exportiert alles: exportPattern(".") # Falls C und/oder Fortrancode geladen werden soll, hier nicht akt # useDynLib(packagename) 6.11.2 Hilfeseiten Der Quelltext von Hilfeseiten wird in einer *.Rd Datei abgelegt, die einige LATEX-ähnliche Konstrukte enthält. Am einfachsten geht man so vor dass man zuerst die Funktion schreibt, und dann, wenn die Gestaltung des Aufrufs klar ist, mit prompt(functionsname) eine leeres Skelett einer Hilfedatei funktionsname.Rd erzeugt, diese ins man Verzeichnis verschiebt, und die Strukturen entsprechend der erzeugten Kommentare weiter auffüllt. Zur folgenden Funktion myfunc <- function(data, par1=TRUE, par2=1, par3="test"){ # ... ret } erzeugt > prompt ( myfunc ) 6.11. PAKETE 213 Datei namens ' myfunc . Rd ' erzeugt . Bearbeite die Datei und verschiebe sie in das geeignete Verzeichnis . die Datei \name{myfunc} \alias{myfunc} %- Also NEED an '\alias' for EACH other topic documented here. \title{ %% ~~function to do ... ~~ } \description{ %% ~~ A concise (1-5 lines) description of what the function does. ~~ } \usage{ myfunc(data, par1 = TRUE, par2 = 1, par3 = "test") } %- maybe also 'usage' for other objects documented here. \arguments{ \item{data}{ %% ~~Describe \code{data} here~~ } \item{par1}{ %% ~~Describe \code{par1} here~~ } \item{par2}{ %% ~~Describe \code{par2} here~~ } \item{par3}{ %% ~~Describe \code{par3} here~~ } } \details{ %% ~~ If necessary, more details than the description above ~~ } 214 KAPITEL 6. R \value{ %% ~Describe the value returned %% If it is a LIST, use %% \item{comp1 }{Description of 'comp1'} %% \item{comp2 }{Description of 'comp2'} %% ... } \references{ %% ~put references to the literature/web site here ~ } \author{ %% ~~who you are~~ } \note{ %% ~~further notes~~ } %% ~Make other sections like Warning with \section{Warning }{....} ~ \seealso{ %% ~~objects to See Also as \code{\link{help}}, ~~~ } \examples{ ##---- Should be DIRECTLY executable !! ---##-- ==> Define data, use random, ##--or do help(data=index) for the standard data sets. ## The function is currently defined as function (data, par1 = TRUE, par2 = 1, par3 = "test") { ret } } % Add one or more standard keywords, see file 'KEYWORDS' in the 6.11. PAKETE 215 % R documentation directory. \keyword{ ~kwd1 } \keyword{ ~kwd2 }% __ONLY ONE__ keyword per line Man beachte, daß das erzeugte File bereits Einträge für die Argumente dieser Funktion sowie deren allgemeinen Auruf enthält. Die Prozentzeichen leiten Kommentarzeilen ein, welche beschreiben was an die jeweilige Positionen zu schreiben ist. Am Ende der Hilfedatei sind ein oder mehrere Beispielaufrufe anzugeben, die später mit example(myfunc) direkt ausführbar sind. 6.11.3 C / Fortran C und Fortranfunktionen werden im src Unterverzeichnis abgelegt. Zusätzlich müssen in R Callwrapper geschrieben werden, die mittels .C() oder .Fortran() die externen Routinen mit Argumenten versorgen, aufrufen und die Rückgabewerte extrahieren, siehe Abschnitt 6.10.1. Das manuelle Laden der shared library / DLL entfällt durch die Angabe von useDynLib(packagename) im NAMESPACE File. Die Parameterübergabe ist der kritischste Teil beim Umgang mit .C() und .Fortran(), stimmen hier Anzahl und Datentyp nicht zwischen R Interface und externer Routine überein, führt dies im günstigsten Fall zum sofortigen Absturz oder – schlimmer – zum Rücklesen völlig falscher Werte von der externen Routine. Um solchen Fehlern vorzubeugen, empfiehlt es sich, sämtliche externe Funktionen mit der Anzahl und dem Typ ihrer Parameter in folgender Weise in einem Header- (z.B. packagename.h) und einem C-File (z.B. init.c), hier passend zu den Beispielen in Abschnitt 6.10.2 und 6.10.3, festzulegen. Wenn man nun vom R Interface aus die Funktionen mit falscher Anzahl oder falschem Typ von Parametern aufruft, erhält man in R eine entprechende Fehlermeldung. Das Headerfile packagename.h: 216 KAPITEL 6. R #include <R.h> /* Fortran SUBROUTINE: */ void F77_NAME(addf)(int *n, double *a, double *b, double *c); /* C Funktion: */ void addc(int *n, double *a, double *b, double *c); Die Initialisierungsfunktionen init.c die beim Laden der Library ausgeführt werden: #include <R.h> #include <Rinternals.h> #include "packagename.h" #include <R_ext/Rdynload.h> /* Typdeklaration der Fortran Funktionen, INTEGER und DOUBLE PRECISION Argumente muessen auf die R internen Listentypen INTSXP (integer S expression) und REALSXP (real S expression) abgebildet werden: */ static R_NativePrimitiveArgType addf_t[4] = { INTSXP, /* N */ REALSXP, /* A */ REALSXP, /* B */ REALSXP /* C */ }; /* Typdeklaration der C Funktionen, int und double muessen ebenso auf INTSXP und REALSXP abgebildet werden: */ 6.11. PAKETE 217 static R_NativePrimitiveArgType addc_t[4] = { INTSXP, /* n */ REALSXP, /* a */ REALSXP, /* b */ REALSXP /* c */ }; /* NULL-terminierte Liste aller Fortran Deklarationen */ static R_FortranMethodDef fortranMethods[] = { {"addf", (DL_FUNC) &F77_SUB(addf), 4, addf_t}, {NULL, NULL, 0} }; /* NULL-terminierte Liste aller C Deklarationen */ static R_CMethodDef cMethods[] = { {"addc", (DL_FUNC) addc, 4, addc_t}, {NULL, NULL, 0} }; /* Initialisierungsfunktion, wird einmal beim Laden der Library ausgefuehrt */ void R_init_packagename(DllInfo *info) { /* hier werden nur Funktionen fuer das .C und .Fortran Interface deklariert, .Call und .External sind zwei weitere Interfaces die hier nicht verwendet sind, deshalb NULL */ R_registerRoutines(info, cMethods, NULL /*callMethods*/, fortranMethods, NULL /*externalMethods*/); 218 KAPITEL 6. R } In allfälligen C Quelltexten sind die nun angelegten Header Files natürlich auch mit einzubetten, also in diesem Beispiel: #include "packagename.h" Durch Anhängen von PACKAGE="packagename" als Argument von .C() und .Fortran() stellt man sicher daß wirklich die C / Fortran Funktionen der eigenen Library und nicht irgendwelche Doppelgänger gleichen Namens anderer Pakete verwendet werden. 6.11.4 Installation von Paketen Das Quelltextpaket der Library wird auf der Kommandozeile ein Verzeichnis oberhalb von packagename mittels R CMD build packagename erstellt (es ensteht packagename_1.0-1.tar.gz, die Versionsnummer wird automatisch aus dem DESCRIPTION File entnommen), dieses kann mit R CMD INSTALL packagename_1.0-1.tar.gz installiert werden. Das binäre Installationspaket packagename_1.0-1.zip für Windows erstellt man mit R CMD INSTALL --build packagename Voraussetzung dafür ist das passende und korrekt installierte Rtools4 Paket passend zur installierten R Version. Dieses umfasst die nötigen Compiler (GNU C und Fortran) sowie eine Teilmenge der UnixKommandozeilentools die für deren Funktionieren notwendig sind. 4 http://cran.r-project.org/bin/windows/Rtools/ 6.12. R, EMACS UND LATEX 219 Voraussetzung ist weiterhin, dass R unter Windows innerhalb der DOS Kommandozeile (CMD) aufrufbar ist. Dazu muss der R Installationspfad (üblicherweise C:\Programme\R\R-X.Y\bin mit passender Versionsnummer X.Y ) in die PATH Systemvariable aufgenommen werden. Des Weiteren kann man mittels R CMD check packagename das Paket auf Fehlerfreiheit testen. In der Regel sind hier mehrere Durchläufe nötig um alle Fehler- und Warnmeldungen auszumerzen, die Entwicklerdokumentation5 auf CRAN beschreibt dies alles im Detail. 6.12 R, Emacs und LATEX Mit Hilfe des Emacs Zusatzpakets ESS6 kann, wie oben schon erwähnt, R im Emacs ausgeführt ( Alt x R) werden und Dateien mit R Code (Endung .R) bequem editiert und ganz oder teilweise ins R übernommen werden. Eine R Sitzung kann als R Protokoll (Dateiendung .St) abgespeichert und später nochmals ausgeführt werden. Mit Hilfe von Sweave7 kann R Code mit LATEX vermischt werden. Dazu baut man sogenannte Code-chunks in ein sogenanntes Sweave Dokument (Dateieindung .Rnw) ein, das ansonsten den normalen LATEX-Quelltext enthält: hier steht \LaTeX Quelltext <<>>= 5 Writing R Extensions, http://cran.r-project.org/doc/manuals/ r-release/R-exts.html 6 http://ess.r-project.org 7 http://www.statistik.lmu.de/~leisch/Sweave/ 220 KAPITEL 6. R hier steht der R Code @ und hier wieder \LaTeX Quelltext Solche Chunks können benannt werden, <<label=chunk1>>= und über diese Namen wiederverwendet werden: werden: <<label=chunk2,>>= <<chunk1>> y <- x*2 @ <<label=chunk1>>= x <- rnorm(5) @ Es können auch Chunks versteckt werden indem die Option echo auf FALSE gesetzt wird: <<label=chunk3,echo=FALSE>>= hidden <- 42 @ Mittels \Sexpr{expr} können R Variablen direkt in den Text gesetzt werden, z.B. mit \Sexpr{hidden} die folgende Zahl: 42. Auch Grafiken können automatisch eingebunden werden. Zuerst wird ein Code Chunk erstellt der die Grafik erzeugt: <<label=sweaveplot>>= plot(c(1,4,3,2,1),type="h") @ > plot ( c (1 ,4 ,3 ,2 ,1) , type = " h " ) 221 2.5 1.0 1.5 2.0 c(1, 4, 3, 2, 1) 3.0 3.5 4.0 6.12. R, EMACS UND LATEX 1 2 3 4 5 Index Abbildung 6.19: Mit Sweave erzeugter Plot und dann eine figure Umgebung erstellt die auf diesen Chunk verweist: \begin{figure} \centering <<label=figsweaveplot,fig=TRUE,echo=FALSE,results=hide>>= <<sweaveplot>> @ \caption{Mit Sweave erzeugter Plot} \label{fig:swaeveplot} \end{figure} Generell können durch Labels benannte Chunks in anderen Chunks wiederverwendet werden. Ein Sweave Dokument kann nicht mehr direkt mit LATEX übersetzt 222 KAPITEL 6. R werden, zuerst muss aus ihm ein TEX-File erstellt werden, von der Kommandozeile aus mittels : R CMD Sweave Datei.Rnw oder von R aus mit > Sweave ( " Datei . Rnw " ) Writing to file Datei . tex Processing code chunks with options ... 1 : echo keep . source term verbatim ( label = chunk1 , Datei . Rnw :10) 2 : ... You can now run ( pdf ) latex on ' Datei . tex ' Im Emacs wird ein Sweave File über dessen .Rnw-Endung erkannt und ein entsprechendes Zusatzmenü zu den auctex Menüs angezeigt (Noweb), darin sind Einträge zum Starten von Sweave und zum anschließenden LATEX Aufruf vorhanden. Wenn im Emacs der Eingabecursor innerhalb eines Code-Chunks steht, wird der auctex-Modus verlassen und in den ESS Modus gewechselt (die Menüs werden getauscht und die ESS Eingabehilfen aktiviert). Sämtliche R Beispiele und Plots in diesem Skriptum sind mittels Sweave entstanden. Kapitel 7 Octave Octave ist eine Programmiersprache, die hauptsächlich auf numerische Berechnungen spezialisiert ist. Sie bietet u.a. Hilfsmittel zur Lösung von Aufgaben der linearen und nichtlinearen Algebra. Zur grafischen Darstellung wird ein Interface zu Gnuplot verwendet. Octave lässt sich durch eigene Funktionen erweitern, die entweder in Octave selbst (sog. M-files) oder in C++ (oct-files) geschrieben sind. Octave1 steht unter der GPL und ist somit freie Software. Obwohl vom Autor (John W. Eaton) nicht ursprünglich beabsichtigt, besitzt Octave in seiner Syntax große Ähnlichkeit zu MATLAB, einem kommerziellen Programm mit ähnlichem Anwendungsspektrum. Viele Octave Befehle sind unverändert auch unter MATLAB ausführbar und umgekehrt. Mit Scilab2 existiert eine weitere Numeriksoftware deren Syntax stark an MATLAB angelehnt ist, im Gegensatz zu Octave ist hier eine GUI integriert. Scilab ist eng mit Scicos3 1 http://www.octave.org 2 http://www.scilab.org/ 3 http://www.scicos.org 223 224 KAPITEL 7. OCTAVE verknüpft, einem grafischen Modellierungsprogramm zur Simulation technischer Systeme, das Ähnlichkeit mit MATLABs Simulink aufweist. 7.1 Grundlagen Octave ist ein kommandozeilenorientiertes Programm und meldet sich nach dem Aufruf octave mit dem Prompt GNU Octave, version 3.0.5 Copyright (C) 2008 John W. Eaton and others. This is free software; see the source code for copying conditions. There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, type `warranty'. Octave was configured for "i486-pc-linux-gnu". Additional information about Octave is available at http://www.octave.org. Please contribute if you find this software useful. For more information, visit http://www.octave.org/help-wanted.html Report bugs to <[email protected]> (but first, please read http://www.octave.org/bugs.html to learn how to write a helpful report). For information about changes from previous versions, type `news'. octave:1> Innerhalb vom Emacs läßt sich Octave mittels Alt - X run-octave Enter starten. Der Emacs hält auch für das Editieren von M-Files einen speziellen Modus bereit. Auf dem Kommandoprompt ist Octave zunächst wie ein Taschenrechner benutzbar. Die üblichen Klammersetzungen haben ebenso Gültigkeit wie die Standardrechenoperationen. 7.2. VARIABLEN UND DATENTYPEN 225 Werte können aber auch Variablen zugewiesen werden: o c t a v e :1 > a=1 a = 1 o c t a v e :2 > b=2; Dadurch daß eine Zeile mit “;” abgeschlossen wird, läßt sich die nochmalige Ausgabe des Ergebnisses unterdrücken. Dies ist besonders dann von Bedeutung wenn Programme, also M-Files, geschrieben werden und nicht jeder Zwischenschritt eine Bildschirmausgabe produzieren soll. Es kann allerdings auch mit einer einzigen Zuweisung auf mehrere Variablen geschrieben werden. Dies ist allerdings nur in Zusammenhang mit Funktionen, die mehrere Rückgabewerte besitzen möglich, wie z.b. bei der Eigenwert-Eigenvektorzerlegung. 7.2 Variablen und Datentypen Daten in Octave sind entweder reelle oder komplexe Gleitkommazahlen oder Strings, bzw. Vektoren oder Matrizen dieser Datentypen. Variablen werden mit dem Zuweisungsoperator “=” erzeugt. o c t a v e :3 > x=1 x = 1 Zusätzlich lassen sich diese Typen in C-struct ähnliche Datenstrukturen organisieren. Hierzu werden die Komponenten der Datenstruktur mit einem “.” von deren Namen getrennt: o c t a v e :16 > a . t e i l 1 =1 a. teil1 = 1 o c t a v e :17 > a . t e i l 2 =” t e x t ” a . t e i l 2 = text 226 KAPITEL 7. OCTAVE o c t a v e :18 > a a = { t e i l 2 = text teil1 = 1 } Die Eingabe von Vektoren und Matrizen erfolgt mittels eckiger Klammern []. Innerhalb dieser Klammern trennt “,” oder ein Leerzeichen Spalten innerhalb einer Zeile und “;” oder Zeilenumbruch Zeilen voneinander. o c t a v e :4 > A= [ 1 , 2 ; 3 , 4 ] A = 1 3 2 4 o c t a v e :5 > B=[1 2 > 3 4] B = 1 3 2 4 o c t a v e :6 > C=[1 2 ; 3 4 ] C = 1 3 2 4 Auf Teile von Vektoren und Matrizen kann mittels Indexangaben zugegriffen werden: o c t a v e > C( 1 , 2 ) ans = 2 octave> C( : , 2 ) ans = 2 7.2. VARIABLEN UND DATENTYPEN 227 4 Dabei können mit dem Bereichsoperator : Bereiche, z.B. ganze Zeilen oder Spalten angegeben werden. Man kann auch Blockmatrizen aus vorhandenen Matrizen bilden: o c t a v e > D=[C C ; C C ] D = 1 3 1 3 2 4 2 4 1 3 1 3 2 4 2 4 o c t a v e > D( 1 : 2 , 2 : 3 ) ans = 2 4 1 3 Mit eye erzeugt man die Einheitsmatrix: o c t a v e > I=e y e ( 3 ) I = D i a g o n a l Matrix 1 0 0 0 1 0 0 0 1 und mit diag eine Diagonalmatrix: o c t a v e > E=d i a g ( [ 1 , 2 , 3 ] ) E = D i a g o n a l Matrix 1 0 0 0 2 0 0 0 3 228 KAPITEL 7. OCTAVE diag kann aber auch aus einer vorhandenen Matrix die Diagonale extrahieren, z.B. mit Matrix D von oben: o c t a v e > d i a g (D) ans = 1 4 1 4 Vordefinierte Variablen sind Konstanten wie pi, i und e. Weitere vordefinierte Variablen steuern das Verhalten von Octave in unterschiedlichen Bereichen. Die Funktionen columns() und rows() geben die Spalten- und Zeilenzahl des übergebenen Arguments zurück, die Funktion length() deren Maximum. Die Funktion size() liefert beides. Ihr Rückgabewert lässt sich auf zwei Variablen gleichzeitig schreiben: o c t a v e :7 > s i z e (A) ans = 2 2 o c t a v e :8 > [ n c o l , nrow ]= s i z e (A) ncol = 2 nrow = 2 Im Gegensatz zu R speichert Octave die während einer Sitzung erstellten Variablen nicht ab, beim Beenden gehen diese alle verloren. Man kann aber mit der save Funktion einzelne oder alle Variablen in verschiedenen Formaten in Dateien sichern. Folgender Aufruf sichert alle Variablne in Binärformat in eine Datei daten.mat: o c t a v e :8 > s a v e ( ”−b i n a r y ” , ”daten . mat ” , ”∗ ” ) ; 7.3. OPERATOREN 229 Mit load("daten.mat") kann dies dann später wieder geladen werden. 7.3 Operatoren Operatoren in Octave sind grundsätzlich Matrix- bzw. Vektoroperatoren. Sollen sie davon abweichend einzeln auf die Elemente der Operanden angewendet werden, ist ihnen ein “.” vorn anzuhängen (Bei Addition und Subtraktion macht dies natürlich keinen Unterschied). Matrix- bzw. Vektoraddition, -subtraktion und -multiplikation erfolgen also, richtige Matrixdimensionen vorausgesetzt, z.B. so octave> [ 1 1 ; 0 1 ] + [ 1 0 ; 0 1 ] ans = 2 1 0 2 octave> [ 1 1 ; 0 1 ] ∗ [ 1 0 ; 0 1 ] ans = 1 1 0 1 Zum Unterschied die elementweise Multiplikation: octave> [ 1 1 ; 0 1 ] . ∗ [ 1 0 ; 0 1 ] ans = 1 0 0 1 Matrix- division“ entspricht Multiplikation mit der Inversen, entwe” der von links oder rechts: A\B = A−1 B bzw. A/B =AB−1 Der \ Operator läßt sich somit zum Lösen von Gleichungssystemen Ax = b wie folgt einsetzen (mit nachgestelltem ' wird transponiert): 230 KAPITEL 7. OCTAVE o c t a v e > A=[1 1 ; 0 1 ] A = 1 0 1 1 o c t a v e > b=[1 1 ] ' b = 1 1 o c t a v e > x=A\b x = 0 1 o c t a v e > A∗x−b ans = 0 0 Es können auch die von C bekannten Inkrement- und Dekrementoperatoren ++ und -- angewendet werden, mit der Matrix C = 1 2 z.B.: 3 4 o c t a v e > C++ ans = 1 3 2 4 o c t a v e > ++C ans = 3 4 7.4. STEUERANWEISUNGEN 5 231 6 Zu beachten ist, wie bei C, die Prefix- oder Postfixnotation dieser Operatoren, deshalb sieht men im ersten Beispiel noch den Zustand 2 3 vor der Anwendung und nicht 4 5 7.4 Steueranweisungen In Octave bzw. MATLAB können eigene Programme, d.h. Funktionen, geschrieben werden. Hierzu existieren die nachfolgend beschriebenen Steueranweisungen, die also weniger im interaktiven Modus sondern hauptsächlich in den sog. M-Files vorkommen. 7.4.1 Verzweigungen Bedingte Ausführung läßt sich im einfachen Fall mit if und bei Mehrfachentscheidungen mit switch realisieren. Bei if können ein else oder auch mehrere elseif Blöcke mit angegeben werden. Die Bedingungen sind logische Ausdrücke die mit den Relationen ==, <=, >=,<, cmd> und != sowie den logischen Operatoren &, | und ! gebildet werden (diese wirken elementweise, && und || wandeln vorher ihre Argumente mit dem all Operator in einen Skalar um!). if ( Bedingung 1 ) if - Block elsif ( Bedingung 2 ) elseif - Block else else - Block endif Eine elseif Konstruktion der folgenden Form 232 KAPITEL 7. OCTAVE if ( A ==1) Block 1 ; elseif ( A ==2) Block 2 ; ... else Block n +1 ; endif lässt sich besser mit switch ausdrücken: switch ( A ) case 1 Block 1 ; case 2 Block 2 ; ... otherwise Block n +1 ; endswitch 7.4.2 Schleifen Die Syntax für die üblichen Schleifenkonstrukte for, do until und while lautet: for laufvariable = ausdruck for - Block endfor octave> f i b = [ 1 1 ] fib = 1 1 octave> f o r i = 3:10 > f i b ( i ) = f i b ( i −1) + f i b ( i −2); 7.4. STEUERANWEISUNGEN 233 > endfor octave> f i b fib = 1 1 2 3 5 8 13 21 34 55 21 34 55 21 34 55 octave> do do - Block until ( Bedingung ) octave> f i b = [ 1 1 ] ; o c t a v e > i =2; o c t a v e > do > i ++; > f i b ( i ) = f i b ( i −1) + f i b ( i −2); > u n t i l ( i ==10) octave> f i b fib = 1 1 2 3 5 8 13 while ( Bedingung ) while - Block endwhile octave> f i b = [ 1 1 ] ; octave> i = 3 ; o c t a v e > w h i l e ( i <= 1 0 ) > f i b ( i ) = f i b ( i −1) + f i b ( i −2); > i ++; > endwhile octave> f i b fib = 1 1 2 3 5 8 13 234 7.5 KAPITEL 7. OCTAVE Funktionen Octave und MATLAB Programme werden in Form von Funktionen, üblicherweise eine Funktion pro File, geschrieben. Dabei muss der Funktionsname mit dem Dateinamen (erweitert mit einem abschließenden .m) übereinstimmen. Pn Die folgende Funktion ermittelt ab welchem n die Summe i=1 i−1 i2 eine vorgegebene Schranke überschreitet. Typischerweise liefern Funktionen mehrere Rückgabewerte, hier zusätzlich den aktuellen Wert der Summe. f u n c t i o n [ i t e r , cumsum]=summe ( l i m i t ) cumsum=0; i t e r =0; w h i l e cumsum<l i m i t i t e r=i t e r +1; cumsum=cumsum+( i t e r −1)/ i t e r ˆ 2 ; end end Wird die Funktion ohne Zwischenspeichern aufgerufen, erhält man nur den ersten Rückgabewert, will man alle behalten muss man auf einen Vektor mit entsprechend viel Variablennamen abspeichern: octave> summe(3) ans = 57 octave> [i,s]=summe(3) i = 57 s = 3.0015 In Octave kann eine Funktion auch mit endfunction abgeschlossen werden, in MATLAB nur mit end. 7.5. FUNKTIONEN 235 Als etwas komplexeres Beispiel wird nun der Simplexalgorithmus implementiert, ein einzelner Simplexschritt wird von der Funktion simplex abgewickelt: function [ZFi,Ti,bi,iP,jP] = simplex(A,b,c,iB,iNB) % A - m x n, vollst. Tableau % c - Kostenvektor (Spaltenv.) % iB, iNB - Index Basis/Nichtbasis (Spaltenv.) [m,n]=size(A); % Aufteilung des Tableaus in Basis/Nichtbasis An=A(:,iNB'); Ab=A(:,iB'); Ti=Ab\A; % aktuelles Tableau Ab^-1 * A % reduzierter Kostenvektor: % (0 ,c.b'*Ab^-1*An-c.nb )' cr(iNB) = ( c(iB)'* (Ab\An) - c(iNB)' )' ; cr(iB) = zeros(m,1); % bi=Ab\b; %aktuelle Basisloesung Ab^-1*b % akt ZF Wert cb'*Ab^-1*b ZFi=c(iB)'*bi; % Zulaessigkeit pruefen: 236 KAPITEL 7. OCTAVE % bi>=0 if(min(bi)<0) disp('unzulaessig!') return; endif % Optimalität, alle red. c.nb nichtneg.?: if(min(cr(iNB))>=0) iP=0; jP=0; disp('Optimalitaet erkannt!') return endif % Pivotspalte: % kleinsten pos. Nichtbasiseintrag im red. % Kostenvektor suchen: [minc, iP] = min(cr(iNB)); % Quotientenspalte: rechte Seite/Pivotspalte % = max. zul. Schrittweite entlang % ausgew. Kante q=bi./Ti(:,iP); % Pivotzeile: [minq, jPq] = min(q); jP=iB(jPq); endfunction Das komplette Verfahren, Phase I und II, ist in dosimplex implementiert: 7.5. FUNKTIONEN function [ZF,x] = dosimplex(A,b,c) [m,n]=size(A); % TODO: Phase I % einfacher Fall: A*x<=b, x>=0, b>=0 T=[A eye(m)]; % Ausgangstableau mit Schlupfvar. cw=[c; zeros(m,1)]; % erw. Kostenvektor (Spalte) % Indexvektoren Basis/Nichtbasis iNB=1:n; iB=(n+1):(n+m); % Indizes zum Basistausch iP=-1; jP=-1; while(iP!=0 && jP!=0) [ZF,Tbl,x,iP,jP]=simplex(T,b,cw,iB',iNB'); % Basistausch: iB(iB==jP)=iP; iNB(iNB==iP)=jP; endwhile endfunction 237 238 KAPITEL 7. OCTAVE Beispiel: 10x1 + 30x2 + 10x3 + 40x4 → max x1 + x2 ≤ 200 x3 + x4 ≤ 100 x1 + x3 ≤ 150 x2 + x4 ≤ 150 octave> A= [1,1,0,0 ; 0,0,1,1 ; 1,0,1,0 ; 0,1,0,1] b= [200;100;150;150] c= [20;30;10;40] A = 1 0 1 0 1 0 0 1 0 1 1 0 octave> b = 200 100 150 150 octave> c = 20 30 10 40 0 1 0 1 7.6. GRAFIK 239 octave> octave> octave> [f,x]=dosimplex(A,b,c) Optimalitaet erkannt! f = 8500 x = 150 100 0 50 7.6 Grafik Für die Grafikanzeige in Octave ist gnuplot, ein externes Programm, zuständig (genau wie bei Maxima). Einfache x-y-Plots erzeugt man mit plot und sichert sie als EPS file mit print: octave> x = -pi:0.1:pi; octave> plot(x,sin(x)) octave> print -deps sin-plot.eps print -deps sin-plot.eps Dreidimensionale Plots werden mit mesh erzeugt: octave> octave> octave> octave> tx = ty = linspace (-8, 8, 41)'; [xx, yy] = meshgrid (tx, ty); r = sqrt (xx .^ 2 + yy .^ 2) + eps; tz = sin (r) ./ r; 240 KAPITEL 7. OCTAVE 1 0.5 0 -0.5 -1 -4 -3 -2 -1 0 1 2 3 4 Abbildung 7.1: Octave Plot octave> mesh (tx, ty, tz); octave> print -deps mesh-plot.eps print -deps mesh-plot.eps Die Funktionen linspace und meshgrid erzeugen regelmäßige Punktgitter in R1 bzw. R2 7.7 Octave, LATEX und Emacs Im Emacs kann Octave mittels Alt - X run-octave Enter gestartet werden, der Vorteil besteht darin, dass die gesamte Ein- und Ausgabe anschließend in ein Textfile gesichert werden kann. Außerdem steht Tab -Vervollständigung für Funktions- und Variablennamen zur Verfügung. Für M-Files existiert ein spezieller Editiermodus der u.a. Syntaxhighlighting und automatische Einrückung bereitstellt Es gibt mit MATweave4 , auch eine rudimentäre Einbindung von 4 http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/matweave.html 7.7. OCTAVE, LATEX UND EMACS 241 1 0.8 0.6 0.4 0.2 0 -0.2 -0.410 10 5 5 0 0 -5 -5 -10-10 Abbildung 7.2: Octave 3D Plot Octavecode in LATEX, die allerdings nicht so ausgefeilt wie Sweave für R funktioniert. Es ist damit lediglich möglich Octave Befehle so in einem LATEX-File zu verstecken, dass man das LATEX-File ohne es zerlegen zu müssen in Octave ausführen kann. Zu diesem Zweck muss das LATEX File mit den Zeilen %{ noch vor der documentclass Zeile beginnen und nach dem document Environment mit %} enden. Dann kann MATLAB/Octave Code in \begin{verbatim} - \end{verbatim} Blöcke gesetzt werden wenn die Octave Befehle zusätzlich in %} und %{. Zeilen geklammert werden, siehe Beispiel unten. Anschließend kann das LATEX-File in Octave mit source filename.tex 242 KAPITEL 7. OCTAVE eingelesen und die Code-Abschnitte ausgeführt werden. Die Ausgabe landet leider nicht automatisch im LATEX-File sondern muss per Hand in verbatim Blöcke kopiert werden. Der folgende Block \begin{verbatim} %} A=rand(3,3) %{ \end{verbatim} erzeugt in LATEXdie folgenden Zeilen %} A=rand(3,3) %{ und in Octave sieht es dann so aus: octave:1> source octave.tex A = 0.67968 0.97532 0.58097 7.8 7.8.1 0.47222 0.98646 0.20887 0.11348 0.65218 0.72261 Aufgaben Nullstellenbestimmung Im folgenden File wird die regula falsi Methode implementiert: function [x,ftol]=regulafalsi(f,unten,oben) 7.8. AUFGABEN 243 eps=10^-6; maxiter=25 if (sign(f(unten)==sign(f(oben)))) # Fehler abfangen error("gleiche Vorzeichen in 'unten' und 'oben'!"); end # ";" am zeilenende nicht vergessen! step=0; mitte=unten; # endlose Iterationen verhindern! while(abs(f(mitte))>eps && step<=maxiter) step=step+1; mitte=(unten*f(oben)-oben*f(unten))/(f(oben)-f(unten)); # vgl Wikip if(sign(f(mitte))==sign(f(unten))) unten=mitte; elseif(sign(f(oben))==sign(f(mitte))) oben=mitte; else x=mitte; ftol=0; return; end end # je nach Ergebnis Wert zurueck oder Fehler: if(step<maxiter) x=mitte; ftol=abs(f(mitte)); else error("max. Iterationszahl erreicht!"); end end 244 KAPITEL 7. OCTAVE Dasselbe nun in C++ mittels ds liboctave Interfaces: #include #include #include #include #include <octave/oct.h> <octave/octave.h> <octave/parse.h> <octave/ov-scalar.h> <math.h> double callf(octave_function *f, double x){ octave_value_list args; args (0)=octave_value(x); const octave_value_list result = feval (f,args,1); return result(0).double_value(); } DEFUN_DLD (ccregulafalsi, args, nargout, "solve f(x)=0 by regalu falsi"){ int nargin=args.length (); octave_function *f = args(0).function_value (); double unten=args(1).scalar_value(); double oben=args(2).scalar_value(); int maxiter=25,step; double x,ftol,mitte,eps=1.0e-6; octave_value_list retval; step=0; mitte=unten; if (callf(f,unten)*callf(f,oben)>0){ error("gleiche Vorzeichen in 'unten' und 'oben'!"); return retval; } 7.8. AUFGABEN 245 while(fabs(callf(f,mitte))>eps && step<=maxiter){ step++; mitte=(unten*callf(f,oben)-oben*callf(f,unten))/ (callf(f,oben)-callf(f,unten)); if(callf(f,mitte)*callf(f,unten)>0){ unten=mitte; } else if (callf(f,mitte)*callf(f,unten)<0){ oben=mitte; } else { x=mitte; ftol=0; break; } // auskommentieren fuer debugging: // octave_stdout << "step " << step << // " f(" << mitte << ")=" << callf(f,mitte) << ")\n"; } if(step<maxiter){ x=mitte; ftol=fabs(callf(f,mitte)); } else { error("max. Iterationszahl erreicht!"); } retval(0)=octave_value(x); retval(1)=octave_value(ftol); return retval; } 246 7.8.2 KAPITEL 7. OCTAVE Gleichungssysteme mit Töplitzmatrizen Töplitzmatrizen sind quadratische Matrizen deren Haupt- und Nebendiagonalen aus konstanten Einträgen bestehen: ρ0 ρ−1 ρ−2 . . . . . . ρ−n+1 .. . ρ ρ0 ρ−1 . . . 1 .. .. .. .. . . . . ρ1 ρ Tn = .2 .. .. .. . . ρ−1 . . . ρ−2 .. .. . ρ1 ρ0 . ρ−1 ρn−1 . . . . . . ρ2 ρ1 ρ0 Symmetrische Töplitzmatrizen insbesondere haben also folgende Form: ρ0 ρ1 ρ2 . . . . . . ρn−1 .. .. ρ . ρ0 ρ1 . 1 .. .. .. .. . . . ρ1 . ρ Tn = .2 .. .. .. . . . . ρ1 . ρ2 .. .. . ρ1 ρ0 . ρ1 ρn−1 . . . . . . ρ2 ρ1 ρ0 In der Signalverarbeitung und der Zeitreihenanalyse enstehen bei der optimalen Vorhersage Ŷn+1 = φ> Y , Y = (Y1 , . . . , Yn )> Gleichungssysteme mit symmetrischen Töplitzmatrizen, die sog. Yule-Walker Gleichungen: Tn φn = ρn mit φn = (φ1 , . . . , φn )> und ρn = (ρ1 , . . . , ρn )> , wobei ρk = Corr(Yt , Yt−k ) die Autokorrelation der als stationär vorausgesetzten Zeitreihe be- 7.8. AUFGABEN 247 zeichnet. Im Falle eines autoregressiven Prozesses bezeichnet n dessen Ordnung. Dieses Gleichungssystem wird nicht einfach mit dem Gauss-EliminationsVerfahren gelöst, dies würde O(n3 ) Operationen benötigen, sondern mit der Durbin-Levinson-Rekursion, diese benötigt lediglich O(n2 ) Operationen. Algorithmus zum Lösen von Tn x = b, Tn symmetrisch, t = (to , . . . , tn−1 )> bezeichne die erste Spalte von Tn , enthält also die unterschiedlichen Werte der Diagonalen und Nebendiagonalen, siehe z.B. Ng [2004]: 1. δ0 := t0 2. x1 := b1 δ0 3. Wiederhole für m = 1, . . . , n − 1: (a) Falls m = 1: γ0 = − δt10 > )(r1 ,...,rm−1 ) (b) Falls m > 1: γm−1 := − tm +(t1 ,...,tm−1 δm−1 (c) Falls m > 1: rk := rk−1 + γm−1 rm−k+1 , k = 2, . . . , m (d) r1 := γm−1 (e) δm := t0 + (t1 , . . . , tm )(rm , . . . , r1 )> (f) xm+1 := bm+1 +(b1 ,...,bm )(r1 ,...,rm )> δm (g) xk := xk + xm+1 rk , k = 1, . . . , m Die Vektoren rm die im Algorithmus im m-ten Schritt entstehen 248 KAPITEL 7. OCTAVE (Szegö-Vektoren) bilden eine obere Dreiecksmatrix mit Diagonale 1: 1 r1,1 r2,1 r3,1 . . . rn−1,1 0 1 r2,2 r3,2 . . . rn−1,2 0 1 r3,3 . . . rn−1,3 0 . .. .. .. .. R = . . . . . . .. .. .. .. . rn−1,n−1 . . . 0 0 0 0 ... 1 Die Werte δm werden zu einer Diagonalmatrix D = diag((δm ))n−1 m=0 zusammengefasst. Damit gilt folgende inverse Choleskyzerlegung: R> Tn R = D Diese Eigenschaft und die Tatsache dass die Töplitzmatrix Tn−1 als Diagonalblock in Tn enthalten ist, ist die Grundlage für den Algorithmus. Als Nebenprodukt entstehen im Vektor γ (Schurparameter) die Werte der partiellen Autokorrelationsfunktion (oder bedingten Autokorrelationsfunktion): γkk = Corr(Yt , Yt−k |Yt−1 = yt−1 , . . . , Yt−k+1 = yt−k+1 ) Im folgenden werden zwei Octave Funktionen angegeben die aus einem (Zeilen-) Vektor eine Töplitzmatrix erstellen und für eine Töplitzmtrix (gegeben durch den Vektor ihrer Diagonaleinträge) und eine rechte Seite das Yule-Walker Gleichungssystem lösen. Zurückgegeben werden zusätzlich zur Lösung x auch die Matrizen R und D sowie der Vektor der partiellen Korrelationskoeffizienten γ. Töplitzmatrix erstellen, toeplitz.m, der Vektor t wird als Zeilenvektor angegeben: 7.8. AUFGABEN 249 % -*- mode: octave -*function [T] = toeplitz(t) n=length(t); T=t'; for i=2:n T=[T, [t(i:-1:2), t(1:n-i+1)]']; end % braucht ca doppelt so lang: % for i=1:n % for j=i:n % T(i,j)=t(j-i+1); % end % end end % mit for loop: %octave> tic; TT=toeplitz(1:1000); toc %Elapsed time is 8.398 seconds. % mit Vektoren: %octave> tic; TT=toeplitz(1:1000); toc %Elapsed time is 3.226 seconds. % mit C++: %octave> tic; TT=toeplitz(1:1000); toc %generate Toeplitz matrix with dim 1000 x 1000 %Elapsed time is 0.03299 seconds. Yule-Walker Gleichungssystem lösen, durbinlevinson.m, man beachte dass im Gegensatz zur Darstellung des Algorithmus alle Indi- 250 KAPITEL 7. OCTAVE zes mit 1 und nicht teilweise mit 0 wie oben beginnen, das ergibt an einigen Stellen entsprechende Indexverschiebungen. Weiters werden alle vorkommenden Vektoren als Zeilenvektoren verwendet: % -*- mode: octave -*function [R,D,gamma,x] = durbinlevinson(t,b) % t,b,r,gamma,x usw. sind Zeilenvektoren! % Skalarprodukt ist also z.B. t*b' !!! n=length(t); % Matrizen R und D der Choleskyzerlegung initialisieren: R=(1); delta(1)=t(1); if (delta(1)==0) error("Matrix singulaer!") end % Loesung initialisieren: x(1)=b(1)/delta(1); % Durbin Levinson Iteration: for m=1:n-1 % gamma: Schurparameter, partielle Autokorrelation % r: Szegoevektor if (m==1) gamma(m)=-t(m+1)/delta(m); else gamma(m)=-(t(m+1)+t(2:m)*r(1:m-1)')/delta(m); r(2:m)=r(1:m-1)+gamma(m)*r(m-1:-1:1); end r(1)=gamma(m); % Matrix R vergoessern, % r rechts als Spalte anhaehngen, 1 in Diagonale, % 0 in neue letzte Zeile: 7.8. AUFGABEN 251 R=[ [R; zeros(1,m) ], [r,1]']; delta(m+1)=t(1)+t(2:m+1)*r(m:-1:1)'; if (delta(m+1)==0) error("Matrix singulaer!") end % Loesung updaten: x(m+1)=(b(m+1)+b(1:m)*r(1:m)')/delta(m+1); x(1:m)=x(1:m)+x(m+1)*r(1:m); end D=diag(delta); end Abschließend ein Beispielaufruf: octave> t=[4 3 2 1] t = 4 3 2 1 octave> T=toeplitz(t) T = 4 3 2 1 3 4 3 2 2 3 4 3 1 2 3 4 Jetzt ein Gleichungssystem lösen, als rechte Seite z.B. (t0 +1, . . . , tn−1 + 1)> verwenden: octave> [R,D,gamma,x]=durbinlevinson(t,t+1) R = 252 KAPITEL 7. OCTAVE 1.00000 0.00000 0.00000 0.00000 -0.75000 1.00000 0.00000 0.00000 0.14286 -0.85714 1.00000 0.00000 0.16667 0.00000 -0.83333 1.00000 D = Diagonal Matrix 4.0000 0 0 0 0 1.7500 0 0 0 0 1.7143 0 0 0 0 1.6667 gamma = -0.75000 0.14286 0.16667 x = 1.2000e+00 -1.4988e-16 1.3878e-16 2.0000e-01 Probe für Gleichungssystem und Choleskyzerlegung: octave> T*x'-(t'+1) ans = -1.7764e-15 -8.8818e-16 -4.4409e-16 7.8. AUFGABEN 253 0.0000e+00 octave> R'*T*R-D ans = 0.0000e+00 0.0000e+00 1.1102e-16 2.7756e-17 0.0000e+00 0.0000e+00 8.3267e-17 2.5674e-16 1.1102e-16 8.3267e-17 -2.2204e-16 1.2688e-16 2.7756e-17 2.5674e-16 7.1449e-17 -2.2204e-16 Im File toeplitz.cc ist eine C++ Implementation der Funktion zur Erzeugung der Töplitzmatrix enthalten die das liboctave Interface verwendet. Beim Einsatz dieser Funktion kann man gegenüber dem oben vorgestellten m-File eine Geschwindigkeitsverbesserung um den Faktor 100 bis 1000 erwarten. #include <octave/oct.h> DEFUN_DLD (toeplitz, args, nargout, "generate a toeplitz matrix") { int nargin = args.length (); RowVector t(args(0).row_vector_value()); int n = t.length(); Matrix T(n,n); octave_stdout << "generate Toeplitz matrix with dim << " x " << n <<"\n"; for (octave_idx_type i=0;i<n;i++){ for (octave_idx_type j=i;j<n;j++){ T(i,j)=T(j,i)=t(j-i); } " << n 254 KAPITEL 7. OCTAVE } return octave_value (T); } // um Faktor 100 bis 1000 schneller als m-File Kapitel 8 Programmieren 8.1 Hilfsmittel Zum effektiven Umgang mit Compilern und anderen für das Erstellen eigener Programme wichtiger Schritte existieren verschiedene Hilfsmittel eines davon ist make, als weiteres Hilfsmittel lässt sich die Shell, speziell wegen ihrer Programmierbarkeit (siehe 2.7.1) betrachten. 8.1.1 Make Mit make lässt sich der Prozess des Herstellens eines oder mehrerer Endprodukte (Files) aus mehreren Ausgangsdateien automatisieren. Voraussetzung ist, dass die Schritte von den Ausgangsdateien zu den Enddateien auf der Kommandozeile ausführbar sind. Die Ausführung von make wird durch ein sogenanntes Makefile (eine gleichnamige Datei) gesteuert. Das Makefile enthält eine Be255 256 KAPITEL 8. PROGRAMMIEREN schreibung der Abhängigkeitsstruktur von Endfile und Ausgangsfile (über mögliche Zwischenstadien hinweg) sowie die Information, welche Kommandos für die einzelnen Schritte von Ausgangsfile zu Endfile auszuführen sind. Alle Dateien werden innerhalb des Makefiles als sog. targets, d.h. Ziele die es zu erstellen gilt, betrachtet. Ein Makefile enthält • Variablendefinitionen (ähnlich der Variablendefinition in der Shell) VAR = wert • Regeln, sie stellen eine Beschreibung der Abhängigkeit zwischen target A und evt. mehreren targets Bi und die Angabe der Befehle um von den Bi zu A zu gelangen dar. target _ A : target _ B1 target _ B2 ... target _ Bn -----> Kommando ( s ) TAB < Leerzeile > Um aus der Datei test.c z.b. den Objectcode test.o mit dem Befehl cc -c test.c -o test.o zu erstellen würde ein Makefile die Zeilen test . o : test . c -----> cc -c test . c -o test . o TAB < Leerzeile > enthalten. • implizite Regeln beschreiben verallgemeinerbare Abhängigkeiten und Erstellungsprozeduren. . suffix1 . suffix2 : -----> Kommando ( s ) TAB < Leerzeile > 8.1. HILFSMITTEL 257 In impliziten Regeln kann auf die targets links und rechts des Doppelpunkts mit $@ und $< zugegriffen werden. Das obige Beispiel könnte also einfacher test . o : test . c < Leerzeile > .c.o: -----> cc -c $ < -o $ @ TAB < Leerzeile > lauten. Da make eine gewisse Anzahl eingebauter impliziter Regeln schon kennt (u.a. zum Compilieren von C Files) würde hier sogar schon test . o : test . c < Leerzeile > ausreichen. Die Namen der targets sind dabei die entsprechenden Dateinamen. Im Falle eines einzelnen Endprodukts A beschreibt ein Makefile einen Baum mit der Wurzel A und den Blättern Bi . Die Arbeitsweise von make ist wie folgt. Nach dem Aufruf make target überprüft make ob es alle Regeln kennt die es zur Herstellung von target benötigt. Wenn ja, überprüft make welche der vorauszusetzenden Targets neueren Datums als das Zieltarget sind (wenn dies schon existiert) und arbeitet die entsprechenden Teilgraphen das Abhängigkeitsbaumes ab. Es werden also nicht alle Dateien z.B. neu kompiliert sondern nur solche bei denen z.B. Änderungen im Quelltext vorgenommen wurden. 258 KAPITEL 8. PROGRAMMIEREN 8.2 8.2.1 FORTRAN Geschichte Die Entwicklung von FORTRAN (FORmula TRANslator system) begann bei IBM im Jahr 1954 durch eine Gruppe von Entwicklern um John Backus, die 1957 FORTRAN I fertigstellten. 1962 erschien FORTRAN IV, der nächste wichtige Schritt war ANSI FORTRAN 77 (1977), das für sehr lange Zeit (eigentlich bis heute) weite Verbreitung fand. Aktuell ist FORTRAN 90 bzw. FORTRAN 95, trotzdem ist FORTRAN 77 auch heute noch von Bedeutung, da viele Anwendungen und Bibliotheken FORTRAN 77 verwenden. Im Weiteren wird deshalb auch nur auf FORTRAN 77 eingegangen. 8.2.2 Aufbau von FORTRAN Programmen Beim Editieren von FORTRAN 77 Programmtexten müssen recht strenge Regeln eingehalten werden. Einige dieser Regeln werden von modernen Compilern nicht mehr so streng eingefordert, andere aber dennoch. 8.2.2.1 Verwendbare Zeichen FORTRAN Programme dürfen aus • den Großbuchstaben A-Z (keine Umlaute), • den Ziffern 0-9, • Leerzeichen und den Sonderzeichen =+-*/(),.$' bestehen. Die Einschränkung auf Großbuchstaben trifft für aktuelle Compiler kaum mehr zu. Wenn ein FORTRAN Compiler Kleinbuchstaben akzeptiert, dann allerdings nicht case sensitiv, d.h. der Text 8.2. FORTRAN 259 wird so eingelesen als ob er in Großbuchstaben stehen würde. Man beachte, dass Zeichen wie ^, < und > aber auch | und & nicht dazugehören. 8.2.2.2 Zeilen Zeilen in FORTRAN sind auf eine Länge von 80 Zeichen beschränkt. Dies ist eine Erbschaft aus der Zeit der Lochkarten, in der jede Zeile genau einer Lochkarte entsprach. FORTRAN kennt drei Arten von Zeilen: • Kommentarzeilen, sie beginnen auf Position 1 mit C oder * (Leerzeilen werden auch als Kommentarzeilen interpretiert). • Anweisungszeilen, sie enthalten eine (eventuell nicht vollständige) Anweisung (oder mehrere durch ; getrennte Anweisungen). Sie beginnen auf Position 7, Position 6 muss ein Leerzeichen sein, Position 1 bis 5 darf eine ganzzahlige (nicht notwendigerweise aufsteigend nummerierte) Zeilenmarke enthalten. Das letzte interpretierte Zeichen steht auf Position 72. • Fortsetzungszeilen, sie enthalten auf Position 1 bis 5 Leerzeichen (also keine Marke), auf Position 6 ein beliebiges Zeichen (außer dem Leerzeichen) und in Position 7 bis 72 weitere Anweisungen oder Anweisungsteile. Verwendet man moderne Editoren wie den Emacs oder den vim, wird man beim Einhalten dieser Regeln meist in irgendeinerweise unterstützt. Im FORTRAN mode des Emacs verwendet man zum Erreichen der ersten sinnvollen Spaltenposition (Spalte 7 für Anweisungszeilen) den Tabulator, überschreibt man die Position 73 wird dies im Emacs durch Umschalten auf rote Schrift angezeigt. Der vim 260 KAPITEL 8. PROGRAMMIEREN bricht automatische auf die nächste Zeile um wenn Position 73 erreicht wird, allerdings muss man dann für das korrekte Setzen einer Zeilenfortsetzungsmarke in Spalte 6 sorgen. Die ersten 6 Postionen werden im vim farblich hervorgehoben, so dass dadurch Fehler erkennbar sind. Im Emacs vermeidet man diese Fehler durch konsequentes Benutzen der Tabulatortaste. Gibt man im Emacs als erstes Wort innerhalb einer Zeile ein (ganze) Zahl ein wird diese automatisch nach vorn in die ersten 5 Positionen als Marke gesetzt. Abbildung 8.1: FORTRAN im vim 8.2.2.3 Struktur von FORTRAN Programmen Einfache FORTRAN Programme haben den folgenden Aufbau: C C C C Name des P r o g r a m m s ( o p ti on a l ): PROGRAM PROGNAME Variablendeklarationen ... Daten ... Anweisungen 8.2. FORTRAN 261 Abbildung 8.2: FORTRAN im Emacs ... END Man kann in FORTRAN Unterprogramme und Funktionen erstellen, diese können in eigenen Quelltextdateien aber auch in der Datei mit dem PROGRAM - END Abschnitt stehen. 8.2.2.4 Unterprogramme und Funktionen Unterprogramme werden mit SUBROUTINE begonnen und enden mit END: C C C SUBROUTINE SUBNAME ( argumentliste ) V a r i a b l e n d e k l a r a t i o n e n , umfasst alle Namen aus der A r g u m e n t l i s t e ... Daten ... Anweisungen ... END 262 KAPITEL 8. PROGRAMMIEREN In FUNCTION Unterprogrammen muss eine Variable selben Namens wie die Funktion selbst deklariert und irgendwann einmal mit dem Rückgabewert beschrieben werden: C C C C FUNCTION FUNCNAME ( argumentliste ) V a r i a b l e n d e k l a r a t i o n e n , umfasst alle Namen aus der A r g u m e n t l i s UND den Namen der F un kt i on ! ... Daten ... Anweisungen , e n t h a l t e n d eine Z u w e i s u n g F UN C NA M E = wert ... RETURN END Mittels RETURN werden Unterprogramme (vor Erreichen von END) beendet. Die Parameterübergabe erfolgt per call-by-reference, d.h. Änderungen an Argumenten innerhalb des Unterprogramms werden an den Aufrufer zurückgegeben. Funktionsunterprogramme können innerhalb von Ausdrücken in der Form FUNCNAME ( ARGUMENTE ) verwendet werden. Subroutinen werden mittels CALL SUBNAME ( argumente ) aufgerufen. 8.2.2.5 Compileraufruf Ein FORTRAN Hauptprogramm wird mit $ f77 prog . f übersetzt und gelinkt, dabei entsteht die ausführbare Datei a.out die mit 8.2. FORTRAN 263 $ . / a . out aufgerufen werden kann. Mit $ f77 -c datei . f wird nur übersetzt und datei.o angelegt, diese Objektdateien können das Hauptprogramm und eine oder mehrere Unterprogramme und Funktionen enthalten. Mehrere Objektdateien werden mit $ f77 -o programm objekt . o J objekt . o ... K zum ausführbaren Programm programm gelinkt. 8.2.3 Datentypen und Variablendeklarationen 8.2.3.1 Typen FORTRAN kennt die in Tabelle 8.1 aufgeführten Datentypen. Typ Wertebereich LOGICAL INTEGER REAL DOUBLE PRECISION COMPLEX CHARACTER CHARACTER*n wahr und falsch -2147483648 bis 214783647 Betrag: 2.9E-37 bis 1.7E38 Betrag: 5.6E-308 bis 9.2E308 Real- und Imaginärteil wie REAL Zeichen Zeichenkette der Länge n Beispiel für Konstante .TRUE. und .FALSE. 1, 123, -10 1.0, -.3, 3.723E12, -3E-2 1.0D0, -2.345D10, 5D-10 i =(0,1), (-1E2,0.2) ’a’ CHARACTER*4: ’Text’ Tabelle 8.1: FORTRAN Datentypen Der Typ DOUBLE PRECISION kann auch als REAL*8 geschrieben werden, (= reelle Zahl mit 8 Byte, im Gegensatz zu REAL*4=REAL). 264 8.2.3.2 KAPITEL 8. PROGRAMMIEREN Die PARAMETER Anweisung Man kann mittels PARAMETER ( name = const J name2 = const2 ,... K ) symbolische Konstanten einführen (nicht mit Variablen verwechseln!), z.B. für π usw: REAL PI DOUBLE PRECISION ONE , ZERO PARAMETER ( PI =3.141593) PARAMETER ( ONE =1.0 D0 , ZERO =0.0 D0 ) 8.2.3.3 Variablen Im Kopfteil eines Programms (oder Unterprogramms) erfolgen die Variablendeklarationen. Variablennamen sind nur bis zum sechsten Buchstaben signifikant, d.h. die Variablen BEISPIEL und BEISPI sind identisch (diese Einschränkung ist wiederum compilerabhängig). Variablen skalaren Typs werden mittels typname varname J , varname2 , ... K angelegt, üblicherweise alle Variablen eines Typs in einer (verlängerten Zeile), aber auch mehrfache Deklarationen eines Typs wie typname varname typname varname2 sind möglich. Vektoren und Matrizen werden durch Angabe der Dimension des entsprechenden Arrays in runden Klammern nach dem Variablennamen deklariert: typname vektorname ( n ) , matrixname ( m ,n ) 8.2. FORTRAN 265 Die Feldgrößen m und n müssen als INTEGER Werte fix vorgegeben werden. Es besteht keine Möglichkeit Felder variabler Größe in FORTRAN Programmen zu erzeugen. Unterprogramme und Funktionen könne aber für Variablen beliebiger Feldgröße geschrieben werden. Dazu wird * in die Position der Dimensionsangabe gesetzt: typname vektorname ( * ) , matrixname (n , * ) Für Matrizen muß dabei allerdings die maximale Spaltenlänge bekannt sein. Das rührt daher, daß Matrizen intern als Vektor mit der Zusatzangabe einer “leading Dimension” geführt werden, dieser Vektor wird dann aller n Elemente in die einzelnen Spalten zerlegt. Diese Art der internen Speicherung bewirkt, dass Matrizen entlang ihrer Spalten (und nicht zeilenweise!) gefüllt werden. Wenn man später solche Matrizen mit Code in anderen Sprachen (z.B. C) austauscht, muß man dies beachten! Beispiele: REAL A ,B , C (5 ,5) DOUBLE PRECISION D , E (10) LOGICAL TEST , FEHLER CHARACTER * 10 VORNAME Man darf Variablen auch verwenden ohne sie zu deklarieren. Dies beruht auf der impliziten Typdeklaration. Mittels IMPLICIT typname ( an f an g sb u ch s ta b e ) kann für alle Variablen deren Name mit dem angegebenen Anfangsbuchstaben beginnt ein einheitlicher Typ deklariert werden. Standardmäßig gilt die Einstellung IMPLICIT REAL (A -H ,O - Z ) IMPLICIT INTEGER (I - N ) 266 KAPITEL 8. PROGRAMMIEREN Mittels IMPLICIT NONE lässt sich dieses Verhalten komplett abschalten (empfehlenswert, erspart Fehlersuche bei Tippfehlern in Variablennamen, diese werden sonst nämlich übergangen indem einfach eine neue Variable mit dem falschen Namen angelegt wird, was nicht beabsichtigt und nur sehr schwer zu erkennen ist!) 8.2.4 Ausdrücke Arithmetische Ausdrücke werden aus Konstanten, Parametern, Variablen, Funktionsaufrufen und den binären Operatoren +, -, *, / und ** (Potenzieren, nicht ^ !!) sowie den unären Operatoren + und sowie den runden Klammern nach den üblichen Klammerungsregeln gebildet. Bei der Division ist zu beachten, dass die Division zweier INTEGER Werte als ganzzahlige Division ausgeführt wird. Generell wird für den Typ des Resultats der “genaueste” Typ aller beteiligten Werte verwendet und die einzelnen Komponenten schrittweise in diesen Typ umgewandelt. Den Rest der ganzzahligen Division liefert die Funktion MOD(a,b). Logische Ausdrücke sind Verknüpfungen von LOGICAL-Konstanten und -Variablen sowie Bedingungen mittels .NOT., .AND., .OR., .EQV. und .NEQ.. Bedingungen werden mittels .LE. (≤), .LT. (<), .EQ. (=), .GT. (>) und .GE. (≥) sowie .NE. (6=) gebildet. Alle Vergleiche sind auf numerische Werte (INTEGER, REAL, DOUBLE PRECISION) anwendbar, auf COMPLEX nur .EQ. und .NE., auf LOGICAL nur .EQV. und .NEQ.. Vergleiche bei Zeichenketten sind lexikografische Vergleiche. Die Verkettung von Zeichenketten erfolgt mit dem Operator //. Wertzuweisungen haben die Form 8.2. FORTRAN 267 name = wert wobei der Ausdruck \meta{wert} in den Typ der Variablen \meta{name} umgewandelt wird. Mit der DATA Anweisung lassen sich bei Programmstart Anfangswerte auf Variablen schreiben: DATA name1 J , name2 ,... K / wert1 J , wert2 ,... K / z.B. DOUBLE PRECISION A , B DATA A , B / 1.0 D0 ,3.4 D10 / 8.2.5 Ein- und Ausgabe Variablen kann man mittels READ ( * ,* ) variable von der Standardeingabe lesen und mittels WRITE ( * ,* ) variable am Bildschirm wieder ausgeben. Soll dabei das Ausgabeformat der Werte genau vorgegeben werden muss als zweiter Parameter in READ oder WRITE die Marke einer Zeile mit einem FORMAT Befehl oder der FMT Parameter von READ oder WRITE angegeben werden, also WRITE ( * , marke ) variable ( n ) marke FORMAT ( formatangabe ) oder WRITE ( * , FMT = formatangabe ) variable ( n ) 268 KAPITEL 8. PROGRAMMIEREN Formatangaben bestehen aus einer kommagetrennten Aufzählung von Zeichenketten und Platzhaltern für die einzelnen Variablen, je nach Datentyp wird • Ia: INTEGER, a Stellen • Fa.b: Festkommadarstellung mit (max.) a Positionen (Ziffern, Dezimalpunkt und evt. Vorzeichen) und genau b Nachkommastellen, • Ea.b: Exponentialdarstellung, a Positionen (Ziffern, Dezimalpunkt, evt. Vorzeichen und 4 Zeichen für Exponent (mit Vorzeichen)), b Nachkommastellen, • Da.b: wie Ea.b, aber für DOUBLE PRECISION, d.h. Exponent bis zu dreistellig. • A: für Zeichenketten. 8.2.5.1 Dateioperationen Wenn Dateien gelesen oder geschrieben werden sollen, sind sie zuerst zu öffnen und einer I/O UNIT zuzuordnen. Diese werden durch positive Integerwerte benannt: OPEN ( UNIT = unitnummer , FILE = ' dateiname ') Im nachfolgenden Programmtext kann nun diese UNIT als erster Parameter der WRITE oder READ Anweisung eingesetzt werden. Die Datei wird dabei sequentiell (zeilenweise) verarbeitet. Mit REWIND und BACKSPACE kann an den Dateianfang oder eine Zeile zurückgesprungen werden. Beispiel: 8.2. FORTRAN 10 20 269 PROGRAM TEST INTEGER N REAL * 8 D OPEN ( UNIT =1 , FILE = ' datei . txt ') READ (1 ,10) N FORMAT ( I8 ) WRITE (1 ,20)2.0 * N FORMAT ( ' doppelt : ' , D16 .8) REWIND (1) READ (1 ,10) N WRITE ( * ,* ) N READ (1 ,20) D WRITE ( * ,* ) D END Ausgabe: agebhard@epsilon[FORTRAN]$ agebhard@epsilon[FORTRAN]$ 12 agebhard@epsilon[FORTRAN]$ 12 24. agebhard@epsilon[FORTRAN]$ 12 doppelt: 0.24000000E+02 f77 test.f cat datei.txt ./a.out cat datei.txt 8.2.6 Steueranweisungen 8.2.6.1 Bedingungen Die einfache IF Anweisung (logisches IF) lautet IF ( bedingung ) anweisung 270 KAPITEL 8. PROGRAMMIEREN Die Block-IF Anweisung hat die Form IF ( bedingung ) THEN anweisung ( en ) END IF bzw. IF ( bedingung ) THEN anweisung ( en ) ELSE anweisung ( en ) END IF oder IF ( bedingung ) THEN anweisung ( en ) ELSE IF ( bedingung ) THEN anweisung ( en ) ELSE IF ... ... ELSE anweisung ( en ) END IF (END IF kann auch ENDIF geschrieben werden, analog ELSE IF) 8.2.6.2 Schleifen und Verzweigungen Mittels GOTO marke können die in den ersten 5 Spalten definierten Markennamen angesprungen werden (nicht über Unterprogrammgrenzen hinweg). Mit der arithmetischen GOTO Anweisung wird je nach Wert (1,2,3,...) der 8.2. FORTRAN 271 verwendeten Variablen an die erste, zweite, dritte, ... angegebene Marke gesprungen: GOTO ( marke1 , marke2 ,...) varname Iterationsschleifen werden in der Form DO marke laufvariable = von , bis J , schrittweite K anweisung ( en ) marke CONTINUE geschrieben, CONTINUE ist übrigens die leere Anweisung und wird hier als “Aufhänger” für die die Schleife begrenzende Marke verwendet. Beispiel: C Summe der Zahlen von 1 bis 100 INTEGER SUMME , I SUMME =0 DO 10 I =1 ,100 SUMME = SUMME + I 10 CONTINUE 8.2.7 Beispiel - lineare Interpolation Als einfaches Beispiel wird nun die Aufgabe der linearen Interpolation für einen Datensatz {(xi , yi )|i = 1, . . . , n} in mehreren Varianten gelöst. Einfache Variante, Daten fix eingetragen mittels DATA In der ersten Version erhält das Testprogramm die Daten über eine DATA Anweisung. Zuerst werden die Daten ausgegeben (xi mit einfachem WRITE, yi mit FORMAT-gesteuertem WRITE), dann wird ein x0 Wert gelesen und der zugehörige interpolierte Wert ausgegeben. Voraussetzung ist, dass die x Werte schon sortiert vorliegen. Liegt x0 272 KAPITEL 8. PROGRAMMIEREN Abbildung 8.3: lineare Interpolation 8.2. FORTRAN 273 außerhalb des Wertebereichs der xi bricht das Programm mit einer Fehlermeldung ab. PROGRAM INTERP IMPLICIT NONE C lineare I n t e r p o l a t i o n : DOUBLE PRECISION X (5) , Y (5) , X0 , Y0 , XL , XR , YL , YR INTEGER I , N LOGICAL EXTRAP DATA N / 5 / C X muss schon s or t ie rt sein ! ! DATA X / 1.0 ,3.0 ,3.5 ,6 ,7 / DATA Y / 0 , 2.0 ,10.5 ,3 E -4 , -3.5 E20 / EXTRAP =. TRUE . WRITE ( * ,* ) ' lineare Interpolation ' WRITE ( * ,* ) ' = = = = = = = = = = = = = = = = = = = = = ' C e i nf a ch e l i s t g e s t e u e r t e Ausgabe der X Werte DO 10 I =1 , N WRITE ( * ,* ) 'X ( ' ,I , ' )= ' ,X ( I ) 10 CONTINUE C e i nf a ch e l i s t g e s t e u e r t e Ausgabe der X Werte DO 30 I =1 , N WRITE ( * ,20) I , Y ( I ) 20 FORMAT ( 'Y ( ' ,I1 , ' )= ' , E16 .8) 30 CONTINUE C X0 e in l es en : WRITE ( * ,* ) ' X0 eingeben : ' READ ( * ,* ) X0 DO 40 I =1 ,N -1 XL = X ( I ); XR = X ( I +1) C V e r m e i d u n g von D i vi s io n durch Null IF ( X ( I ). NE . X ( I +1)) THEN 274 KAPITEL 8. PROGRAMMIEREN YL = Y ( I ); YR = Y ( I +1) IF ( XL . LE . X0 . AND . X0 . LT . XR ) THEN Y0 = YL +( YR - YL ) / ( XR - XL ) * ( X0 - XL ) EXTRAP =. FALSE . END IF ELSE C Fehler , Abbruch WRITE ( * ,* ) 'X Werte ' ,I , ' und ' ,I +1 , ' sind identisch ! ! ' RETURN END IF 40 CONTINUE C E r ge b ni s a u sg eb e n IF ( EXTRAP ) THEN WRITE ( * ,* ) ' X0 ausserhalb des Wertebereichs von X ( * ) ' ELSE WRITE ( * ,* ) ' Ergebnis fuer X0 = ' ,X0 , ': ' , Y0 END IF END Verbesserte Variante, mit Sortierung Für die zweite Variante wurde der DSORT1 Algorithmus der SLATEC2 Library eingebaut. PROGRAM INTERP2 IMPLICIT NONE C lineare I n t e r p o l a t i o n : DOUBLE PRECISION X (5) , Y (5) , X0 , Y0 , XL , XR , YL , YR INTEGER I , N LOGICAL EXTRAP DATA N / 5 / C X muss nicht mehr s or t ie rt sein ! ! 1 http://netlib.org/cgi-bin/netlibfiles.pl?filename=slatec/src/ dsort.f 2 http://netlib.org/slatec/ 8.2. FORTRAN 275 DATA X / 3.0 ,0 ,3.5 ,6 ,7 / DATA Y / 0 , 2.0 ,10.5 ,3 E -4 , -3.5 E20 / EXTRAP =. TRUE . WRITE ( * ,* ) ' lineare Interpolation ' WRITE ( * ,* ) ' = = = = = = = = = = = = = = = = = = = = = ' C Daten s o r t i e r e n : CALL DSORT (X ,Y ,N ,2) C e i nf a ch e l i s t g e s t e u e r t e Ausgabe der X Werte DO 10 I =1 , N WRITE ( * ,* ) 'X ( ' ,I , ' )= ' ,X ( I ) 10 CONTINUE C e i nf a ch e l i s t g e s t e u e r t e Ausgabe der X Werte DO 30 I =1 , N WRITE ( * ,20) I , Y ( I ) 20 FORMAT ( 'Y ( ' ,I1 , ' )= ' , E16 .8) 30 CONTINUE C X0 e in l es en : WRITE ( * ,* ) ' X0 eingeben : ' READ ( * ,* ) X0 DO 40 I =1 ,N -1 XL = X ( I ); XR = X ( I +1) C V e r m e i d u n g von D i vi s io n durch Null IF ( X ( I ). NE . X ( I +1)) THEN YL = Y ( I ); YR = Y ( I +1) IF ( XL . LE . X0 . AND . X0 . LT . XR ) THEN Y0 = YL +( YR - YL ) / ( XR - XL ) * ( X0 - XL ) EXTRAP =. FALSE . END IF ELSE C Fehler , Abbruch WRITE ( * ,* ) 'X Werte ' ,I , ' und ' ,I +1 , ' sind identisch ! ! ' RETURN END IF 40 CONTINUE 276 KAPITEL 8. PROGRAMMIEREN C E r ge b ni s a u sg eb e n IF ( EXTRAP ) THEN WRITE ( * ,* ) ' X0 ausserhalb des Wertebereichs von X ( * ) ' ELSE WRITE ( * ,* ) ' Ergebnis fuer X0 = ' ,X0 , ': ' , Y0 END IF END Verbesserte Variante, Daten aus Datei In dieser Version werden die Daten nicht mehr über DATA Blöcke sondern mittels formatgesteuerten READ Anweisungen aus einer Datei gelesen. PROGRAM INTERP3 IMPLICIT NONE C lineare I n t e r p o l a t i o n : INTEGER MAXN PARAMETER ( MAXN =1000) DOUBLE PRECISION X ( MAXN ) , Y ( MAXN ) , X0 , Y0 , XL , XR , YL , YR INTEGER I , N LOGICAL EXTRAP C Daten f o r m a t i e r t aus Datei lesen : OPEN ( UNIT =1 , FILE = ' daten . txt ') READ (1 ,5) N 5 FORMAT ( ' Anzahl : ' , I4 ) WRITE ( * ,* ) ' Lese ' ,N , ' Zeilen ... ' DO 9 I =1 , N READ (1 ,8) X0 , Y0 8 FORMAT ( D12 .4 , ' , ' , D12 .4) X ( I )= X0 ; Y ( I )= Y0 9 CONTINUE 8.2. FORTRAN 277 EXTRAP =. TRUE . WRITE ( * ,* ) ' lineare Interpolation ' WRITE ( * ,* ) ' = = = = = = = = = = = = = = = = = = = = = ' C Daten s o r t i e r e n : CALL DSORT (X ,Y ,N ,2) C e i nf a ch e l i s t g e s t e u e r t e Ausgabe der X Werte DO 10 I =1 , N WRITE ( * ,* ) 'X ( ' ,I , ' )= ' ,X ( I ) 10 CONTINUE C e i nf a ch e l i s t g e s t e u e r t e Ausgabe der X Werte DO 30 I =1 , N WRITE ( * ,20) I , Y ( I ) 20 FORMAT ( 'Y ( ' ,I1 , ' )= ' , E16 .8) 30 CONTINUE C X0 e in l es en : WRITE ( * ,* ) ' X0 eingeben : ' READ ( * ,* ) X0 DO 40 I =1 ,N -1 XL = X ( I ); XR = X ( I +1) C V e r m e i d u n g von D i vi s io n durch Null IF ( X ( I ). NE . X ( I +1)) THEN YL = Y ( I ); YR = Y ( I +1) IF ( XL . LE . X0 . AND . X0 . LT . XR ) THEN Y0 = YL +( YR - YL ) / ( XR - XL ) * ( X0 - XL ) EXTRAP =. FALSE . END IF ELSE C Fehler , Abbruch WRITE ( * ,* ) 'X Werte ' ,I , ' und ' ,I +1 , ' sind identisch ! ! ' RETURN END IF 40 CONTINUE C E r ge b ni s a u sg eb e n IF ( EXTRAP ) THEN 278 KAPITEL 8. PROGRAMMIEREN WRITE ( * ,* ) ' X0 ausserhalb des Wertebereichs von X ( * ) ' ELSE WRITE ( * ,* ) ' Ergebnis fuer X0 = ' ,X0 , ': ' , Y0 END IF END Variante mit Unterprogramm Abschließend wurde die eigentlich Rechnung von den I/O Anweisungen getrennt und in eine SUBROUTINE ausgelagert. PROGRAM INTERP4 IMPLICIT NONE C lineare I n t e r p o l a t i o n : INTEGER MAXN PARAMETER ( MAXN =1000) DOUBLE PRECISION X ( MAXN ) , Y ( MAXN ) , X0 , Y0 , XL , XR , YL , YR INTEGER I ,N , IERR C Daten f o r m a t i e r t aus Datei lesen : OPEN ( UNIT =1 , FILE = ' daten . txt ') READ (1 ,5) N 5 FORMAT ( ' Anzahl : ' , I4 ) WRITE ( * ,* ) ' Lese ' ,N , ' Zeilen ... ' DO 9 I =1 , N READ (1 ,8) X0 , Y0 8 FORMAT ( D12 .4 , ' , ' , D12 .4) X ( I )= X0 ; Y ( I )= Y0 9 CONTINUE C Daten s o r t i e r e n : CALL DSORT (X ,Y ,N ,2) C e i nf a ch e l i s t g e s t e u e r t e Ausgabe der X Werte DO 10 I =1 , N 8.2. FORTRAN 10 279 WRITE ( * ,* ) 'X ( ' ,I , ' )= ' ,X ( I ) CONTINUE C e i nf a ch e l i s t g e s t e u e r t e Ausgabe der X Werte DO 30 I =1 , N WRITE ( * ,20) I , Y ( I ) 20 FORMAT ( 'Y ( ' ,I1 , ' )= ' , E16 .8) 30 CONTINUE C X0 e in l es en : WRITE ( * ,* ) ' X0 eingeben : ' READ ( * ,* ) X0 CALL INTERP (X ,Y , X0 , Y0 ,N , IERR ) C E r ge b ni s a u sg eb e n IF ( IERR . EQ . -1) THEN WRITE ( * ,* ) ' X0 ausserhalb des Wertebereichs von X ( * ) ' ELSE IF ( IERR . GT .0) THEN WRITE ( * ,* ) 'X Werte ' , IERR , ' und ' , IERR +1 , ' sind identisch ! ! ' ELSE WRITE ( * ,* ) ' Ergebnis fuer X0 = ' ,X0 , ': ' , Y0 END IF END SUBROUTINE INTERP (X ,Y , X0 , Y0 ,N , IERR ) IMPLICIT NONE INTEGER N , IERR , I DOUBLE PRECISION X ( * ) , Y ( * ) , X0 , Y0 , XL , XR , YL , YR LOGICAL EXTRAP EXTRAP =. TRUE . IERR =0 WRITE ( * ,* ) ' lineare Interpolation ( SUBROUTINE ) ' WRITE ( * ,* ) ' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ' DO 40 I =1 ,N -1 XL = X ( I ); XR = X ( I +1) C V e r m e i d u n g von D i vi s io n durch Null IF ( X ( I ). NE . X ( I +1)) THEN 280 KAPITEL 8. PROGRAMMIEREN YL = Y ( I ); YR = Y ( I +1) IF ( XL . LE . X0 . AND . X0 . LT . XR ) THEN Y0 = YL +( YR - YL ) / ( XR - XL ) * ( X0 - XL ) EXTRAP =. FALSE . END IF ELSE C Fehler , Abbruch , IERR setzen IERR = I RETURN END IF 40 CONTINUE IF ( EXTRAP ) IERR = -1 RETURN END 8.2.8 Anwendung: LAPACK Eine der bedeutendsten auf http://www.netlib.org angebotenen Numeriklibraries ist LAPACK, ein Paket für numerische lineare Algebra (Linear Algebra PACKage). Eine ausführliche Dokumentation dazu ist Anderson et al. [1999]. Funktionen der LAPACK Library folgen meistens einem Namensschema bei dem der erste Buchstabe der Funktion den Typ der beteiligten Argumente (S=sinlge für REAL, D für DOUBLE PRECISION und C für COMPLEX) angibt. Im folgenden werden die Funktionen jeweils für DOUBLE PRECISION vorgestellt. 8.2. FORTRAN 8.2.8.1 281 Einfache Vektor- und Matrixoperationen Die Funktionen der LAPACK Bibliothek bauen wiederum auf denen der BLAS3 Library (Basic Linear Algebra Subprograms) auf. Sie stellen die wesentlichen Operationen für das Rechnen mit Vektoren und Matrizen zur Verfügung. Die Performance von LAPACK Routinen hängt in wesentlichem Maß von der Performance der darunterliegenden BLAS Routinen ab. Aus diesem Grund werden meist speziell für die einzelnen Rechnerarchitekturen optimierte Varianten der BLAS Library eingesetzt, so z.B. unter Digital UNIX bzw. Tru64 UNIX auf Alpha Prozessoren die DXML bzw. CXML4 oder die Sun Performance Library für SPARC Prozessoren5 . Für Intel Prozessoren steht die ATLAS (Automatically Tuned Linear Algebra Software) Library zur Verfügung6 Die wichtigsten elementaren BLAS Routinen sind7 (für DOUBLE PRECISION angegeben) • Kopieren eines Vektors / einer Matrix: y = x DCOPY (Double COPY) Aufruf SUBROUTINE c c c c c c DCOPY (N , DX , INCX , DY , INCY ) copies a vector , x , to a vector , y . uses u nr o ll e d loops for i n c r e m e n t s equal to one . jack dongarra , linpack , 3 / 11 / 78. m od i fi e d 12 / 3 / 93 , array (1) d e c l a r a t i o n s changed to array ( * ) DOUBLE PRECISION DX ( * ) , DY ( * ) INTEGER N , INCX , INCY 3 http://www.netlib.org/blas 4 http://h18000.www1.hp.com/math/ 5 http://docs.sun.com/source/817-0935/index.html 6 http://math-atlas.sourceforge.net/ 7 Eine vollständige Übersicht bietet http://www.netlib.no/netlib/blas/ 282 KAPITEL 8. PROGRAMMIEREN Da Matrizen intern auch als Vektoren gespeichert werden, lassen sie sich ebenfalls mit DCOPY kopieren wenn man für N entsprechend Zeilenzahl × Spaltenzahl einsetzt. Durch geschickte Wahl der Indexinkrementwerte lassen sich auch einzelne Zeilen von Matrizen kopieren (Inkrement=Spaltenlänge, N=Zeilenlänge wählen), Spalten von Matrizen lassen sich durch Angabe des jeweils ersten Elements und Beschränkung von N auf die Spaltenlänge kopieren. • Multiplikation eines Vektors mit einem Skalar: α · x DSCAL (Double SCALar multiplication) Aufruf SUBROUTINE DSCAL (N , DA , DX , INCX ) C C C C C C C scales a vector by a c o ns t an t . uses u nr o ll e d loops for i n c r e m e n t equal to one . jack dongarra , linpack , 3 / 11 / 78. m o di fi e d 3 / 93 to return if incx . le . 0. m od i fi e d 12 / 3 / 93 , array (1) d e c l a r a t i o n s changed to array ( DOUBLE PRECISION DA , DX ( * ) INTEGER N , INCX DA=α, DX=x ∈ Rn , INCX=Indexinkrement in x, üblicherweise 1 (Durch geschickte Wahl des Indexinkrements kann man damit Zeilen einer Matrix als Vektor verwenden ohne sie umkopieren zu müssen, in diesem Fall muss die leading dimension der Matrix als Inkrement verwendet werden) • Vektoraddition: x + y DAXPY (Double A times X Plus Y) Aufruf implementiert: (Ergebnis steht auf y) y = αx + y 8.2. FORTRAN 283 SUBROUTINE DAXPY (N , DA , DX , INCX , DY , INCY ) C C C C C C C ON S TA N T TIMES A VECTOR PLUS A VECTOR . USES U NR O LL E D LOOPS FOR I N C R E M E N T S EQUAL TO ONE . JACK DONGARRA , LINPACK , 3 / 11 / 78. M OD I FI E D 12 / 3 / 93 , ARRAY (1) D E C L A R A T I O N S CHANGED TO ARRAY ( * ) DOUBLE PRECISION DX ( * ) , DY ( * ) , DA INTEGER INCX , INCY , N • Skalarprodukt: xT y DDOT (Double DOT product) DOUBLE PRECISION FUNCTION DDOT (N , DX , INCX , DY , INCY ) C C C C C C forms the dot product of two vectors . uses u nr o ll e d loops for i n c r e m e n t s equal to one . jack dongarra , linpack , 3 / 11 / 78. m od i fi e d 12 / 3 / 93 , array (1) d e c l a r a t i o n s changed to array ( * ) DOUBLE PRECISION DX ( * ) , DY ( * ) INTEGER INCX , INCY , N • Vektor-Matrix Produkt Ax: DGEMV (Double GEnereal Matrix-Vector product) implementiert y = αAx + βy wobei A wahlweise transponiert wird. y muss sinnvoll initialisiert werden (oder β = 0 setzen)! $ C C SUBROUTINE DGEMV ( TRANS , M , N , ALPHA , A , LDA , X , INCX , BETA , Y , INCY ) .. Scalar A r g u m e n t s .. DOUBLE PRECISION ALPHA , BETA INTEGER INCX , INCY , LDA , M , N CHARACTER * 1 TRANS .. Array A r g u m e n t s .. DOUBLE PRECISION A ( LDA , * ) , X ( * ) , Y ( * ) 284 KAPITEL 8. PROGRAMMIEREN C C C C C C C C C C .. where alpha and beta are scalars , x and y are vectors and A C m by n matrix . Purpose ======= DGEMV p er f or ms one of the matrix - vector o p e r a t i o n s y := alpha * A * x + beta *y , or y := alpha *A ' * x + beta *y , • Matrixmultiplikation AB: DGEMM (Double GEnereal Matrix-Matrix product) implementiert C = αAB + βC wobei A und B wahlweise transponiert werden. C muss sinnvoll initialisiert werden (oder β = 0 setzen)! $ C C C C C C C C C C C C C SUBROUTINE DGEMM ( TRANSA , TRANSB , M , N , K , ALPHA , A , LDA BETA , C , LDC ) .. Scalar A r g u m e n t s .. CHARACTER * 1 TRANSA , TRANSB INTEGER M , N , K , LDA , LDB , LDC DOUBLE PRECISION ALPHA , BETA .. Array A r g u m e n t s .. DOUBLE PRECISION A ( LDA , * ) , B ( LDB , * ) , C ( LDC , * ) .. Purpose ======= DGEMM p er f or ms one of the matrix - matrix o p e r a t i o n s C := alpha * op ( A ) * op ( B ) + beta *C , where op ( X ) is one of 8.2. FORTRAN 285 C op ( X ) = X or op ( X ) = X ' , C C alpha and beta are scalars , and A , B and C are matrices , with op ( C an m by k matrix , op ( B ) a k by n matrix and C an m by n matrix . Für (fast) alle BLAS und LAPACK Routinen existieren Manpages die man wie üblich mit man (oder Alt - x manual-page im Emacs) anzeigen lassen kann. 8.2.8.2 Lineare Gleichungssysteme Matrixgleichungssystem (Gleichungssystem mit mehreren rechten Seiten) A·X=B DGESV für allgemeine Matrizen (Double GEneral matrix SolVer) SUBROUTINE DGESV ( N , NRHS , A , LDA , IPIV , B , LDB , INFO ) C C C C C C C C C C C C C C C -- LAPACK driver routine ( version 3.0) -Univ . of Tennessee , Univ . of C a l i f o r n i a Berkeley , NAG Ltd . , Courant Institute , Argonne Na t io na l Lab , and Rice U n i v e r s i t y March 31 , 1993 .. Scalar A r g u m e n t s .. INTEGER INFO , LDA , LDB , N , NRHS .. .. Array A r g u m e n t s .. INTEGER IPIV ( * ) DOUBLE PRECISION A ( LDA , * ) , B ( LDB , * ) .. Purpose ======= DGESV co m pu t es the s o lu t io n to a real system of linear e q u a t i o n s 286 C C C C C C C C C KAPITEL 8. PROGRAMMIEREN A * X = B, where A is an N - by - N matrix and X and B are N - by - NRHS ma tr i ce s . The LU d e c o m p o s i t i o n with partial pi vo t in g and row i n t e r c h a n g e s i used to factor A as A = P * L * U, where P is a p e r m u t a t i o n matrix , L is unit lower triangular , and upper t r i a n g u l a r . The f a ct or e d form of A is then used to solve t system of e q u a t i o n s A * X = B . C Grundlage für DGESV ist die BLAS Subroutine DTRSV (Double Triangular SolVer) * * * * * * * * * * * * * * * * SUBROUTINE DTRSV ( UPLO , TRANS , DIAG , N , A , LDA , X , INCX ) .. Scalar Arguments .. INTEGER INCX , LDA , N CHARACTER * 1 DIAG , TRANS , UPLO .. Array Arguments .. DOUBLE PRECISION A ( LDA , * ) , X ( * ) .. Purpose ======= DTRSV solves one of the systems of equations A*x = b, or A '* x = b , where b and x are n element vectors and A is an n by n unit , or non - unit , upper or lower triangular matrix . No test for singularity or near - singularity is included in this routine . Such tests must be performed before calling this routine für tridiagonale Matrizen A: DGTSV (Double General Tridiagonal SolVer) 8.2. FORTRAN 287 SUBROUTINE DGTSV ( N , NRHS , DL , D , DU , B , LDB , INFO ) C C C C C C C C C C C C C C C C C C C C C C C -- LAPACK routine ( version 3.0) -Univ . of Tennessee , Univ . of C a l i f o r n i a Berkeley , NAG Ltd . , Courant Institute , Argonne Na t io na l Lab , and Rice U n i v e r s i t y October 31 , 1999 .. Scalar A r g u m e n t s .. INTEGER INFO , LDB , N , NRHS .. .. Array A r g u m e n t s .. DOUBLE PRECISION B ( LDB , * ) , D ( * ) , DL ( * ) , DU ( * ) .. Purpose ======= DGTSV solves the e q ua ti o n A*X = B, where A is an n by n t r i d i a g o n a l matrix , by Ga us s ia n e l i m i n a t i o n with partial p i vo ti n g . Note that the e q ua t io n A ' * X = B may be solved by i n t e r c h a n g i n g the order of the a r g u m e n t s DU and DL . 8.2.8.3 Eigenwertaufgaben Eigenwerte und -vektoren einer symmetrischen Matrix: A = U diag(w) U> DSYEV (Double SYmmetric Eigenvalues and eigenVectors) U überschreibt A!! SUBROUTINE DSYEV ( JOBZ , UPLO , N , A , LDA , W , WORK , LWORK , INFO ) C 288 C C C C C C KAPITEL 8. PROGRAMMIEREN -- LAPACK driver routine ( version 3.0) -Univ . of Tennessee , Univ . of C a l i f o r n i a Berkeley , NAG Ltd . , Courant Institute , Argonne Na t io na l Lab , and Rice U n i v e r s i t y June 30 , 1999 .. Scalar A r g u m e n t s .. CHARACTER JOBZ , UPLO INTEGER INFO , LDA , LWORK , N .. .. Array A r g u m e n t s .. DOUBLE PRECISION A ( LDA , * ) , W ( * ) , WORK ( * ) .. C C C C C C C C DSYEV co m pu t es all e i g e n v a l u e s and , optionally , e i g e n v e c t o r s of a C real s y m m e t r i c matrix A . Purpose ======= Singularwertzerlegung einer beliebigen Matrix: A = U diag(s) V> DGESVD (Double GEneral matrix Singular Value Decompostion) Es wird V> zurückgeliefert, nicht V!! $ C C C C C C C C C SUBROUTINE DGESVD ( JOBU , JOBVT , M , N , A , LDA , S , U , LDU , VT , L WORK , LWORK , INFO ) -- LAPACK driver routine ( version 3.0) -Univ . of Tennessee , Univ . of C a l i f o r n i a Berkeley , NAG Ltd . , Courant Institute , Argonne Na t io na l Lab , and Rice U n i v e r s i t y October 31 , 1999 .. Scalar A r g u m e n t s .. CHARACTER JOBU , JOBVT INTEGER INFO , LDA , LDU , LDVT , LWORK , M , N .. .. Array A r g u m e n t s .. 8.2. FORTRAN DOUBLE PRECISION $ C C C C C C C C C C C C C C C C C C C 289 A ( LDA , * ) , S ( * ) , U ( LDU , * ) , VT ( LDVT , * ) , WORK ( * ) .. Purpose ======= DGESVD c om p ut es the si n gu la r value d e c o m p o s i t i o n ( SVD ) of a real M - by - N matrix A , o p t i o n a l l y c o m p u t i n g the left and / or right s in gu l ar vectors . The SVD is written A = U * SIGMA * t r a n s p o s e ( V ) where SIGMA is an M - by - N matrix which is zero except for its min (m , n ) d i ag o na l elements , U is an M - by - M o r t h o g o n a l matrix , and V is an N - by - N o r t h o g o n a l matrix . The di ag o na l e l em e nt s of SIGMA are the s i ng ul a r values of A ; they are real and non - negative , and are r e tu r ne d in d e s c e n d i n g order . The first min (m , n ) columns of U and V are the left and right s in gu l ar vectors of A . Note that the routine returns V * *T , not V . Bei komplizierteren LAPACK Funktionen sind i.d.R. entsprechend mehr Parameter anzugeben, von denen ein Teil meist sog. “working arrays”, also nur Hilfsvariablen sind. Die Größe dieser Hilfsarrays hängt dann von der Größe der anderen Eingangsparameter ab. Meist existiert bei solchen LAPACK Funktionen dann eine spezielle Aufrufvariante, bei der man lediglich die Größen der Eingangsparameter angibt und als Rückgabe auf einem speziellen Parameter die optimale Größe der Hilfsarrays abliest. 290 KAPITEL 8. PROGRAMMIEREN 8.2.8.4 Beispiele Folgende Aufgaben sind mit LAPACK Funktionen zu lösen. Gegeben seien Vektoren > u = 1 −1 1 −1 1 −1 > v = 1 4 2 5 3 6 > b = 1 2 3 4 5 6 1. Bestimmen Sie die Matrix M = uv > − vu> + I wobei I die entsprechende Einheitsmatrix ist. 2. Lösen sie das Gleichungssystem Mx = b 3. Bestimmen Sie den Fehlervektor Mx − b sowie dessen Norm, verwenden Sie die BLAS Funktion DNRM2. 4. Nach welchem Prinzip sind die Vektoren u, v und b aufgebaut, verallgemeinern Sie das Programm zur Lösung von 2 für beliebige Dimension n. 5. Dem Gleichungssystem werde eine Zeile mit lauter 1en hinzugefügt. Das entstehende überbestimmte Gleichungssystem ist i.d.R. nicht lösbar. Es läßt sich jedoch ein Vektor x so bestimmen daß der Fehler ||Mx − b||2 minimal wird. Dies wird durch die LAPACK Funktion DGELS implementiert. Bestimmen Sie damit die Minimum-Norm Lösung des überbestimmten Systems sowie die Norm der Abweichung. 8.2. FORTRAN 291 6. Streichen Sie aus dem Gleichungssystem 2 die letzte Zeile. Das entstehende unterbestimmte System ist nicht mehr eindeutig lösbar. Die Funktion DGELS bestimmt in diesem Fall jenen Lösungsvektor der minimale Norm hat. Lösen Sie dies. 7. Eine weitere Möglichkeit ein überbestimmtes Gleichungssystem zu lösen besteht darin für gewisse Zeilen das Gleichungssystems die exakte Lösung zu fordern und die restlichen nur im Sinne minimalen Fehlers zu lösen. Hierzu verwenden Sie die LAPACK Funktion DGGLSE. Lösen Sie das um eine Zeile erweiterte System so, dass das ursprüngliche System exakt, die zusätzliche Zeile näherungsweise gelöst werden. 8. Zusatzaufgabe: Überprüfen Sie die Ergebnisse in Octave! Lösungen: Aufgabe 1,2,3: PROGRAM LAPACK IMPLICIT NONE DOUBLE PRECISION DNRM2 EXTERNAL DNRM2 INTEGER MAXN PARAMETER ( MAXN =6) $ C DOUBLE PRECISION U ( MAXN ) , V ( MAXN ) , B ( MAXN ) , MAT ( MAXN , MAXN ) , MCPY ( MAXN , MAXN ) , BCPY ( MAXN ) INTEGER I ,J ,N , INFO , IPIV ( MAXN ) N =6 DATA U / 1.0 D0 , -1.0 D0 , 1.0 D0 , -1.0 D0 , 1.0 D0 , -1.0 D0 / DATA V / 1.0 D0 , 4.0 D0 , 2.0 D0 , 5.0 D0 , 3.0 D0 , 6.0 D0 / DATA B / 1.0 D0 , 2.0 D0 , 3.0 D0 , 4.0 D0 , 5.0 D0 , 6.0 D0 / MAT = U * V ^ T CALL DGEMM ( 'N ' , 'T ' ,N ,N ,1 ,1.0 D0 ,U , MAXN ,V , MAXN ,0.0 D0 , MAT , MAXN ) 292 KAPITEL 8. PROGRAMMIEREN C MAT = MAT + V * U ^ T CALL DGEMM ( 'N ' , 'T ' ,N ,N ,1 , -1.0 D0 ,V , MAXN ,U , MAXN ,1.0 D0 , MAT , MAXN ) C 10 MAT = MAT + I DO 10 I =1 , N MAT (I , I )= MAT (I , I )+1.0 D0 CONTINUE 20 DO 20 I =1 , N WRITE ( * , ' (7 F8 .1) ' )( MAT (I , J ) , J =1 , N ) , B ( I ) CONTINUE C MAT und B sichern CALL DCOPY (N ,B ,1 , BCPY ,1) CALL DCOPY ( N *N , MAT ,1 , MCPY ,1) C GLS loesen CALL DGESV (N ,1 , MAT , MAXN , IPIV ,B , MAXN , INFO ) C Loesung : WRITE ( * ,* ) " INFO : " , INFO DO 40 I =1 , N WRITE ( * ,* ) " X ( " ,I , " )= " ,B ( I ) CONTINUE 40 C 50 Fehler b e s t i m m e n : ERR =B - MAT * X CALL DGEMV ( 'N ' ,N ,N ,1.0 D0 , MCPY , MAXN ,B ,1 , -1.0 D0 , BCPY ,1) DO 50 I =1 , N WRITE ( * ,* ) " Fehler ( " ,I , " )= " , BCPY ( I ) CONTINUE WRITE ( * ,* ) " Norm des Fehlers : " , DNRM2 (N , BCPY ,1) END agebhard@pc28 - math [ lapack ] $ f77 a1 . f -o a1 - lblas - llapack agebhard@pc28 - math [ lapack ] $ . / a1 1.0 5.0 1.0 6.0 2.0 7.0 1.0 -5.0 1.0 -6.0 -1.0 -7.0 -2.0 2.0 -1.0 6.0 1.0 7.0 1.0 8.0 3.0 8.2. FORTRAN -6.0 1.0 -7.0 1.0 -2.0 7.0 -1.0 8.0 -7.0 2.0 -8.0 1.0 INFO : 0 X ( 1)= -1.31545064 X ( 2)= -0.963519313 X ( 3)= -0.371244635 X ( 4)= -0.0193133047 X ( 5)= 0.572961373 X ( 6)= 0.924892704 Fehler ( 1)= -3.33066907 E -16 Fehler ( 2)= 1.23165367 E -15 Fehler ( 3)= -2.49800181 E -16 Fehler ( 4)= -3.43475248 E -16 Fehler ( 5)= -2.77555756 E -17 Fehler ( 6)= -1.23165367 E -15 Norm des Fehlers : 1.82373815 E -15 293 -8.0 1.0 -9.0 -1.0 9.0 1.0 4.0 5.0 6.0 Aufgabe 4: TODO Aufgabe 5: PROGRAM LAPACK IMPLICIT NONE C externe Fu n kt i on DNRM2 : DOUBLE PRECISION DNRM2 EXTERNAL DNRM2 INTEGER MAXN , MAXM PARAMETER ( MAXN =6 , MAXM =7) $ C DOUBLE PRECISION U ( MAXN ) , V ( MAXN ) , B ( MAXM ) , MAT ( MAXM , MAXN ) , MCPY ( MAXM , MAXN ) , BCPY ( MAXM ) , WORK (10000) INTEGER I ,J ,N ,M , INFO , IPIV ( MAXN ) , LWORK Daten : N =6; M =7 DATA U / 1.0 D0 , -1.0 D0 , 1.0 D0 , -1.0 D0 , 1.0 D0 , -1.0 D0 / 294 KAPITEL 8. PROGRAMMIEREN DATA V / 1.0 D0 , DATA B / 1.0 D0 , 4.0 D0 , 2.0 D0 , 2.0 D0 , 3.0 D0 , 5.0 D0 , 4.0 D0 , 3.0 D0 , 5.0 D0 , 6.0 D0 / 6.0 D0 , 1.0 D0 / C MAT = U * V ^ T CALL DGEMM ( 'N ' , 'T ' ,N ,N ,1 ,1.0 D0 ,U , MAXN ,V , MAXN ,0.0 D0 , MAT , MAXM ) C MAT = MAT + V * U ^ T CALL DGEMM ( 'N ' , 'T ' ,N ,N ,1 , -1.0 D0 ,V , MAXN ,U , MAXN ,1.0 D0 , MAT , MAXM ) C 10 MAT = MAT + I DO 10 I =1 , N MAT (I , I )= MAT (I , I )+1.0 D0 CONTINUE 21 Zeile mit 1 en hinzu : DO 21 I =1 , N MAT (7 , I )=1.0 D0 CONTINUE 20 DO 20 I =1 , N +1 WRITE ( * , ' (7 F8 .1) ' )( MAT (I , J ) , J =1 , N ) , B ( I ) CONTINUE C C MAT und B sichern CALL DCOPY ( MAXN ,B ,1 , BCPY ,1) CALL DCOPY ( MAXM * MAXN , MAT ,1 , MCPY ,1) C o p t i m a l e s LWORK b e s t i m m e n : CALL DGELS ( 'N ' ,M ,N ,1 , MAT , MAXM ,B , MAXM , WORK , -1 , INFO ) IF ( INFO . EQ .0) THEN WRITE ( * ,* ) " opt . LWORK : " , WORK (1) LWORK = WORK (1) ELSE WRITE ( * ,* ) " Fehler " RETURN END IF C GLS loesen ( Minimum Norm Loesung ) CALL DGELS ( 'N ' ,M ,N ,1 , MAT , MAXM ,B , MAXM , WORK , LWORK , INFO ) 8.2. FORTRAN C 40 C 50 295 Loesung : WRITE ( * ,* ) " INFO : " , INFO DO 40 I =1 , M WRITE ( * ,* ) " X ( " ,I , " )= " ,B ( I ) CONTINUE Fehler b e s t i m m e n : ERR =B - MAT * X CALL DGEMV ( 'N ' ,M ,N ,1.0 D0 , MCPY , MAXM ,B ,1 , -1.0 D0 , BCPY ,1) DO 50 I =1 , M WRITE ( * ,* ) " Fehler ( " ,I , " )= " , BCPY ( I ) CONTINUE WRITE ( * ,* ) " Norm des Fehlers : " , DNRM2 (N , BCPY ,1) END agebhard@pc28 - math [ lapack ] $ f77 a5 . f -o a5 - lblas - llapack agebhard@pc28 - math [ lapack ] $ . / a5 1.0 5.0 1.0 6.0 2.0 7.0 1.0 -5.0 1.0 -6.0 -1.0 -7.0 -2.0 2.0 -1.0 6.0 1.0 7.0 1.0 8.0 3.0 -6.0 1.0 -7.0 1.0 -8.0 -1.0 4.0 -2.0 7.0 -1.0 8.0 1.0 9.0 5.0 -7.0 2.0 -8.0 1.0 -9.0 1.0 6.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 opt . LWORK : 438. INFO : 0 X ( 1)= -0.783108522 X ( 2)= -0.431177192 X ( 3)= -0.283108522 X ( 4)= 0.0688228081 X ( 5)= 0.216891478 X ( 6)= 0.568822808 X ( 7)= 1.88884882 Fehler ( 1)= 0.606376456 Fehler ( 2)= 0.458307787 Fehler ( 3)= 0.162170448 Fehler ( 4)= 0.0141017781 Fehler ( 5)= -0.282035561 Fehler ( 6)= -0.430104231 Fehler ( 7)= -0.642857143 296 KAPITEL 8. PROGRAMMIEREN Norm des Fehlers : 0.93207846 Aufgabe 6: PROGRAM LAPACK IMPLICIT NONE C externe Fu n kt i on DNRM2 : DOUBLE PRECISION DNRM2 EXTERNAL DNRM2 INTEGER MAXN PARAMETER ( MAXN =6) $ C DOUBLE PRECISION U ( MAXN ) , V ( MAXN ) , B ( MAXN ) , MAT ( MAXN , MAXN ) , MCPY ( MAXN , MAXN ) , BCPY ( MAXN ) , WORK (1000) INTEGER I ,J ,N , INFO , IPIV ( MAXN ) , LWORK Daten : N =6 DATA U / 1.0 D0 , -1.0 D0 , 1.0 D0 , -1.0 D0 , 1.0 D0 , -1.0 D0 / DATA V / 1.0 D0 , 4.0 D0 , 2.0 D0 , 5.0 D0 , 3.0 D0 , 6.0 D0 / DATA B / 1.0 D0 , 2.0 D0 , 3.0 D0 , 4.0 D0 , 5.0 D0 , 6.0 D0 / C MAT = U * V ^ T CALL DGEMM ( 'N ' , 'T ' ,N ,N ,1 ,1.0 D0 ,U , MAXN ,V , MAXN ,0.0 D0 , MAT , MAXN ) C MAT = MAT + V * U ^ T CALL DGEMM ( 'N ' , 'T ' ,N ,N ,1 , -1.0 D0 ,V , MAXN ,U , MAXN ,1.0 D0 , MAT , MAXN ) C 10 MAT = MAT + I DO 10 I =1 , N MAT (I , I )= MAT (I , I )+1.0 D0 CONTINUE 20 DO 20 I =1 ,N -1 WRITE ( * , ' (7 F8 .1) ' )( MAT (I , J ) , J =1 , N ) , B ( I ) CONTINUE 8.2. FORTRAN 297 C MAT und B sichern CALL DCOPY (N ,B ,1 , BCPY ,1) CALL DCOPY ( N *N , MAT ,1 , MCPY ,1) C o p t i m a l e s LWORK b e s t i m m e n ( nur N -1 Zeilen v e r w e n d e n ): CALL DGELS ( 'N ' ,N -1 ,N ,1 , MAT , MAXN ,B , MAXN , WORK , -1 , INFO ) IF ( INFO . EQ .0) THEN WRITE ( * ,* ) " opt . LWORK : " , WORK (1) LWORK = WORK (1) ELSE WRITE ( * ,* ) " Fehler " RETURN END IF C GLS loesen ( Minimum Norm Loesung , nur N -1 Zeilen v e r w e n d e n ) CALL DGELS ( 'N ' ,N -1 ,N ,1 , MAT , MAXN ,B , MAXN , WORK , LWORK , INFO ) C Loesung : WRITE ( * ,* ) " INFO : " , INFO DO 40 I =1 ,N -1 WRITE ( * ,* ) " X ( " ,I , " )= " ,B ( I ) CONTINUE 40 C 50 Fehler b e s t i m m e n : ERR =B - MAT * X CALL DGEMV ( 'N ' ,N -1 ,N ,1.0 D0 , MCPY , MAXN ,B ,1 , -1.0 D0 , BCPY ,1) DO 50 I =1 ,N -1 WRITE ( * ,* ) " Fehler ( " ,I , " )= " , BCPY ( I ) CONTINUE WRITE ( * ,* ) " Norm des Fehlers : " , DNRM2 (N -1 , BCPY ,1) END agebhard@pc28 - math [ lapack ] $ f77 a6 . f -o a6 - lblas - llapack agebhard@pc28 - math [ lapack ] $ . / a6 1.0 5.0 1.0 6.0 2.0 7.0 1.0 -5.0 1.0 -6.0 -1.0 -7.0 -2.0 2.0 -1.0 6.0 1.0 7.0 1.0 8.0 3.0 -6.0 1.0 -7.0 1.0 -8.0 -1.0 4.0 -2.0 7.0 -1.0 8.0 1.0 9.0 5.0 298 KAPITEL 8. PROGRAMMIEREN opt . LWORK : 365. INFO : 0 X ( 1)= -1.32420312 X ( 2)= -0.546318175 X ( 3)= -0.298307373 X ( 4)= 0.479577567 X ( 5)= 0.727588369 Fehler ( 1)= 4.4408921 E -16 Fehler ( 2)= -3.21964677 E -15 Fehler ( 3)= 2.22044605 E -15 Fehler ( 4)= -2.55351296 E -15 Fehler ( 5)= 1.77635684 E -15 Norm des Fehlers : 5.01693066 E -15 Aufgabe 7: PROGRAM LAPACK IMPLICIT NONE C externe Fu n kt i on DNRM2 : DOUBLE PRECISION DNRM2 EXTERNAL DNRM2 INTEGER MAXN , MAXM PARAMETER ( MAXN =6 , MAXM =7) $ $ C DOUBLE PRECISION U ( MAXN ) , V ( MAXN ) , B ( MAXN ) , MAT ( MAXN , MAXN ) , MCPY ( MAXM , MAXN ) , BCPY ( MAXM ) , WORK (10000) , MAT2 (1 , MAXN ) , B2 (1) , X ( MAXM ) INTEGER I ,J ,N ,M , INFO , IPIV ( MAXN ) , LWORK Daten : N =6; M =7 DATA U / 1.0 D0 , -1.0 D0 , 1.0 D0 , -1.0 D0 , DATA V / 1.0 D0 , 4.0 D0 , 2.0 D0 , 5.0 D0 , DATA B / 1.0 D0 , 2.0 D0 , 3.0 D0 , 4.0 D0 , 1.0 D0 , -1.0 D0 / 3.0 D0 , 6.0 D0 / 5.0 D0 , 6.0 D0 / 8.2. FORTRAN 299 C MAT = U * V ^ T CALL DGEMM ( 'N ' , 'T ' ,N ,N ,1 ,1.0 D0 ,U , MAXN ,V , MAXN ,0.0 D0 , MAT , MAXN ) C MAT = MAT + V * U ^ T CALL DGEMM ( 'N ' , 'T ' ,N ,N ,1 , -1.0 D0 ,V , MAXN ,U , MAXN ,1.0 D0 , MAT , MAXN ) C MAT = MAT + I DO 10 I =1 , N MAT (I , I )= MAT (I , I )+1.0 D0 CONTINUE 10 C 21 C C 19 20 C Matrix mit 1 er Zeile : DO 21 I =1 , N MAT2 (1 , I )=1.0 D0 CONTINUE B2 (1)=1 MAT und B sichern , MAT2 / B2 a n h a e n g e n CALL DCOPY ( MAXN ,B ,1 , BCPY ,1) BCPY ( M )= B2 (1) s p a l t e n w e i s e k op ie r en da MAT und MCPY nicht gleich gross ! ! DO 19 I =1 , N CALL DCOPY ( MAXN , MAT (1 , I ) ,1 , MCPY (1 , I ) ,1) CONTINUE CALL DCOPY ( MAXN , MAT2 ,1 , MCPY (7 ,1) , MAXM ) DO 20 I =1 , M WRITE ( * , ' (7 F8 .1) ' )( MCPY (I , J ) , J =1 , N ) , BCPY ( I ) CONTINUE o p t i m a l e s LWORK b e s t i m m e n : CALL DGGLSE (1 ,N ,N , MAT2 ,1 , MAT , MAXN , B2 ,B ,X , WORK , -1 , INFO ) IF ( INFO . EQ .0) THEN WRITE ( * ,* ) " opt . LWORK : " , WORK (1) LWORK = WORK (1) ELSE WRITE ( * ,* ) " Fehler " RETURN END IF 300 KAPITEL 8. PROGRAMMIEREN C GLS loesen ( exakt fuer MAT , Minimum Norm Loesung fuer MAT2 ) CALL DGGLSE (1 ,N ,N , MAT2 ,1 , MAT , MAXN , B2 ,B ,X , WORK , LWORK , INFO ) C Loesung : WRITE ( * ,* ) " INFO : " , INFO DO 40 I =1 , N WRITE ( * ,* ) " X ( " ,I , " )= " ,X ( I ) CONTINUE 40 C 50 Fehler b e s t i m m e n : ERR =B - MAT * X CALL DGEMV ( 'N ' ,M ,N ,1.0 D0 , MCPY , MAXM ,X ,1 , -1.0 D0 , BCPY ,1) DO 50 I =1 , M WRITE ( * ,* ) " Fehler ( " ,I , " )= " , BCPY ( I ) CONTINUE WRITE ( * ,* ) " Norm des Fehlers : " , DNRM2 (N , BCPY ,1) END agebhard@pc28 - math [ lapack ] $ f77 a7 . f -o a7 - lblas - llapack agebhard@pc28 - math [ lapack ] $ . / a7 1.0 5.0 1.0 6.0 2.0 7.0 1.0 -5.0 1.0 -6.0 -1.0 -7.0 -2.0 2.0 -1.0 6.0 1.0 7.0 1.0 8.0 3.0 -6.0 1.0 -7.0 1.0 -8.0 -1.0 4.0 -2.0 7.0 -1.0 8.0 1.0 9.0 5.0 -7.0 2.0 -8.0 1.0 -9.0 1.0 6.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 opt . LWORK : 439. INFO : 0 X ( 1)= -1.31545064 X ( 2)= -0.963519313 X ( 3)= -0.371244635 X ( 4)= -0.0193133047 X ( 5)= 0.572961373 X ( 6)= 0.924892704 Fehler ( 1)= 7.91033905 E -16 Fehler ( 2)= 9.02056208 E -17 Fehler ( 3)= -2.41473508 E -15 Fehler ( 4)= -9.02056208 E -17 8.2. FORTRAN 301 Fehler ( 5)= -1.16573418 E -15 Fehler ( 6)= 2.13024043 E -15 Fehler ( 7)= -2.17167382 Norm des Fehlers : 3.51707474 E -15 Aufgabe 8: GNU Octave , version 2.0.16.92 ( i386 - pc - linux - gnu ). Copyright ( C ) 1996 , 1997 , 1998 , 1999 , 2000 John W . Eaton . This is free software with ABSOLUTELY NO WARRANTY . For details , type ` warranty '. octave > u =[1 -1 1 -1 1 -1] ' u = 1 -1 1 -1 1 -1 octave > v =[1 4 2 5 3 6] ' v = 1 4 2 5 3 6 octave > b =[1 2 3 4 5 6] ' b = 1 2 3 302 KAPITEL 8. PROGRAMMIEREN 4 5 6 octave > M = u *v ' - v *u '+ eye (6) M = 1 -5 -1 -6 -2 -7 5 1 6 1 7 2 1 -6 1 -7 -1 -8 6 -1 7 1 8 1 2 -7 1 -8 1 -9 7 -2 8 -1 9 1 octave > x = inv ( M ) * b x = -1.315451 -0.963519 -0.371245 -0.019313 0.572961 0.924893 octave > e = M *x - b e = -1.7764 e -15 5.3291 e -15 8.8818 e -16 5.3291 e -15 1.7764 e -15 6.2172 e -15 octave > norm ( e ) ans = 1.0127 e -14 octave > M1 =[ M ;[1 1 1 1 1 1]] M1 = 8.2. FORTRAN 1 -5 -1 -6 -2 -7 1 5 1 6 1 7 2 1 1 -6 1 -7 -1 -8 1 6 -1 7 1 8 1 1 303 2 -7 1 -8 1 -9 1 octave > b1 =[ b ; 1] b1 = 1 2 3 4 5 6 1 % falsch :?? octave > x1 = ols ( M1 , b1 ) ' x1 = -0.94565 0.83696 -0.95652 0.82609 -0.96739 0.81522 octave > e1 = M1 * x1 - b1 e1 = 10.0109 13.6196 13.3478 16.9565 16.6848 20.2935 -1.3913 7 -2 8 -1 9 1 1 304 KAPITEL 8. PROGRAMMIEREN octave > norm ( e1 ) ans = 37.994 8.3 C Die Geschichte8 der Programmiersprache C ist eng mit der von UNIX verbunden. Die erste Version von UNIX (die noch UNICS hieß, siehe Abschnitt 2.2) war noch direkt in Assembler für den DEC PDP7 Minicomputer geschrieben. 1970 versuchte Ken Thompson UNIX in BCPL (einer Programmiersprache aus den 60er Jahren) umzuschreiben, hierzu musste BCPL erst auf die PDP Hardware angepasst und dabei verkleinert werden – es entstand die Programmiersprache B. 1971 entwickelten Dennis Ritchie und Brian Kernighan C als Nachfolger von B während UNIX nun auf der DEC PDP-11 weiterentwickelt wurde. Seit 1973 ist UNIX komplett in C geschrieben. Die erste Sprachversion wird durch Kernighan and Ritchie [1978] beschrieben und als K&R C bezeichnet. Die Standardisierung erfolgte Mitte bis Ende der 80er Jahre im ANSI-C Standard , siehe Ame [1989]. C ist eine strukturierte Programmiersprache die hauptsächlich für prozedurales Programmieren (im Gegensatz zu den moderneren objektorientierten Sprachen) eingesetzt wird. Es sind neben den einfachen Datentypen auch strukturierte Typen erlaubt und es werden häufig sogenannte Pointer, d.h. Referenzen auf Speicheradressen verwendet. Es ist auch recht einfach Operationen auf einzelnen Bits auszuführen sowie Assemblercode direkt ins Programm einzubetten. Dies ist und war besonders wichtig für den Einsatz von C zur Systemprogrammierung. 8 siehe z.B. http://www.lysator.liu.se/c/chistory.ps 8.3. C 8.3.1 305 Programmaufbau C Programme bestehen aus • Kommentaren, das sind Texte zwischen /* und */ eingebettet, z.B. / * Kommentar * - -- - -- - - * / bzw. Teile von Zeilen ab einer // Zeichenfolge a =1; / / Kommentar • Präprozessoranweisungen, entsprechende Zeilen beginnen mit # (im engeren Sinne muss das # in der ersten Spalte stehen), z.B. # define VAR1 # ifdef VAR1 / * ... * / # endif • und C Anweisungen die jeweils durch ein Semikolon ; beendet werden. Bei den zulässigen Zeichen wird zwischen dem normalen und dem erweiterten Zeichensatz unterschieden. Der erweiterte Zeichensatz ist nur in Stringkonstanten erlaubt und enthält neben den alphanumerischen Zeichen, dem Leerzeichen, Tabulator und den gebräuchlichen Sonderzeichen ( ^ ,! ," ,% ,& ,/ ,( ,) ,= ,? ,{ ,[ ,] ,} ,\ ,* ,+ ,< ,> ,| ,, ,; ,. ,: ,- ,# ,’ ) u.a. noch länderspezifische Sonderzeichen wie z.B. $. Ein C Programm muss (wenn es ein selbständig lauffähiges Programm sein soll) genau eine main Funktion besitzen. In der Regel 306 KAPITEL 8. PROGRAMMIEREN verwendet es weitere selbstgeschriebene und vom System in der sogenannten C-Library zur Verfügung gestellte Funktionen. Während des Übersetzens müssen die Namen und die Rückgabe- und Argumenttypen aller verwendeten Funktionen bekannt sein, da sonst falsche Typumwandlungen erfolgen würden. Aus diesem Grund muß man alle Funktionen deklarieren bevor man sie schreibt bzw. das erste mal aufruft. Diese Typdeklarationen trennt man in der Regel vom eigentlichen C Quellcode (Dateien mit Endung .c) und speichert sie in sog. Headerdateien (mit Endung .h). Diese Headerdateien werden mittels der #include Präprozessoranweisung zu Beginn eines C Quelltexts geladen. Die allgemeine Struktur eines C Quelltexts für ein Hauptprogramm sieht also so aus: / * Kommentar ( e ) * / / * include Anweisungen , z . B . * / # include " myfunc1 . h " # include < stdio .h > / * eventuell : globale Variablendeklarationen , weitere Unt erfu nkti one int main ( int argc , char * argv []){ / * T y p d e k k l a r a t i o n e n ... * / /* Programmanweisungen */ return 0; } Anweisungen sind durch ; zu beenden und können mittels geschweifter Klammern zu Blöcken zusammengefaßt werden. 8.3. C 8.3.1.1 307 Compileraufruf Der C Compiler heißt in der Regel cc und wird zum Kompilieren und gleichzeitigen Linken eines Programms in der Form cc datei.c aufgerufen. Hierbei entsteht das Programm a.out das mit ./a.out gestartet werden kann. Soll die Ausgabedatei einen anderen Namen erhalten ist cc datei.c -o output zu verwenden. Soll nur kompiliert und nicht gelinkt werden (z.B für Unterprogrammdateien) ist die Option -c zu ergänzen: cc -c datei.c oder cc -c datei -o datei.o Weitere oft verwendete Optionen geben zusätzlich Suchpfade für • Headerdateien cc -c datei.c -Ipfad • oder Libraries cc -Lpfad -lmylib datei.o -o output 308 KAPITEL 8. PROGRAMMIEREN an. Das erste Beispiel bewirkt dass Headerdateien die mit #include eingelesen werden auch im Verzeichnis pfad gesucht werden. Im zweiten Beispiel wird eine Library mit Namen libmylib.a (statische Library) oder libmylib.so (dynamische Library) im Pfad pfad gesucht und zum Hauptprogramm hinzugelinkt. Weitere wichtige Optionen sind • -g Übersetzen für den Debugmodus • -O optimiertes Übersetzen • -E nur Präprozessordurchlauf • -S Ausgabe des Assemblercodes Es existieren natürlich noch viel mehr Optionen, die dann meist compiler- und plattformabhängig sind, die Optionen des GNU C Compilers gcc liest man unter man gcc nach. 8.3.2 Schlüsselwörter und Bezeichner Folgende vordefinierten Schlüsselwörter auto break case continue default do enum extern float if inline int restrict return short static struct swicth unsigned void volatile _Complex _Imaginary existieren char double for long signed typdef while in C: const else goto register sizeof union _Bool 8.3. C 309 Sie dürfen nicht als Bezeichner verwendet werden. Bezeichner bestehen aus alphanumerischen und dem Sonderzeichen _. Das erste Zeichen darf dabei keine Ziffer sein. Groß- und Kleinschreibung werden (im Unterschied zu FORTRAN) unterschieden. Bezeichner werden als Namen für Variablen, Funktionen, Typen, Typkomponenten und Marken verwendet. 8.3.3 Datentypen Man unterscheidet grundsätzlich vordefinierte und abgeleitete Datentypen. Zu den vordefinierten Typen gehören die elementaren Typen (umfassend die ganzzahligen und Gleitpunktypen) sowie der Typ void. Abgeleitete Typen umfassen die Aufzählungstypen, zusammengesetzte Typen (structure, union, Bitfelder), Vektoren und Zeiger (Pointer). Es existieren zusätzlich sogenannte modifier mit denen die Art und Weise der internen Speicherung (die sog. Speicherklasse) beeinflusst werden kann. Diese modifier sind: • auto: nur innerhalb von Funktionen, Variable wird bei jedem Funktionseintritt neu initialisiert initialisiert und gilt nur lokal. (Ist Standard, deshalb wird auto kaum explizit angegeben.) • register: wie auto, aber die Variable wird so es möglich ist in ein Register der CPU geschrieben. Damit ist der Adressoperator & (siehe Zeiger ...) nicht mehr anwendbar! • extern: wird für globale Variablen verwendet, muss nur dann angegeben werden wenn der Quelltext über mehrere Files verteilt ist. • static: Variable wird nur einmal (zu Beginn initialisiert und gilt während der gesamten Laufzeit des Programms). Im Ge- 310 KAPITEL 8. PROGRAMMIEREN gensatz zu extern kann nicht von anderen Quelltextdateien desselben Programmes heraus zugegriffen werden. Variablendeklarationen erfolgen in der Form K J modifier K . . . )) J qualifier K type varname (( , varname J = initval optional mit Anfangswertzuweisungen. static Variablen werden wenn nicht explizit anders vorgegeben mit 0 initialisiert, alle anderen Variablen nicht! Mittels der modifier Präfixe const und volatile lassen sich Werte entweder konstant (vor Zugriff geschützt) oder als extern veränderbar (=vor Compileroptimierung geschützt) deklarieren. 8.3.3.1 Elementare Typen Integer Typen Die ganzzahligen Typen sind Typ char unsigned char signed char int unsigned int short unsigned short long unsigned long long long unsigned long long # Bytes 1 1 1 2/4 2/4 2 2 4 4 8 8 Wertebereich FORTRAN Äquivalent 0 bis 255 -128 bis 127 CHARACTER -32768 bis 32767 0 bis 65535 −231 bis 231 − 1 0 bis 232 − 1 −263 bis 263−1 0 bis 264 − 1 INTEGER INTEGER*8 Je nach Compiler ist char mit unsigned char oder signed char identisch, genauso ist compilerabhängig ob int mit short oder long übereinstimmt. Anstelle von short und long darf auch short int und long int geschrieben werden. 8.3. C 311 Gleitkommatypen Floating point Typen sind Typ float double long double # Bytes 4 8 10 Wertebereich Stellen 6 15 19 FORTRAN Äquivalent REAL DOUBLE PRECISION REAL*16 Ein weiterer wichtiger elementarer Typ ist void. Er wird z.B. verwendet um anzuzeigen daß eine Funktion keinen Rückgabewert zurückliefert. Andererseits kann der Typ void mit dem cast Operator (s.u.) in jeden beliebigen Typ umgewandelt werden, das ist z.B. bei der dynamischen Speicherverwaltung mittels malloc wichtig. Der neueste ANSI-C 99 Standard legt zusätzlich noch die Typen • _Bool für logische Variablen (1 Byte) und • _Complex für komplexe und _Imaginary für rein imaginäre Zahlen fest. 8.3.3.2 Abgeleitete Typen Mittels typedef kann man eigene Typen deklarieren: typedef typ typname Vektoren Durch Angabe der Dimension in eckigen Klammern im Anschluss an den Variablennamen lassen sich ein- oder mehrdimensionale Vektoren beliebigen Typs erstellen: typ vektorname [ dimension ]; typ arrayname [ dimension1 ][ dimension2 ]; 312 KAPITEL 8. PROGRAMMIEREN Auf die Elemente wird durch Indexangabe in eckigen Klammern zugegriffen, Zählung beginnt bei 0!! int v [10]; float f [3]={1.0 , -1.5 , 0.1}; v [0]=0; / / erstes Element von v belegen f [2]=1.0; / / ueberschreibt den Wert 0.1 Aufzählungstypen enum enumname { ze i ch e nk o ns t an t e enum enumname varname ; J , z ei c he n ko n st a nt e. . . K }; bzw. typedef enum enumname { ze i ch e nk o ns ta n te K } enumtype ; enumtype varname ; J , z ei c he n ko n st a nt e. . . Bsp.: typedef enum Farben {rot , gruen , blau , orange , gelb , violett , weis schwarz , braun} Farben _ t ; Farben _ t f ; f = blau ; Die Werte von Aufzählungstypen werden intern als positive Integerwerte beginnend mit 0 kodiert. Zusammengesetzte Typen In zusammengesetzten Typen werden mehrere Elemente unterschiedlichen Typs in einer Einheit (structure) zusammengefaßt. 8.3. C 313 struct structname { typ elementname ; J typ elementname ; . . . K }; struct structname varname ; bzw. typedef struct structname { typ elementname ; J typ elementname ; . . . K } structtype ; structtype varname ; Auf die Elemente kann anschließend mittels varname.elementname zugegriffen werden. Bsp: # define MAX _ NAME 20 # define MAX _ VORNAME 40 typedef struct Person { char Vorname [ MAX _ VORNAME ]; char Name [ MAX _ NAME ]; int Alter ; float Groesse ; } Person _ t ; Person _ t student1 ; Person _ t student2 ={" Hans " ," Beispiel " ,25 ,1.65}; strcpy ( student1 . Vorname , " Max " ); / / gefaehrlich ! keine L a e n g e n u e b e r p strncpy ( student1 . Name , " Muster " , MAX _ NAME ); / / besser student1 . Alter =24; student1 . Groesse = student2 . Groesse +0.15; In einer struct Variablen werden alle Elemente aufeinanderfolgend im Speicher abgebildet. In einer union Variablen beginnen dagegen alle Elemente an der selben Speicheradresse. 314 KAPITEL 8. PROGRAMMIEREN union unionname { typ elementname ; J typ elementname ; . . . K }; union unionname varname ; bzw. typedef union unionname { typ elementname ; J typ elementname ; . . . K } uniontype ; uniontype varname ; Es können also Variablen definiert werden die wahlweise zum Speichern von Werten der unterschiedlichen beteiligten Elementtypen verwendet werden können. 8.3.3.3 Zeiger Zeigervariablen werden mittels typ * varname ; bzw. typ * varname ; deklariert. Sie enthalten Zeiger auf Variablen des angegebenen Typs (d.h. Speicheradressen von Variablen dieses Typs). Mit dem & Operator kann man die Adresse von Variablen ermitteln und z.B. einer passenden Zeigervariablen zuweisen. Mit dem * Operator lassen sich Zeiger dereferenzieren, also auf den Wert der in Ihnen enthaltenen Speicheradresse zugreifen. 8.3. C 315 # include < stdio .h > int i =1 , j ; int * p _ i ; p_i = &i; j = *p_i; printf ( " Wert von j : % i \ n " ,j ); Vektoren und Arrayvariablen werden ebenfalls über Zeiger realisiert, verwendet man den Variablennamen ohne Elementangabe in eckiger Klammer so erhält man einen Zeiger auf das erste Element das Arrays. Mit der malloc Funktion kann auch auf dynamische Weise Speicherplatz reserviert und mit einer Zeigervariablen referenziert werden: # include < stdlib .h > int * iv ; Person _ t * s ; iv = ( int * ) malloc (10 * sizeof ( int )); s = ( Person _ t * ) malloc ( sizeof ( Person _ t )); / / iv ist nun wie ein Array der Laenge 10 we i te r ve r we n db a r iv [0]=1; / / Beim Zugriff auf Elemente einer struct Variablen ueber Zeiger wird / / statt des " . " ein " ->" verwendet . s - > Alter =30; / / das ist aequivalent zur etwas um st a en d li c he r en Schreibweise ( * s ). Alter =30; / / ... free ( s ); free ( iv ); Dynamischer Speicherplatz sollte nach seiner Verwendung wieder freigegeben werden (mit free). 316 KAPITEL 8. PROGRAMMIEREN 8.3.3.4 Zeichenkonstante und Stringliterale Zeichenkonstante sind ein oder mehrere Zeichen des Zeichensatzes in einfachen Hochkommas, Stringliterale sind Zeichenketten in doppelten Hochkommas. 8.3.4 Operationen Wertzuweisung erfolgt mittels varname = ausdruck ; Die arithmetischen Operatoren sind • * • / • % (modulo) • + (binär oder unär) • - (binär oder unär) • ++ (Inkrement) • -- (Dekrement) Die Inkrement oder Dekrementoperatoren werden von links oder rechts an einen (ganzzahligen) Variablennamen geschrieben (++x oder x++)und bedeuten x = x +1; wobei diese Operation im Falle des Präfixoperators vor und im Falle des Postfixoperators nach der Verwendung von x erfolgt. Bsp: 8.3. C 317 int x1 =1 , x2 =1 , y ; y =++ x1 * 2; / / y =4 , x1 =2 printf ( " % i % i \ n " ,x1 , y ); y = x2 ++ * 2 ; / / y =2 , x2 =2 printf ( " % i % i \ n " ,x2 , y ); Mit ganzzahligen Operanden können Bitoperationen durchgeführt werden: • & bitweises AND: x&y • | bitweises OR: x|y • ^ bitweises XOR: x^y • ~ bitweises NOT: ~x • << left-shift: x<<y (Bits von x werden um y Positionen nach links geschoben) • >> right-shift: x>>y (Bits von x werden um y Positionen nach rechts geschoben) Alle bisherigen Operatoren können im Spezialfall der Anwendung var1 = var1 op var2 in der Form var1 op = var2 geschrieben werden, also z.B. a +=2; c < <=3; / / a = a +2 / / c =c < <3 b / =1.5; / / b = b / 1.5 318 KAPITEL 8. PROGRAMMIEREN Die Speicherzugriffsoperatoren sind • - Vektorelement • & - Adresse • * - Dereferenzieren • . - Elementzugriff in struct und union • -> - Elementzugriff in struct und union über Zeiger Weitere Operatoren sind • der cast Operator ( typ ) ausdruck Er wandelt den Typ von ausdruck explizit nach typ um (falls möglich). Er ist z.B. bei der Verwendung von malloc nötig da diese Funktion den Typ des dynamisch angelegten Speichers auf (void *) setzt. • Funktionsargumente werden mit dem () Operator angegeben. • Der sizeof Operator ermittelt die Speichergröße des als Argument angegebenen Typs (wird wiederum bei Anwendung von malloc benötigt um ausreichend Platz zu reservieren, siehe Beispiel weiter oben.) • Verkettete Auswertung erfolgt mittels ausdruck1 , ausdruck2 • Bedingte Auswertung erfolgt mittels 8.3. C 319 ausdruck1 ? ausdruck2 : ausdruck3 Ist ausdruck1 wahr (also 6= 0) wird ausdruck2 ausgewertet, sonst ausdruck3. 8.3.5 Steueranweisungen Die Werte “wahr” und “falsch” werden in C durch 1 und 0 bzw. allgemeiner durch 6= 0 und = 0 bestimmt. 8.3.5.1 Bedingungen Vergleichsoperatoren sind • < • <= • == • >= • > • != Verglichen werden dürfen arithmetische Operanden (Typumwandlung auf allgemeineren erfolgt) und Zeiger gleichen Typs. 8.3.5.2 if Verzweigung if ( ausdruck ) anweisung1 else anweisung2 ausdruck muss von skalarem Typ sein. anweisung1 und anweisung2 bestehen in der Regel aus ganzen Anweisungsblöcken: 320 KAPITEL 8. PROGRAMMIEREN if (x <=3){ y =2; i ++; } else { i =0; } 8.3.5.3 switch Verzweigung Sollen mehrere Zustände eines Ausdrucks gleichzeitig unterschiedlich behandelt werden ist die switch Anweisung angebracht: switch ( ausdruck ){ case ganzz . Konst . : anweisung ; J case ganzz . Konst . : anweisung ; . . . K J default : anweisung ; K } ausdruck muss von skalarem Typ sein. 8.3.5.4 for Schleifen for ( J anweisung1 K ; J anweisung2 K ; J anweisung3 K ) J anweisung4 K anweisung4 ist in der Regel ein Anweisungsblock, anweisung1 bis anweisung3 sind Anweisungssequenzen anweisung1 wird zu Beginn der Schleife genau einmal ausgeführt, nach jedem Schleifendurchlauf wird anweisung2 ausgeführt, falls deren Wert “falsch” ergibt wird die Schleife abgebrochen (anweisung2 muss also skalaren Typ liefern). Nach jedem Schleifendurchlauf wird anweisung3 ausgeführt. Der eigentliche Schleifenkörper besteht aus anweisung4. Alle Anweisungen sind optional!! D.h. for (;;); 8.3. C 321 ist zulässig (es stellt eine Endlosschleife dar die nichts tut). Eine herkömmliche Schleife wäre # include < stdio .h > int main ( int argc , char * argv []){ int i , n =10 , v [10]={1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10}, s ; for ( i =0 , s =0; i < n ; i ++){ s += v [ i ]; } printf ( " Summe % i \ n " ,s ); } 8.3.5.5 while Schleifen anfangsgeprüft: while ( ausdruck ) anweisung ; endgeprüft do anweisung while ( ausdruck ); Auch hierbei besteht anweisung meist aus einem Anweisungsblock. ausdruck hat skalaren Typ und wird auf “wahr” oder “falsch” geprüft. 8.3.6 Funktionen Funktionen bilden die Grundlage eines jeden C-Programms. In der Regel existiert neben der zwingend erforderlichen main Funktion mehrere anwendungsspezifische Funktionen die die Funktionalitäten des jeweiligen Programms implementieren. Funktionen erhalten bei ihrem Aufruf in der Regel einige Argumente übergeben, und führen dann bestimmte Operationen oder Aktionen aus. 322 KAPITEL 8. PROGRAMMIEREN Besteht der Zweck der Funktion darin in Abhängigkeit von den Argumenten bestimmte Ergebniswerte zu bestimmen, müssen diese an die aufrufende Stelle zurückgeliefert werden können. Falls das Ergebnis von skalarem Typ oder ein Zeiger ist, kann dies über die Vergabe eines von void verschieden Typs an die Funktion und Verwendung der return Funktion geschehen. Müssen mehrere Werte (evt. unterschiedlichen) Typs zurückgegeben werden, kann dies nur über Verwendung des call-by-reference Prinzips, also der Verwendung von Zeigervariablen in der Argumentliste, erfolgen. Funktionen müssen aber nicht unbedingt Werte zurückliefern. Ihr Zweck kann z.B. auch das Ausführen spezieller I/O Operationen wie das Lesen oder Schreiben einer Datei sein. In den meisten Fällen empfiehlt es sich aber dennoch den Funktionsrückgabewert zumindest als Indikator für Erfolg oder Fehlschlagen der gewünschten Aktion zu verwenden. / * Funktion ohne Argumente und ohne Rueckgabewert * / void func1 (){ printf ( " test \ n " ); } / * Funktion mit Argument und ohne Rueckgabewert * / void func1 ( int i ){ printf ( " i : % i \ n " ,i ); } / * Funktion mit Argumenten und Rueckgabewert * / int func2 ( int i , int j ){ return ( i + j ); } / * Funktion mit Argumenten und Rueckgabe ueber Zeigerargument * / void func3 ( int i , int * j ){ * j =2 * i ; } 8.3. C 8.3.7 323 Interface zu FORTRAN Funktionen FORTRAN Funktionen und Unterprogramme unterscheiden sich in ihrer compilerinternen Namensgebung von C Funktionen. Im compilierten Code behalten C Funktionen ihren Namen so wie er im Quelltext steht. Die Namen von FORTRAN Funktionen und Unterprogrammen werden in Kleinbuchstaben umgewandelt und um einen Underscore _ erweitert (dies ist compilerabhängig, insbesondere die Anzahl der Underscores). Eine FORTRAN SUBROUTINE ist mit einer C Funktion vom Typ void deren Argumente allesamt Zeigervariablen sind identisch. Um eine FORTRAN Funktion im C verwenden zu können muss eine entsprechende Deklaration geschrieben werden, z.B. müsste für die Funktion SUBROUTINE ADD (N ,A ,B , C ) INTEGER N , I DOUBLE PRECISION A ( * ) , B ( * ) , C ( * ) 10 DO 10 I =1 , N C ( I )= A ( I )+ B ( I ) CONTINUE RETURN END die Deklaration void add _ ( int *n , double *a , double *b , double * c ); verwendet werden. Anschließend könnte man die Funktion add_ im C Code normal verwenden. Hat man umgekehrt eine C Funktion auf die man im FORTRAN zugreifen will (dazu muss man sich bei den Argumenten auf die Typen int*, float* und double* beschränken) muß man der Funktion entweder im Namen gleich den Underscore 324 KAPITEL 8. PROGRAMMIEREN zufügen oder zumindest eine zweite Funktion mit Underscore am Namensende erzeugen die dann die eigentliche C Funktion aufruft: void sub ( int *n , float *a , float *b , float * c ){ int i ; for ( i =0; i < * n ; i ++) c [ i ]= a [ i ] - b [ i ]; } / * Call wrapper : * / void sub _ ( int *n , float *a , float *b , float * c ){ sub (n ,a ,b , c ); } Beim Linken von gemischtem FORTRAN und C Code empfiehlt es sich den FORTRAN Compiler zu verwenden, da dabei die Einstellungen zum Finden der FORTRAN Runtime-Library meist richtig gesetzt werden, ansonsten muss man diese Werte dem C Compiler beim Linken übergeben. Im Falle des aktuellen GNU C Compilers sind dies die Schalter -lg2c -lm. Verwendet man nur Vektoren so sind diese einfach zwischen C und FORTRAN austauschbar, bei Matrizen ist zu beachten daß FORTRAN diese spaltenorientiert speichert, C dagegen zeilenorientiert. FORTRAN Matrizen müssen zudem zusammenhängend im Speicher abgebildet werden. Bei mittels matname[nrow][ncol] erzeugten C Matrizen ist dies i.d.R. nicht der Fall da solche Matrizen aus einem Vektor mit den Zeigern auf die Matrixzeilen bestehen. Also muß man die Matrizen dynamisch allozieren int m ,n , lda ; double * matname ; matname = ( double * ) malloc ( lda * n * sizeof ( double )); und über selbst berechnete Indizes ansprechen: for ( i =0; i < m ; i ++) 8.3. C 325 for ( j =0; j < n ; j ++) matname [ j + i * lda ]=1; 8.3.8 LAPACK und C Entsprechend dem im vorigen Abschnitt vorgestellten Mechanismus zum Zugriff auf FORTRAN Funktionen lassen sich die Methoden der LAPACK und BLAS Library von C aus verwenden9 . Es existiert auch eine C Version10 der LAPACK Bibiliothek die in gleicher Weise verwendet werden kann. z.B. sieht so des Analogon zur FORTRAN Lösung von Aufgabe 1 bis 3 weiter oben aus: #include <stdio.h> /* forward Deklarationen fuer LAPACK Funktionen: */ void dgemm_(char*,char*,int*,int*,int*,double*,double*,int*,double*,int void dcopy_(int*,double*,int*,double*,int*); void dgesv_(int*,int*,double*,int*,int*,double*,int*,int*); void dgemv_(char*,int*,int*,double*,double*,int*,double*,int*,double*,d double* ddot_(int*,double*,int*); int main(){ int i,j,ldm=6,n=6,info,ipiv[6],h1=1,h2; double u[]={1.0, -1.0, 1.0, -1.0, 1.0, -1.0}; double v[]={1.0, 4.0, 2.0, 5.0, 3.0, 6.0}; double b[]={1.0, 2.0, 3.0, 4.0, 5.0, 6.0}, bcpy[6]; double *m, *mcpy; 9 http://www.netlib.org/blas/blast-forum/cinterface.ps 10 http://www.netlib.org/clapack/ 326 KAPITEL 8. PROGRAMMIEREN double alpha, beta; char nt='N', tr='T'; m=(double *) malloc(36*sizeof(double)); mcpy=(double *) malloc(36*sizeof(double)); alpha=1.0; beta=0.0; dgemm_(&nt,&tr,&n,&n,&h1,&alpha,u,&ldm,v,&ldm,&beta,m,&ldm); alpha=-1.0; beta=1.0; dgemm_(&nt,&tr,&n,&n,&h1,&alpha,v,&ldm,u,&ldm,&beta,m,&ldm); for(i=0; i<n; i++) m[i*ldm+i]+=1; printf("GLS:\n"); // i in innerer Schleife wegen FORTRAN Matrix ! for(j=0; j<n; j++){ for(i=0; i<n; i++){ printf("%8.2f ",m[i*ldm+j]); } printf("%8.2f\n",b[i]); } dcopy_(&n,b,&h1,bcpy,&h1); h2=n*n; dcopy_(&h2,m,&h1,mcpy,&h1); dgesv_(&n,&h1,m,&ldm,ipiv,b,&ldm,&info); printf("x = "); 8.3. C 327 for(i=0; i<n; i++){ printf("%f, ",b[i]); } printf("\n"); alpha=1.0; beta=-1.0; dgemv_(&nt,&n,&n,&alpha,mcpy,&ldm,b,&h1,&beta,bcpy,&h1); printf("err = "); for(i=0; i<n; i++){ printf("%e, ",bcpy[i]); } printf("\n"); printf("Norm des Fehlers: %e",dnrm2_(&n,bcpy,&h1)); printf("\n"); } agebhard@pc28 - math [ FORTRAN ] $ cc -c a1 . c agebhard@pc28 - math [ FORTRAN ] $ f77 a1 . o - lblas - llapack -o a1c agebhard@pc28 - math [ FORTRAN ] $ . / a1c GLS : 1.00 5.00 1.00 6.00 2.00 7.00 1.00 -5.00 1.00 -6.00 -1.00 -7.00 -2.00 1.00 -1.00 6.00 1.00 7.00 1.00 8.00 1.00 -6.00 1.00 -7.00 1.00 -8.00 -1.00 1.00 -2.00 7.00 -1.00 8.00 1.00 9.00 1.00 -7.00 2.00 -8.00 1.00 -9.00 1.00 1.00 x = -1.315451 , -0.963519 , -0.371245 , -0.019313 , 0.572961 , 0.924893 , 328 KAPITEL 8. PROGRAMMIEREN err = -3.330669 e -16 , 1.231654 e -15 , -2.498002 e -16 , -3.434752 e -16 , -2. Norm des Fehlers : -1.997631 e +00 8.4 Debugging Bei der Fehlersuche lassen sich Debugger einsetzen. Dazu ist beim Compilieren der −g Schalter zu setzen (und auf Optimieren mittels −O sollte man dabei verzichten). Der GNU Debugger gdb bietet sich unter Linux an. Andere verbreitete Debugger sind dbx, ladebug, ... Der Aufruf des gdb auf der Kommandozeile erfolgt mit gdb / pfad / zu / programm Anschließend kann man mittels break subname in der Unterfunktion subname einen Breakpoint setzen und mit run argumente das Programm starten. Nachdem die Ausführung am Breakpoint gestoppt wurde kann man mit list die aktuellen Programmzeilen ausgeben und mit step oder next die nächste Zeile ausführen (ohne oder mit Überspringen von Unterprogrammaufrufen). Mit continue wird bis zum nächsten Breakpoint fortgesetzt. Zum Anzeigen von Variablen kann print verwendet werden. Bei der Anzeige von FORTRAN Arrays versagt dies manchmal und es ist besser den Speicher direkt mit x zu untersuchen. Der gdb kann auch innerhalb des Emacs mittels Alt - X gdb ausführt werden. Hierbei kann man den Verlauf direkt im Quelltext mitverfolgen. a ge b ha r d@ e ps i lo n [ FORTRAN ] $ gdb . / a1 GNU gdb 5.3 - debian Copyright 2002 Free Software Foundation , Inc . GDB is free software , covered by the GNU General Public License , and 8.4. DEBUGGING 329 Abbildung 8.4: Emacs im gdb-mode welcome to change it and / or distribute copies of it under certain conditi Type " show copying " to see the conditions . There is absolutely no warranty for GDB . Type " show warranty " for detail This GDB was configured as " i386 - linux " ... ( gdb ) break main Breakpoint 1 at 0 x804929c : file a1 .c , line 7. ( gdb ) run Starting program : / afs / home . algepop . dyndns . org / user / agebhard / Sandbox / math Breakpoint 1 , main () at a1 . c :7 7 int i ,j , ldm =6 , n =6 , info , ipiv [6] , h1 =1 , h2 ; ( gdb ) step 8 double u []={1.0 , -1.0 , 1.0 , -1.0 , 1.0 , -1.0}; ( gdb ) 9 double v []={1.0 , 4.0 , 2.0 , 5.0 , 3.0 , 6.0}; ( gdb ) 10 double b []={1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0}, bcpy [6]; ( gdb ) 13 char nt = 'N ' , tr = 'T '; ( gdb ) 330 KAPITEL 8. PROGRAMMIEREN 15 m =( double * ) malloc (36 * sizeof ( double )); ( gdb ) 16 mcpy =( double * ) malloc (36 * sizeof ( double )); ( gdb ) 18 alpha =1.0; beta =0.0; ( gdb ) 19 dgemm _ ( & nt , & tr , &n , &n , & h1 , & alpha ,u , & ldm ,v , & ldm , & beta ,m , & l ( gdb ) 21 alpha = -1.0; beta =1.0; ( gdb ) 22 dgemm _ ( & nt , & tr , &n , &n , & h1 , & alpha ,v , & ldm ,u , & ldm , & beta ,m , & l ( gdb ) 24 for ( i =0; i < n ; i ++) ( gdb ) x / 36 gf m 0 x8052b70 : -0 -5 0 x8052b80 : -1 -6 0 x8052b90 : -2 -7 0 x8052ba0 : 5 -0 0 x8052bb0 : 6 1 0 x8052bc0 : 7 2 0 x8052bd0 : 1 -6 0 x8052be0 : -0 -7 0 x8052bf0 : -1 -8 0 x8052c00 : 6 -1 0 x8052c10 : 7 -0 0 x8052c20 : 8 1 0 x8052c30 : 2 -7 0 x8052c40 : 1 -8 0 x8052c50 : -0 -9 0 x8052c60 : 7 -2 0 x8052c70 : 8 -1 0 x8052c80 : 9 -0 ( gdb ) c Continuing . Matrix M : 1.000000 -5.000000 -1.000000 -6.000000 -2.000000 -7.000000 5.000000 1.000000 6.000000 1.000000 7.000000 2.000000 8.4. DEBUGGING 331 1.000000 -6.000000 1.000000 -7.000000 -1.000000 -8.000000 6.000000 -1.000000 7.000000 1.000000 8.000000 1.000000 2.000000 -7.000000 1.000000 -8.000000 1.000000 -9.000000 7.000000 -2.000000 8.000000 -1.000000 9.000000 1.000000 x = -1.315451 , -0.963519 , -0.371245 , -0.019313 , 0.572961 , 0.924893 , err = 7.771561 e -16 , 0.000000 e +00 , 0.000000 e +00 , -1.110223 e -16 , 2.775558 e Norm des Fehlers : -1.110224 e -16 Program exited with code 01. ( gdb ) Die meisten gdb Befehle kann man mit ihrem Anfangsbuchstaben abkürzen, also s, c usw., einfache Eingabe von Enter wiederholt den letzten Befehl. 332 KAPITEL 8. PROGRAMMIEREN Tabellenverzeichnis 2.1 Usereinteilung . . . . . . . . . . . . . . . . . . . . . . 24 2.2 Dateitypen . . . . . . . . . . . . . . . . . . . . . . . 29 3.1 vi command mode . . . . . . . . . . . . . . . . . . . 55 3.2 vi ed mode Kommandos . . . . . . . . . . . . . . . . 56 3.3 Ausgewählte Emacs Steuerkommandos . . . . . . . . 59 4.1 Dokumentklassen . . . . . . . . . . . . . . . . . . . . 67 4.2 Schriftarten . . . . . . . . . . . . . . . . . . . . . . . 68 4.3 Wichtige Formelsymbole . . . . . . . . . . . . . . . . 76 4.4 Beispiel für eine abgesetzte Tabelle . . . . . . . . . . 77 5.1 Konstanten . . . . . . . . . . . . . . . . . . . . . . . 118 5.2 Operationen . . . . . . . . . . . . . . . . . . . . . . . 120 5.3 CAS Funktionen . . . . . . . . . . . . . . . . . . . . 122 5.4 Funktionsdefinition . . . . . . . . . . . . . . . . . . . 123 5.5 Substitution . . . . . . . . . . . . . . . . . . . . . . . 125 333 334 TABELLENVERZEICHNIS 5.6 Gleichungen lösen . . . . . . . . . . . . . . . . . . . . 127 5.7 Grenzwerte . . . . . . . . . . . . . . . . . . . . . . . 128 5.8 Differenzieren, Differentialgleichungen . . . . . . . . 131 5.9 Integration . . . . . . . . . . . . . . . . . . . . . . . 132 5.10 Funktionsdarstellungen . . . . . . . . . . . . . . . . . 133 8.1 263 FORTRAN Datentypen . . . . . . . . . . . . . . . . Abbildungsverzeichnis 2.1 D. Ritchie und K. Thompson an einer DEC PDP 11 19 2.2 Schema der Filesystemhierarchie . . . . . . . . . . . 29 4.1 Beispiel für figure . . . . . . . . . . . . . . . . . . . 79 5.1 MAXIMA im Emacs (imaxima) . . . . . . . . . . . . 103 5.2 MAXIMA Session innerhalb von TeXmacs . . . . . . 105 5.3 109 5.4 Axiom Session in TEXmacs . . . . . . . . . . . . . . Maple Session unter X Window . . . . . . . . . . . . 5.5 Mathematica Notebook . . . . . . . . . . . . . . . . 112 5.6 XMupad . . . . . . . . . . . . . . . . . . . . . . . . . 114 5.7 Yacas im TEXmacs . . . . . . . . . . . . . . . . . . . 116 6.1 Stabdiagramm der Tiere eines Bauernhofes . . . . . 171 6.2 Stabdiagramm mit mehreren Merkmalen: Tiere von fünf Bauernhöfen . . . . . . . . . . . . . . . . . . . . 172 Ergebnis der Umfrage zur ÖH-Wahl 2003, Uni Klagenfurt . . . . . . . . . . . . . . . . . . . . . . . . . . 173 6.3 335 110 336 ABBILDUNGSVERZEICHNIS 6.4 Tortendiagramm, Tiere von Bauernhof Nr. 5 . . . . 175 6.5 Streifendiagramm . . . . . . . . . . . . . . . . . . . . 176 6.6 Zeitreihe . . . . . . . . . . . . . . . . . . . . . . . . . 179 6.7 Streudiagramm . . . . . . . . . . . . . . . . . . . . . 180 6.8 Sinus- und Kosinuskurve . . . . . . . . . . . . . . . . 181 6.9 Histogramm der Sandkorndurchmesser . . . . . . . . 185 6.10 Histogramm der Sandkorndurchmesser . . . . . . . . 186 6.11 Histogramm der Sandkorndurchmesser . . . . . . . . 187 6.12 Einfaches Boxplot . . . . . . . . . . . . . . . . . . . 189 6.13 Boxplot des Gewichts von 45 Feuerwehrmännern . . 190 6.14 Boxplot der ppm-Werte von Bleimessungen . . . . . 192 6.15 Vergleich Aichfeld-Murau . . . . . . . . . . . . . . . 192 6.16 Streudiagramm Vitalkapazität gegen Alter . . . . . . 195 6.17 Streudiagramm Vitalkapazität gegen Einsekundenkapazität . . . . . . . . . . . . . . . . . . . . . . . . . . 196 6.18 Regressionsgerade nach Methode der kleinsten Quadrate . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 6.19 Mit Sweave erzeugter Plot . . . . . . . . . . . . . . . 221 7.1 Octave Plot . . . . . . . . . . . . . . . . . . . . . . . 240 7.2 Octave 3D Plot . . . . . . . . . . . . . . . . . . . . . 241 8.1 FORTRAN im vim . . . . . . . . . . . . . . . . . . . 260 8.2 FORTRAN im Emacs . . . . . . . . . . . . . . . . . 261 8.3 lineare Interpolation . . . . . . . . . . . . . . . . . . 272 8.4 Emacs im gdb-mode . . . . . . . . . . . . . . . . . . 329 Literaturverzeichnis American National Standard Programming Language C, ANSI X3.159-1989. American National Standards Institute, 1430 Broadway, New York, NY 10018, USA, December 14 1989. E. Anderson, Z. Bai, C. Bischof, S. Blackford, J. Demmel, J. Dongarra, J. Du Croz, A. Greenbaum, S. Hammarling, A. McKenney, and D. Sorensen. LAPACK Users’ Guide Third Edition. SIAM, Philadelphia, 1999. Online Version: http://www.netlib.org/ lapack/lug/. Bruce W. Char, Keith O. Geddes, Gaston H. Gonnet, Benton Leong, Michael B. Monagan, and Stephen M. Watt. First Leaves: A Tutorial Introduction to Maple V. Springer-Verlag, Berlin, Germany / Heidelberg, Germany / London, UK / etc., 1992. ISBN 0-38797621-3, 3-540-97621-3. Also available in Japanese, ISBN 4-43170651-8. Helmut Herold. Linux-Unix-Grundlagen. Addison Wesley, 1999. Brian W. Kernighan and Dennis M. Ritchie. The C Programming Language. Prentice-Hall, Upper Saddle River, NJ 07458, USA, 1978. ISBN 0-13-110163-3. 337 338 LITERATURVERZEICHNIS Michael Kofler. Mathematica, Einführung und Leitfaden für den Praktiker. Addison Wesley, Bonn, Paris, Reading - Mass., 1992. Michael Kofler. Maple V Release 2, Einführung und Leitfaden für den Praktiker. Addison Wesley, Bonn, Paris, Reading - Mass., 1994. Michael Kofler. Linux, Installation, Konfiguration, Anwendung. Addison Wesley, Bonn, Paris, Reading - Mass., 2000. Helmut Kopka. LaTeX Einführung, volume 1. Addison Wesley, Bonn, Paris, Reading - Mass., 1994. M.K. Ng. Iterative Methods For Toeplitz Systems. Iterative Methods for Toeplitz Systems. Oxford University Press, 2004. ISBN 9780198504207. URL http://books.google.at/books? id=o4I9TTWRE50C. Dennis W. Ritchie. The evolution of the Unix time-sharing system. In Jeffrey M. Tobias, editor, Language design and programming methodology: proceedings of a symposium held at Sydney, Australia, 10–11 September 1979, volume 79 of Lecture Notes in Computer Science, pages 25–35, Berlin, Germany / Heidelberg, Germany / London, UK / etc., 1980. Springer-Verlag. ISBN 0-387-097457. URL http://cm.bell-labs.com/cm/cs/who/dmr/hist.html. Sponsored by the Australian Atomic Energy Commission and the University of New South Wales. Frank Ronneburg. Debian GNU, Linux-Anwenderhandbuch. Addison-Wesley, Reading, MA, USA, 2001. ISBN 3-8273-1748-7. Includes CD-ROM. D. Stoyan. Stochastik für Ingenieure und Naturwissenschaftler. Akademie-Verlag, Berlin, 1993. LITERATURVERZEICHNIS 339 J. W. Tukey. Exploratory Data Analysis, volume 1. Addison-Wesley, 1970. (Limited Preliminary Edition). Stephen Wolfram. Mathematica, Ein System für Mathematik auf dem Computer. Addison Wesley, Bonn, Paris, Reading - Mass., 1996. Index Index erzeugen eines, 89 Stichwortverzeichnis, 89 UNIX Geschichte, 18 340