From 0bbcfd5323580327f209cee5e1ef152f6bdcd621 Mon Sep 17 00:00:00 2001 From: Michele Nottoli <michele.nottoli@gmail.com> Date: Mon, 6 Nov 2023 10:13:41 +0100 Subject: [PATCH] Localization. --- 4_Arrays_Linear_Algebra_de.ipynb | 1122 ++++++++++++++++++++++++++++++ 4_Arrays_Linear_Algebra_en.ipynb | 1107 +++++++++++++++++++++++++++++ 2 files changed, 2229 insertions(+) create mode 100644 4_Arrays_Linear_Algebra_de.ipynb create mode 100644 4_Arrays_Linear_Algebra_en.ipynb diff --git a/4_Arrays_Linear_Algebra_de.ipynb b/4_Arrays_Linear_Algebra_de.ipynb new file mode 100644 index 0000000..5e7e811 --- /dev/null +++ b/4_Arrays_Linear_Algebra_de.ipynb @@ -0,0 +1,1122 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2af2061a-6e63-4efd-86f9-8636473f0645", + "metadata": {}, + "source": [ + "# Arrays, Vektoren, Matrizen und Lineare Algebra" + ] + }, + { + "cell_type": "markdown", + "id": "0e2d205f-2d14-4f9f-ac94-9addc71dd662", + "metadata": {}, + "source": [ + "## Arrays\n", + "\n", + "Ein Array ist eine Folge von Werten, die jeden beliebigen Typs sein können. Die Werte in einem Array werden Elemente oder manchmal auch Items genannt.\n", + "\n", + "Es gibt mehrere Möglichkeiten, ein neues Array zu erstellen; die einfachste besteht darin, die Elemente in eckige Klammern (`[ ]`) einzuschließen:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9ecf8d02-ba1c-4296-a9bd-d0a747068e85", + "metadata": {}, + "outputs": [], + "source": [ + "a1 = [10, 20, 30, 40]\n", + "a2 = [\"hi\", \"this\", \"is\", \"an\", \"array\"]\n", + "@show a1 a2;\n" + ] + }, + { + "cell_type": "markdown", + "id": "c60badf7-a824-45ed-9334-ae7cd61e9930", + "metadata": {}, + "source": [ + "Das erste Beispiel ist ein Array von vier Ganzzahlen. Das zweite ist ein Array von fünf Zeichenketten. Die Elemente eines Arrays müssen nicht denselben Typ haben. Das folgende Array enthält eine Zeichenkette, eine Gleitkommazahl, eine Ganzzahl und ein weiteres Array:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52cb6c55-90c0-459b-86cf-ae35ab43abcf", + "metadata": {}, + "outputs": [], + "source": [ + "a3 = [\"spam\", 2.0, 5, [10, 20]]\n" + ] + }, + { + "cell_type": "markdown", + "id": "9b2b7f36-e8a4-4d5a-afd8-e0598dca60bc", + "metadata": {}, + "source": [ + "Ein Array innerhalb eines anderen Arrays kann verschachtelt sein.\n", + "Ein Array, das keine Elemente enthält, wird als leeres Array bezeichnet; es kann mit leeren Klammern, d.h. `[]`, erstellt werden.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e661e5d-b43b-4d1f-a805-32f96d2c741f", + "metadata": {}, + "outputs": [], + "source": [ + "cheeses = [\"Cheddar\", \"Edam\", \"Gouda\"];\n", + "numbers = [42, 123];\n", + "empty = [];\n", + "print(cheeses, \" \", numbers, \" \", empty)\n" + ] + }, + { + "cell_type": "markdown", + "id": "f84a7afa-2329-4fae-bdb8-cf84d89d2d1b", + "metadata": {}, + "source": [ + "Die Art des Arrays wird zwischen geschweiften Klammern angegeben und besteht aus einem Typ und einer Zahl. Die Zahl gibt die Dimensionen an. Das leere Array enthält Werte vom Typ `Any`, d.h. es kann Werte aller Typen aufnehmen.\n", + "\n", + "Die Syntax zum Zugriff auf die Elemente eines Arrays ist der eckige Klammernoperator. Der Ausdruck innerhalb der Klammern gibt den Index an. Beachten Sie, dass die Indizes bei 1 beginnen:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ab05daa-9cb1-4dcd-9a01-03dda978de6f", + "metadata": {}, + "outputs": [], + "source": [ + "cheeses[1]\n" + ] + }, + { + "cell_type": "markdown", + "id": "d927a90b-f602-4e02-9183-3d96233f0e9d", + "metadata": {}, + "source": [ + "Im Gegensatz zu Tupeln sind Arrays **veränderlich**. Wenn der eckige Klammernoperator auf der linken Seite einer Zuweisung erscheint, identifiziert er das Element des Arrays, das zugewiesen wird:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "01a4d81f-ddd4-4fa0-a1de-e5cfa13b496f", + "metadata": {}, + "outputs": [], + "source": [ + "cheeses[2] = \"Gorgonzola\"\n", + "print(cheeses)\n" + ] + }, + { + "cell_type": "markdown", + "id": "1f6ef27c-3265-4fb1-95ef-cd782d67c529", + "metadata": {}, + "source": [ + "Die Regeln für Array-Indizes lauten wie folgt:\n", + " - Jeder ganzzahlige Ausdruck kann als Index verwendet werden.\n", + " - Wenn Sie versuchen, auf ein Element, das nicht existiert, zuzugreifen oder zu überschreiben, erhalten Sie einen `BoundsError`.\n", + " - Das Schlüsselwort `end` zeigt auf den letzten Index des Arrays.\n", + "\n", + "Der Operator `∈` (oder `in`) funktioniert auch bei Arrays:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "576fd3ae-aa20-4178-a52c-ac8e4b4fed29", + "metadata": {}, + "outputs": [], + "source": [ + "@show \"Gouda\" ∈ cheeses\n", + "@show \"Brie\" in cheeses;\n" + ] + }, + { + "cell_type": "markdown", + "id": "7b1e1fab-3c3e-405c-b7dd-f03d4a23d200", + "metadata": {}, + "source": [ + "### Durchlaufen eines Arrays\n", + "\n", + "Die häufigste Methode, um die Elemente eines Arrays zu durchlaufen, ist mit einer for-Schleife. Die Syntax ist die gleiche wie bei Zeichenketten:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51885e2d-3055-4433-b0f8-e561c88f888b", + "metadata": {}, + "outputs": [], + "source": [ + "for cheese in cheeses\n", + " println(cheese)\n", + "end\n" + ] + }, + { + "cell_type": "markdown", + "id": "512d919e-cb7a-483c-aa61-0ef08baab3ad", + "metadata": {}, + "source": [ + "Dies funktioniert gut, wenn Sie nur die Elemente des Arrays lesen müssen, da Sie nur Kopien der Elemente erhalten und das Ändern der Kopien das Array nicht verändert. Wenn Sie jedoch die Elemente überschreiben oder aktualisieren möchten, benötigen Sie die Indizes. Eine gängige Methode, dies zu tun, ist die Verwendung der integrierten Funktion `eachindex`:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00b187f3-7a0d-4741-82e3-7dc286dcf34f", + "metadata": {}, + "outputs": [], + "source": [ + "for i in eachindex(numbers)\n", + " numbers[i] = numbers[i] * 2\n", + "end\n" + ] + }, + { + "cell_type": "markdown", + "id": "f4a5928a-fcc0-4121-b117-fc6a66b7aa78", + "metadata": {}, + "source": [ + "Eine `for`-Schleife über ein leeres Array führt niemals den Körper aus:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17ebecd7-63cc-46d8-b2c5-8721aa616e26", + "metadata": {}, + "outputs": [], + "source": [ + "for x in []\n", + " println(\"This can never happens.\")\n", + "end\n" + ] + }, + { + "cell_type": "markdown", + "id": "7938c983-b5a4-420c-88b4-c1c9a5c5cc90", + "metadata": {}, + "source": [ + "`length` gibt die Anzahl der Elemente im Array zurück.\n", + "Obwohl ein Array ein anderes Array enthalten kann, zählt das verschachtelte Array immer noch als ein einzelnes Element. Die Länge dieses Arrays beträgt vier:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4abdcef7-f424-4d52-91f2-00d1a0387c8c", + "metadata": {}, + "outputs": [], + "source": [ + "array = [\"spam\", 1, [\"Brie\", \"Roquefort\", \"Camembert\"], [1, 2, 3]]\n", + "@show length(array);\n" + ] + }, + { + "cell_type": "markdown", + "id": "a8557e05-a1f2-4a93-b834-df5b9936bb3c", + "metadata": {}, + "source": [ + "### Array-Schnitte\n", + "Der Slice-Operator ermöglicht es Ihnen, Teile eines Arrays auszuwählen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d31afed-81c8-42ef-bbb3-18d1c1d16548", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c', 'd', 'e', 'f']\n", + "print(t[1:3])\n", + "print(t[3:end])\n" + ] + }, + { + "cell_type": "markdown", + "id": "406a15ee-6bd8-45eb-a03b-fed62fe7f99a", + "metadata": {}, + "source": [ + "Der Slice-Operator `[:]` erstellt eine Kopie des gesamten Arrays. Beachten Sie, dass `t2 = t` keine Kopie erstellt. \n", + "Da Arrays veränderlich sind, ist es oft nützlich, eine Kopie zu erstellen, bevor Operationen durchgeführt werden, die Arrays verändern." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c73d80ff-ab60-418f-a0a4-0b2fae76f42e", + "metadata": {}, + "outputs": [], + "source": [ + "t1 = t[:]\n", + "@show t1 === t\n", + "\n", + "t2 = t\n", + "@show t2 === t;\n" + ] + }, + { + "cell_type": "markdown", + "id": "ba8b2dcc-0f00-42f1-a850-579448a86d8e", + "metadata": {}, + "source": [ + "Ein Slice-Operator auf der linken Seite einer Zuweisung kann mehrere Elemente aktualisieren:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c75b53ad-a98b-451c-be5a-9e0d939e23c3", + "metadata": {}, + "outputs": [], + "source": [ + "t[2:3] = ['x', 'y']\n", + "print(t)\n" + ] + }, + { + "cell_type": "markdown", + "id": "1ce6853d-6d8e-4bea-a342-4969c63352d5", + "metadata": {}, + "source": [ + "### Array-Bibliothek\n", + "Julia stellt Funktionen bereit, die auf Arrays wirken. Zum Beispiel fügt `push!` ein neues Element am Ende eines Arrays hinzu (beachten Sie das Ausrufezeichen, da es veränderlich ist). `pushfirst!` fügt ein neues Element am Anfang des Arrays hinzu." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "680e7967-fffb-4112-afb2-422e8e6b87ba", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c']\n", + "push!(t, 'd')\n", + "pushfirst!(t, '0')\n", + "print(t)\n" + ] + }, + { + "cell_type": "markdown", + "id": "4770945a-ff8e-4c60-82a2-0b545f569f47", + "metadata": {}, + "source": [ + "`append!` fügt die Elemente des zweiten Arrays am Ende des ersten hinzu:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b614b4ef-f34a-4aad-8b6d-973ffc8e16de", + "metadata": {}, + "outputs": [], + "source": [ + "t1 = ['a', 'b', 'c']\n", + "t2 = ['d', 'e']\n", + "append!(t1, t2)\n", + "print(t1)\n" + ] + }, + { + "cell_type": "markdown", + "id": "769aee98-5aeb-402b-81d7-23d81d596966", + "metadata": {}, + "source": [ + "Die Funktion `insert!` fügt ein Element an einem bestimmten Index ein:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1cb2569-4b2b-4e8c-a9bd-2bb0a14bfbca", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c']\n", + "print(insert!(t, 2, 'x'))\n" + ] + }, + { + "cell_type": "markdown", + "id": "2e5a4efd-a107-4129-b3ee-de9af8ce0284", + "metadata": {}, + "source": [ + "`sort!` ordnet die Elemente des Arrays von niedrig nach hoch, während `sort` eine Kopie der Elemente des Arrays in sortierter Reihenfolge zurückgibt:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81fa98e2-4bad-4db9-a784-411069ab167b", + "metadata": {}, + "outputs": [], + "source": [ + "t1 = ['d', 'c', 'e', 'b', 'a']\n", + "t2 = ['d', 'c', 'e', 'b', 'a']\n", + "\n", + "sort!(t1)\n", + "println(t1)\n", + "\n", + "t3 = sort(t2)\n", + "println(t3)\n", + "@show t3 === t2;\n" + ] + }, + { + "cell_type": "markdown", + "id": "c3e790e9-fa20-41d1-b43b-67ba30f89229", + "metadata": {}, + "source": [ + "Es gibt mehrere Möglichkeiten, Elemente aus einem Array zu löschen. Wenn Sie den Index des zu löschenden Elements kennen, können Sie `splice!` verwenden. `splice!` ändert das Array und gibt das entfernte Element zurück. `deleteat!` tut dasselbe, gibt jedoch das Element nicht zurück." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f391ab7c-2890-4b70-904a-8e606ec424f2", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c']\n", + "element = splice!(t, 2)\n", + "println(t)\n", + "println(element)\n" + ] + }, + { + "cell_type": "markdown", + "id": "b74c89cd-8d90-459f-a403-5276474736ee", + "metadata": {}, + "source": [ + "`pop!` löscht das letzte Element und gibt es zurück:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47cee6d5-78c2-4f44-af74-054e05fb0d2c", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c']\n", + "element = pop!(t)\n", + "println(t)\n", + "println(element)\n" + ] + }, + { + "cell_type": "markdown", + "id": "4c08249e-8340-424a-8ce2-4469df29e8ed", + "metadata": {}, + "source": [ + "### Übung\n", + " - Die Kernfunktionalität bietet mehrere andere Funktionen, die auf ein Array wirken. Versuchen Sie die folgenden Funktionen mit einem Array `x` und versuchen Sie zu erraten, was sie tun: `ndims(x)`, `eltype(x)`, `length(x)`, `size(x)`, `size(x, 1)`, `reshape(x, 3, 3)`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c6e8e00-924b-4c88-8d8c-dfbcd18c6733", + "metadata": {}, + "outputs": [], + "source": [ + "x = [1, 2, 3, 4, 5, 6, 7, 8, 9];\n", + "# TODO implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "cc1d4b7f-5639-4638-aea3-52e2d52f8fd4", + "metadata": {}, + "source": [ + "### Punkt-Syntax\n", + "Für jeden binären Operator wie `^` gibt es einen entsprechenden Punktoperator `.^`, der automatisch definiert ist, um ^ elementweise auf Arrays anzuwenden. Zum Beispiel ist `[1, 2, 3]^3` nicht definiert, aber `[1, 2, 3].^3` ist definiert und berechnet das ergebnis für jedes Element `[1^3, 2^3, 3^3]`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0aa2e922-aa84-455c-8737-dcaee139a1ba", + "metadata": {}, + "outputs": [], + "source": [ + "print([1, 2, 3] .^ 3)\n" + ] + }, + { + "cell_type": "markdown", + "id": "7a18830c-f3cd-469d-a0b9-f206ee7aec7b", + "metadata": {}, + "source": [ + "Jede Julia-Funktion `f` kann mit der Punkt-Syntax elementweise auf jedes Array angewendet werden. Zum Beispiel, um ein Array von Zeichenketten zu großzügig machen, benötigen wir keine explizite Schleife:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea7d08d7-1417-47e1-be71-abeb8ba80c1e", + "metadata": {}, + "outputs": [], + "source": [ + "t = uppercase.([\"abc\", \"def\", \"ghi\"])\n", + "print(t)\n" + ] + }, + { + "cell_type": "markdown", + "id": "073001cf-0661-4827-b693-a08ca06967b7", + "metadata": {}, + "source": [ + "### Arrays und Zeichenketten\n", + "\n", + "Eine Zeichenkette ist eine Folge von Zeichen und ein Array ist eine Folge von Werten, aber ein Array von Zeichen ist nicht dasselbe wie eine Zeichenkette. Um von einer Zeichenkette zu einem Array von Zeichen zu konvertieren, können Sie die Funktion `collect` verwenden:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6e467ca-3130-449d-b876-f77720b515b5", + "metadata": {}, + "outputs": [], + "source": [ + "print(collect(\"spam\"))\n" + ] + }, + { + "cell_type": "markdown", + "id": "72c17230-0d1b-46ba-9711-1eb3328839c5", + "metadata": {}, + "source": [ + "Wenn Sie eine Zeichenkette in Wörter zerlegen möchten, können Sie die Funktion `split` verwenden. Das Standardtrennzeichen ist das Leerzeichen, aber Sie können ein benutzerdefiniertes Trennzeichen als zweites Argument übergeben." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96a09506-444f-4733-b047-f5de500fbfc2", + "metadata": {}, + "outputs": [], + "source": [ + "@show split(\"building an array of strings\")\n", + "@show split(\"02.11.2023\", \".\");\n" + ] + }, + { + "cell_type": "markdown", + "id": "51981f83-608f-4c41-9321-13de5facb204", + "metadata": {}, + "source": [ + "Schließlich ist `join` die Umkehrung von split. Es nimmt ein Array von Strings und verkettet die Elemente:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43e7272d-2a32-441f-86c0-2fa532411ff6", + "metadata": {}, + "outputs": [], + "source": [ + "t = [\"building\", \"a\", \"string\"]\n", + "@show join(t)\n", + "@show join(t, \" \")\n", + "@show join(t, \"-\");\n" + ] + }, + { + "cell_type": "markdown", + "id": "acf522cd-0297-4f5c-873a-3309ce68b9d8", + "metadata": {}, + "source": [ + "### Übungen\n", + " - Schreiben Sie eine Funktion namens `reverse_array(x)`, die als Eingabe ein Array nimmt und ein **neues** Array mit den Elementen in umgekehrter Reihenfolge zurückgibt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45c7bffe-c8df-440f-9db0-7923969c20fb", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "927e6892-cc03-452f-bd65-ec895cae47ff", + "metadata": {}, + "source": [ + " - Schreiben Sie eine Funktion namens `reverse_array!(x)`, die das Array vor Ort ändert, indem sie seine Elemente umkehrt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19607e02-107e-4edd-90a8-abdca24fae6f", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "b0311dcb-964b-457c-b041-789673f732ca", + "metadata": {}, + "source": [ + " - Schreiben Sie eine Funktion namens `even_numbers(x)`, die als Eingabe ein Array von Ganzzahlen nimmt und ein neues Array zurückgibt, das nur die geraden Elemente enthält." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9babe5e0-2c11-4481-9938-42ec2f697e6b", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "d4b62fae-5d5d-46ac-94d8-b99b9f8aeb13", + "metadata": {}, + "source": [ + "## Vektoren und Matrizen\n", + "\n", + "Im Allgemeinen können Arrays beliebig viele Dimensionen haben. Mit dieser Zeile instantiieren wir ein 2x3x4-Array aus ganzen Nullen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af571cb0-92be-4876-9a66-6217620c9671", + "metadata": {}, + "outputs": [], + "source": [ + "A = zeros(Int, 2, 3, 4)\n", + "@show typeof(A);\n" + ] + }, + { + "cell_type": "markdown", + "id": "d806b78a-e97f-47b1-9ecb-409bf5a2c1c2", + "metadata": {}, + "source": [ + "Wenn jedoch die Dimension des Arrays 1 oder 2 ist, ist der Typ entsprechend `Vector` oder `Matrix`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46f3c7e3-e592-47df-abf4-3b9d650fb68d", + "metadata": {}, + "outputs": [], + "source": [ + "v = [1, 2, 3, 4, 5]\n", + "@show typeof(v)\n", + "m = [1 2 3; 4 5 6; 7 8 9]\n", + "@show typeof(m);\n" + ] + }, + { + "cell_type": "markdown", + "id": "3e29c3ab-1fdb-4e74-b4fc-ca77690a33f1", + "metadata": {}, + "source": [ + "**Hinweis:** Zur Instantiierung einer Matrix sind keine Kommas zwischen den Elementen erforderlich. Die folgende Zeile wird eine 1x3-Matrix und nicht einen Vektor erzeugen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "490491f2-313b-41e2-9015-1ef7687beded", + "metadata": {}, + "outputs": [], + "source": [ + "m = [1 2 3]\n", + "@show typeof(m);\n" + ] + }, + { + "cell_type": "markdown", + "id": "62dfd73b-dd75-4dcc-970d-02c9881627bf", + "metadata": {}, + "source": [ + "Sie können auch explizit überprüfen, dass ein Vektor einfach ein eindimensionales Array ist und dass eine Matrix einfach ein zweidimensionales Array ist." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c19aca9-a3ab-4ae7-9ecf-021ef89e73c8", + "metadata": {}, + "outputs": [], + "source": [ + "@show Vector{Any} === Array{Any, 1}\n", + "@show Matrix{Any} === Array{Any, 2}\n", + "@show Matrix{Any} === Array{Any, 3};\n" + ] + }, + { + "cell_type": "markdown", + "id": "a2957207-e7b7-43d4-9015-c2649bcc4183", + "metadata": {}, + "source": [ + "**Hinweis:** `Array` und `Vector` sind immer konkrete Typen, unabhängig von der Art der Elemente. Daher geben die üblichen Typbeziehungen nicht die erwarteten Ergebnisse:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c94e645f-1e50-4999-be3b-e97de198b2d9", + "metadata": {}, + "outputs": [], + "source": [ + "@show Vector{Float32} <: Vector{Real}\n", + "@show Vector{Real} <: Vector{Any};\n" + ] + }, + { + "cell_type": "markdown", + "id": "a101372e-20c1-4ff6-87c7-99ac21ac9f88", + "metadata": {}, + "source": [ + "### Vektoren\n", + "\n", + "Vektoren können mit eckigen Klammern `[]` erstellt werden oder durch Verwendung des `Vector`-Konstrukts. Der Datentyp kann explizit angegeben werden." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e9049f28-4a9f-4416-9f80-664e7d786bc1", + "metadata": {}, + "outputs": [], + "source": [ + "v1 = [1, 2, 3]\n", + "v2 = Float32[1, 2, 3]\n", + "@show typeof(v1)\n", + "@show typeof(v2);\n" + ] + }, + { + "cell_type": "markdown", + "id": "a312114c-525c-42e5-8676-40e382a789c0", + "metadata": {}, + "source": [ + "Es gibt auch andere schnelle Möglichkeiten, Arrays mit üblichen Inhalten wie Nullen, Einsen oder Zufallszahlen zu erzeugen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0331ed6e-b857-4074-84bf-dc9eb9c95fc1", + "metadata": {}, + "outputs": [], + "source": [ + "v1 = zeros(5)\n", + "v2 = ones(5)\n", + "v3 = rand(5)\n", + "@show v1 v2 v3;\n" + ] + }, + { + "cell_type": "markdown", + "id": "59c0734e-99e9-4450-a9e1-e970233d5b44", + "metadata": {}, + "source": [ + "Es ist auch möglich, einen bestimmten Datentyp zu erzwingen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a0b81571-1044-48ab-9cf6-639c32b4738f", + "metadata": {}, + "outputs": [], + "source": [ + "v1 = zeros(Integer, 5)\n", + "v2 = ones(Float32, 5)\n", + "v3 = rand(Float32, 10)\n", + "@show v1 v2 v3;\n" + ] + }, + { + "cell_type": "markdown", + "id": "28a32ca8-3eb2-4113-a293-822e95f96b81", + "metadata": {}, + "source": [ + "Standardmäßige mathematische Operationen können mit der üblichen Notation durchgeführt werden." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53a0f9b1-83ea-4914-9546-db5c248c7852", + "metadata": {}, + "outputs": [], + "source": [ + "v1 = [1, 2, 3]\n", + "v2 = [1, 1, 1]\n", + "\n", + "@show v1 - v2\n", + "@show v1 + 2*v2;\n" + ] + }, + { + "cell_type": "markdown", + "id": "43b66537-bb2c-487f-8144-d3774f6d8cdf", + "metadata": {}, + "source": [ + "Das Skalarprodukt kann mit der `dot`-Funktion berechnet werden, die Teil des `LinearAlgebra`-Pakets ist." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a98bac2e-9b09-4b6e-9666-f19eeddf2f67", + "metadata": {}, + "outputs": [], + "source": [ + "using LinearAlgebra\n", + "v = [1, 2, 3]\n", + "@show dot(v, v);\n" + ] + }, + { + "cell_type": "markdown", + "id": "15727030-afce-436e-98ec-e1703b793f2c", + "metadata": {}, + "source": [ + "Schließlich kann die Transponierte mit dem `'`-Operator abgerufen werden." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91541224-d1ff-4b07-850f-7fc168851b39", + "metadata": {}, + "outputs": [], + "source": [ + "@show typeof(v) v\n", + "@show typeof(v') v';\n" + ] + }, + { + "cell_type": "markdown", + "id": "8996d0f1-a663-4489-8cde-d81110e093b5", + "metadata": {}, + "source": [ + "### Matrizen\n", + "\n", + "Matrizen können wieder auf verschiedene Arten initialisiert werden." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb41a853-5ce9-4c37-8cd4-62f54ff6312b", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = zeros(Integer, 3, 3)\n", + "m2 = ones(Float32, 3, 3)\n", + "m3 = rand(Float32, 3, 3)\n", + "m4 = Float32[1 2 3; 4 5 6]\n", + "@show m1 m2 m3 m4;\n" + ] + }, + { + "cell_type": "markdown", + "id": "7339ad4b-fe9b-4161-9eeb-2bad5df510c0", + "metadata": {}, + "source": [ + "Wenn Sie die Diagonale (als Vektor) haben und eine Diagonalmatrix konstruieren möchten, können Sie die Funktion `diagm` verwenden." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "906b5a91-3a29-4c9c-947a-d8a88a06dec2", + "metadata": {}, + "outputs": [], + "source": [ + "@show diagm([1, 2, 3]);\n" + ] + }, + { + "cell_type": "markdown", + "id": "e591d680-3ba9-43a6-a014-5799dfcc1959", + "metadata": {}, + "source": [ + "Die Einheitsmatrix wird als `I` dargestellt. **Hinweis**: Dies ist eigentlich keine Matrix, sondern eher eine `UniformScaling`, die die Wirkung der Identitätsoperation ohne die Notwendigkeit von alloziertem Speicher bringt. Die einheitlichen Skalierungen passen sich automatisch an die Größe der Matrizen an, auf die sie wirken." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73a7cd9e-1586-4215-8623-cccd465f6979", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [1 2 3; 3 4 5; 6 7 8]\n", + "@show I*m1;\n" + ] + }, + { + "cell_type": "markdown", + "id": "77643776-b23a-4b2e-b6ee-b84304541d9a", + "metadata": {}, + "source": [ + "Auch die Operationen `+` und `-` können problemlos auf Matrizen angewendet werden, aber in diesem Fall ist auch die Operation `*` definiert." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cbcd610-9cbd-4c73-9632-c4a6d47b374a", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [1 2 3; 3 4 5; 6 7 8]\n", + "m2 = [1 0 0; 0 0 0; 0 0 0]\n", + "@show m1 * m2;\n" + ] + }, + { + "cell_type": "markdown", + "id": "03daee60-cf26-4d80-87a4-18ddebedb8b7", + "metadata": {}, + "source": [ + "Um die Matrizen zu invertieren, können Sie die Funktion `inv` oder die subtilere Operation `/` verwenden." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70de8ba6-6f63-4a43-9ff2-efff2b9a1368", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [1 2; -1 2]\n", + "@show I/m1;\n", + "@show inv(m1);\n" + ] + }, + { + "cell_type": "markdown", + "id": "11e3d462-b24f-4099-9590-3ae27af92985", + "metadata": {}, + "source": [ + "Die Transponierte funktioniert auch bei Matrizen, und beachten Sie, dass bei komplexen Zahlen eine Adjunkte vorliegt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3bbc37c-0bcd-4a54-891f-ec94ee437724", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [0 -1im ; 2im 0];\n", + "@show m1\n", + "@show m1';\n" + ] + }, + { + "cell_type": "markdown", + "id": "a9429302-aeb6-4207-880d-d87ebf87974e", + "metadata": {}, + "source": [ + "Schließlich ist es auch möglich, die Determinante und die Spur mithilfe der Funktionen `det` bzw. `tr` zu berechnen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b52aabb-fc61-4006-99a8-73bd418e810a", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [1 2 3; 3 4 5; 6 7 8]\n", + "@show det(m1);\n", + "@show tr(m1);\n" + ] + }, + { + "cell_type": "markdown", + "id": "8c1cc9db-da30-4ffd-828c-3fdc1611e113", + "metadata": {}, + "source": [ + "## Weiterführende Lineare Algebra\n", + "\n", + "Das Paket `LinearAlgebra` implementiert verschiedene fortgeschrittenere Operationen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "787b534f-57c4-47da-9eb2-cf5c8f8a8344", + "metadata": {}, + "outputs": [], + "source": [ + "m = [3 0.5 0.1; 0.1 5 0.2; 0.2 0.1 3]\n" + ] + }, + { + "cell_type": "markdown", + "id": "ff83a09a-6ede-44df-8151-96e7ce961489", + "metadata": {}, + "source": [ + " - Eigenvalue decomposition" + ] + }, + { + "cell_type": "markdown", + "id": "026f77af-fb87-4d41-88e3-a5f27f2e7305", + "metadata": {}, + "source": [ + " - Eigenwertzerlegung" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0ac2f75-02c4-482a-b668-baff9aac3128", + "metadata": {}, + "outputs": [], + "source": [ + "λ, V = eigen(m)\n", + "m1 = V * diagm(λ) * inv(V)\n" + ] + }, + { + "cell_type": "markdown", + "id": "e9ef9a44-6305-4549-b93e-10b77d2dcd0c", + "metadata": {}, + "source": [ + " - Singulärwertzerlegung" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4724ed84-0ac8-41e9-affd-d3ed0b44172b", + "metadata": {}, + "outputs": [], + "source": [ + "U, λ, V = svd(m)\n", + "m1 = U * diagm(λ) * V'\n" + ] + }, + { + "cell_type": "markdown", + "id": "039a8cfb-0b4f-42e2-ab13-be9cda23fe0f", + "metadata": {}, + "source": [ + " - LU-Zerlegung" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4cfd0965-7f29-473c-86ab-24a50fb4e327", + "metadata": {}, + "outputs": [], + "source": [ + "L, U = lu(m)\n", + "m1 = L * U\n", + "@show L\n", + "@show U\n", + "@show m1;\n" + ] + }, + { + "cell_type": "markdown", + "id": "b90bc471-03a2-4257-8f91-aafcf70f9bfb", + "metadata": {}, + "source": [ + " - Cholesky-Zerlegung (erfordert eine hermitesche Matrix)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ad8a144-0829-4f65-b036-8bec7199e939", + "metadata": {}, + "outputs": [], + "source": [ + "h = m + m'\n", + "L = cholesky(h)\n" + ] + }, + { + "cell_type": "markdown", + "id": "585d7aa3-5ba4-4ea1-8874-95566bcd5de8", + "metadata": {}, + "source": [ + "Für weitere Informationen:\n", + "[https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/)" + ] + }, + { + "cell_type": "markdown", + "id": "9d9422fe-980b-417c-a33a-aea5050e9d3a", + "metadata": {}, + "source": [ + "## Übungen\n", + "\n", + " - Schreiben Sie eine Funktion, die die Quadratwurzel einer Matrix berechnet.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5553cb6e-c0e4-49c6-b75b-586e14d89426", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "4b1c5ca6-06c7-458f-ad36-1fbf2b8da387", + "metadata": {}, + "source": [ + " - Implementieren Sie einen Solver für lineare Systeme, der die [Jacobi-Methode](https://de.wikipedia.org/wiki/Jacobi-Verfahren) verwendet. Vergleichen Sie dann das Ergebnis mit der Standardlösung unter Verwendung der Matrixinversion." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6dc61c1a-5583-4238-b017-7202f8595789", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.9.3", + "language": "julia", + "name": "julia-1.9" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/4_Arrays_Linear_Algebra_en.ipynb b/4_Arrays_Linear_Algebra_en.ipynb new file mode 100644 index 0000000..caa8082 --- /dev/null +++ b/4_Arrays_Linear_Algebra_en.ipynb @@ -0,0 +1,1107 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4f17d479-4a7d-430c-a1ee-92fcd5ec0c16", + "metadata": {}, + "source": [ + "# Arrays, Vectors, Matrices and Linear Algebra" + ] + }, + { + "cell_type": "markdown", + "id": "c02d808e-3b3d-46c6-8199-320d6fa778aa", + "metadata": {}, + "source": [ + "## Arrays\n", + "\n", + "An array is a sequence of values that can be of any type. The values in an array are called elements or sometimes items. \n", + "\n", + "\n", + "There are several ways to create a new array; the simplest is to enclose the elements in square brackets (`[ ]`):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9ecf8d02-ba1c-4296-a9bd-d0a747068e85", + "metadata": {}, + "outputs": [], + "source": [ + "a1 = [10, 20, 30, 40]\n", + "a2 = [\"hi\", \"this\", \"is\", \"an\", \"array\"]\n", + "@show a1 a2;\n" + ] + }, + { + "cell_type": "markdown", + "id": "f9bbdffd-c37b-4317-b07d-d75003b2f568", + "metadata": {}, + "source": [ + "The first example is an array of four integers. The second is an array of five strings. The elements of an array don’t have to be the same type. The following array contains a string, a float, an integer, and another array:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52cb6c55-90c0-459b-86cf-ae35ab43abcf", + "metadata": {}, + "outputs": [], + "source": [ + "a3 = [\"spam\", 2.0, 5, [10, 20]]\n" + ] + }, + { + "cell_type": "markdown", + "id": "a364229e-ed7a-4b7d-b87f-40d073f24682", + "metadata": {}, + "source": [ + "An array within another array can be nested.\n", + "An array that contains no elements is called an empty array; you can create one with empty brackets, `[]`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e661e5d-b43b-4d1f-a805-32f96d2c741f", + "metadata": {}, + "outputs": [], + "source": [ + "cheeses = [\"Cheddar\", \"Edam\", \"Gouda\"];\n", + "numbers = [42, 123];\n", + "empty = [];\n", + "print(cheeses, \" \", numbers, \" \", empty)\n" + ] + }, + { + "cell_type": "markdown", + "id": "0275af11-5f69-49aa-8b8a-794c82f27590", + "metadata": {}, + "source": [ + "The kind of the array is specified between curly braces and is composed of a type and a number. The number indicates the dimensions. The array empty contains values of type `Any`., i.e. it can hold values of all types.\n", + "\n", + "The syntax for accessing the elements of an array is the bracket operator. The expression inside the brackets specifies the index. Remember that the indices start at 1:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ab05daa-9cb1-4dcd-9a01-03dda978de6f", + "metadata": {}, + "outputs": [], + "source": [ + "cheeses[1]\n" + ] + }, + { + "cell_type": "markdown", + "id": "7983a3ae-f9cc-410d-888b-f281812add8c", + "metadata": {}, + "source": [ + "Unlike tuples, arrays are **mutable**. When the bracket operator appears on the left side of an assignment, it identifies the element of the array that will be assigned: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "01a4d81f-ddd4-4fa0-a1de-e5cfa13b496f", + "metadata": {}, + "outputs": [], + "source": [ + "cheeses[2] = \"Gorgonzola\"\n", + "print(cheeses)\n" + ] + }, + { + "cell_type": "markdown", + "id": "918c617e-ffb9-4b90-b9e5-fea8e960ad1e", + "metadata": {}, + "source": [ + "Array indexes follow these rules:\n", + " - Any integer expression can be used as an index.\n", + " - If you try to read or write an element that does not exist, you get a `BoundsError`.\n", + " - The keyword `end` points to the last index of the array.\n", + "\n", + "The `∈` (or `in`) operator also works on arrays:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "576fd3ae-aa20-4178-a52c-ac8e4b4fed29", + "metadata": {}, + "outputs": [], + "source": [ + "@show \"Gouda\" ∈ cheeses\n", + "@show \"Brie\" in cheeses;\n" + ] + }, + { + "cell_type": "markdown", + "id": "7cd2705c-2d8f-43b3-bb9b-204c1674da50", + "metadata": {}, + "source": [ + "### Traversing an array\n", + "\n", + "The most common way to traverse the elements of an array is with a for loop. The syntax is the same as for strings:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51885e2d-3055-4433-b0f8-e561c88f888b", + "metadata": {}, + "outputs": [], + "source": [ + "for cheese in cheeses\n", + " println(cheese)\n", + "end\n" + ] + }, + { + "cell_type": "markdown", + "id": "3c83a447-2c3b-4cb2-8192-6f0f4249ae2e", + "metadata": {}, + "source": [ + "This works well if you only need to read the elements of the array, as you will get only copies of the elements and changing the copies does not change the array. But if you want to write or update the elements, you need the indices. A common way to do that is to use the built-in function `eachindex`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00b187f3-7a0d-4741-82e3-7dc286dcf34f", + "metadata": {}, + "outputs": [], + "source": [ + "for i in eachindex(numbers)\n", + " numbers[i] = numbers[i] * 2\n", + "end\n" + ] + }, + { + "cell_type": "markdown", + "id": "c6f78ad1-4717-42e8-bb94-6fe33691f563", + "metadata": {}, + "source": [ + "A `for` loop over an empty array never runs the body:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17ebecd7-63cc-46d8-b2c5-8721aa616e26", + "metadata": {}, + "outputs": [], + "source": [ + "for x in []\n", + " println(\"This can never happens.\")\n", + "end\n" + ] + }, + { + "cell_type": "markdown", + "id": "adcdb6d4-35bc-4a1c-bbe0-f023a9ab2509", + "metadata": {}, + "source": [ + "`length` returns the number of elements in the array.\n", + "Although an array can contain another array, the nested array still counts as a single element. The length of this array is four:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4abdcef7-f424-4d52-91f2-00d1a0387c8c", + "metadata": {}, + "outputs": [], + "source": [ + "array = [\"spam\", 1, [\"Brie\", \"Roquefort\", \"Camembert\"], [1, 2, 3]]\n", + "@show length(array);\n" + ] + }, + { + "cell_type": "markdown", + "id": "e64ec6e6-dfb7-4e05-ba9e-96cec72955bb", + "metadata": {}, + "source": [ + "### Array slices\n", + "The slice operator lets you select parts of an array." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d31afed-81c8-42ef-bbb3-18d1c1d16548", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c', 'd', 'e', 'f']\n", + "print(t[1:3])\n", + "print(t[3:end])\n" + ] + }, + { + "cell_type": "markdown", + "id": "beee009a-f707-4436-8144-8c7932f122e2", + "metadata": {}, + "source": [ + "The slice operator `[:]`, makes a copy of the whole array. Note that doing `t2 = t` does not create a copy. \n", + "Since arrays are mutable, it is often useful to make a copy before performing operations that modify arrays." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c73d80ff-ab60-418f-a0a4-0b2fae76f42e", + "metadata": {}, + "outputs": [], + "source": [ + "t1 = t[:]\n", + "@show t1 === t\n", + "\n", + "t2 = t\n", + "@show t2 === t;\n" + ] + }, + { + "cell_type": "markdown", + "id": "42e8a620-d702-4f92-8d20-58608294fb38", + "metadata": {}, + "source": [ + "A slice operator on the left side of an assignment can update multiple elements:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c75b53ad-a98b-451c-be5a-9e0d939e23c3", + "metadata": {}, + "outputs": [], + "source": [ + "t[2:3] = ['x', 'y']\n", + "print(t)\n" + ] + }, + { + "cell_type": "markdown", + "id": "2ed7448b-9efc-42bf-a24e-22a6e060a1eb", + "metadata": {}, + "source": [ + "### Array library\n", + "Julia provides functions that operate on arrays. For example, `push!` adds a new element to the end of an array (note the exclamation mark, as it is impure). `pushfirst!` adds a new element at the beginning of the array." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "680e7967-fffb-4112-afb2-422e8e6b87ba", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c']\n", + "push!(t, 'd')\n", + "pushfirst!(t, '0')\n", + "print(t)\n" + ] + }, + { + "cell_type": "markdown", + "id": "1fb6e797-9d98-4264-a7ad-7fd0b6eb3b89", + "metadata": {}, + "source": [ + "`append!` add the elements of the second array to the end of the first:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b614b4ef-f34a-4aad-8b6d-973ffc8e16de", + "metadata": {}, + "outputs": [], + "source": [ + "t1 = ['a', 'b', 'c']\n", + "t2 = ['d', 'e']\n", + "append!(t1, t2)\n", + "print(t1)\n" + ] + }, + { + "cell_type": "markdown", + "id": "b7a64ccf-077b-4f80-81a5-6c3ba0ac9ce3", + "metadata": {}, + "source": [ + "The function `insert!` inserts an element at a given index:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1cb2569-4b2b-4e8c-a9bd-2bb0a14bfbca", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c']\n", + "print(insert!(t, 2, 'x'))\n" + ] + }, + { + "cell_type": "markdown", + "id": "e5fd6caf-c66c-4c5a-8f95-f72a72caaf9d", + "metadata": {}, + "source": [ + "`sort!` arranges the elements of the array from low to high, while `sort` returns a copy of the elements of the array in order: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81fa98e2-4bad-4db9-a784-411069ab167b", + "metadata": {}, + "outputs": [], + "source": [ + "t1 = ['d', 'c', 'e', 'b', 'a']\n", + "t2 = ['d', 'c', 'e', 'b', 'a']\n", + "\n", + "sort!(t1)\n", + "println(t1)\n", + "\n", + "t3 = sort(t2)\n", + "println(t3)\n", + "@show t3 === t2;\n" + ] + }, + { + "cell_type": "markdown", + "id": "130876d4-db72-44a9-beec-c39b5b307df9", + "metadata": {}, + "source": [ + "There are several ways to delete elements from an array. If you know the index of the element you want to delete, you can use `splice!`. `splice!` modifies the array and returns the element that was removed. `deleteat!` does the same without returning the element." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f391ab7c-2890-4b70-904a-8e606ec424f2", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c']\n", + "element = splice!(t, 2)\n", + "println(t)\n", + "println(element)\n" + ] + }, + { + "cell_type": "markdown", + "id": "30b6b7fd-d07a-4792-8250-dd611653bbb1", + "metadata": {}, + "source": [ + "`pop!` deletes and returns the last element:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47cee6d5-78c2-4f44-af74-054e05fb0d2c", + "metadata": {}, + "outputs": [], + "source": [ + "t = ['a', 'b', 'c']\n", + "element = pop!(t)\n", + "println(t)\n", + "println(element)\n" + ] + }, + { + "cell_type": "markdown", + "id": "65fc2a2a-8b06-4dca-910e-2a5d37974460", + "metadata": {}, + "source": [ + "### Exercise\n", + " - The core functionality provides several other functions which act on an array. Given an array `x` try the following functions and try to guess what they do: `ndims(x)`, `eltype(x)`, `length(x)`, `size(x)`, `size(x, 1)`, `reshape(x, 3, 3)`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c6e8e00-924b-4c88-8d8c-dfbcd18c6733", + "metadata": {}, + "outputs": [], + "source": [ + "x = [1, 2, 3, 4, 5, 6, 7, 8, 9];\n", + "# TODO implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "393c8cf4-3c4d-400b-a1af-5af69f4dbf87", + "metadata": {}, + "source": [ + "### Dot syntax\n", + "For every binary operator like `^`, there is a corresponding dot operator .^ that is automatically defined to perform ^ element-by-element on arrays. For example, `[1, 2, 3]^3` is not defined, but `[1, 2, 3].^3` is defined as computing the elementwise result `[1^3, 2^3, 3^3]`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0aa2e922-aa84-455c-8737-dcaee139a1ba", + "metadata": {}, + "outputs": [], + "source": [ + "print([1, 2, 3] .^ 3)\n" + ] + }, + { + "cell_type": "markdown", + "id": "8e88b86e-0284-4679-83c3-9b90e47b4e33", + "metadata": {}, + "source": [ + "Any Julia function `f` can be applied elementwise to any array with the dot syntax. For example to capitalize an array of strings, we don’t need an explicit loop:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea7d08d7-1417-47e1-be71-abeb8ba80c1e", + "metadata": {}, + "outputs": [], + "source": [ + "t = uppercase.([\"abc\", \"def\", \"ghi\"])\n", + "print(t)\n" + ] + }, + { + "cell_type": "markdown", + "id": "93c1a351-0b39-4baf-86cc-66e1f9277db8", + "metadata": {}, + "source": [ + "### Arrays and strings\n", + "\n", + "A string is a sequence of characters and an array is a sequence of values, but an array of characters is not the same as a string. To convert from a string to an array of characters, you can use the function `collect`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6e467ca-3130-449d-b876-f77720b515b5", + "metadata": {}, + "outputs": [], + "source": [ + "print(collect(\"spam\"))\n" + ] + }, + { + "cell_type": "markdown", + "id": "c54747e6-1ebc-4b82-af65-77b982bc3835", + "metadata": {}, + "source": [ + "If you want to break a string into words, you can use the `split` function. The default delimiter is the space, but you can pass a custom delimiter as a second argument." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96a09506-444f-4733-b047-f5de500fbfc2", + "metadata": {}, + "outputs": [], + "source": [ + "@show split(\"building an array of strings\")\n", + "@show split(\"02.11.2023\", \".\");\n" + ] + }, + { + "cell_type": "markdown", + "id": "9f9cf023-a1d5-43d5-8322-13e8319b6637", + "metadata": {}, + "source": [ + "Finally, `join` is the inverse of split. It takes an array of strings and concatenates the elements:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43e7272d-2a32-441f-86c0-2fa532411ff6", + "metadata": {}, + "outputs": [], + "source": [ + "t = [\"building\", \"a\", \"string\"]\n", + "@show join(t)\n", + "@show join(t, \" \")\n", + "@show join(t, \"-\");\n" + ] + }, + { + "cell_type": "markdown", + "id": "c85d6757-a7ac-442c-879c-418137a2ebd0", + "metadata": {}, + "source": [ + "### Exercises\n", + " - Write a function called `reverse_array(x)` which takes as input an array and returns a **new** array with the elements in reverse order." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45c7bffe-c8df-440f-9db0-7923969c20fb", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "45a34bfb-67c1-4fbc-ae18-c60403dc3dda", + "metadata": {}, + "source": [ + " - Write a function called `reverse_array!(x)` which modifies in place the array by reversing its elements." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19607e02-107e-4edd-90a8-abdca24fae6f", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "b5fc2426-b30b-4295-bf8e-f0c9b152267c", + "metadata": {}, + "source": [ + " - Write a function `even_numbers(x)` which takes as input an array of integers and returns a new array containing only the elements which are even." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9babe5e0-2c11-4481-9938-42ec2f697e6b", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "8eb3354b-49b7-46df-9246-29dd520b92af", + "metadata": {}, + "source": [ + "## Vectors and Matrices\n", + "\n", + "In general arrays can have any number of dimensions, with this line we are instantiating a 2x3x4 array made of integer zeros." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af571cb0-92be-4876-9a66-6217620c9671", + "metadata": {}, + "outputs": [], + "source": [ + "A = zeros(Int, 2, 3, 4)\n", + "@show typeof(A);\n" + ] + }, + { + "cell_type": "markdown", + "id": "e2dafffd-9538-477b-9aec-7fb04d3f9d99", + "metadata": {}, + "source": [ + "However, if the dimension of the array is 1 or 2 the type is respectively `Vector` or `Matrix`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46f3c7e3-e592-47df-abf4-3b9d650fb68d", + "metadata": {}, + "outputs": [], + "source": [ + "v = [1, 2, 3, 4, 5]\n", + "@show typeof(v)\n", + "m = [1 2 3; 4 5 6; 7 8 9]\n", + "@show typeof(m);\n" + ] + }, + { + "cell_type": "markdown", + "id": "b1fc0ccd-1b16-4fec-9825-561198fa3763", + "metadata": {}, + "source": [ + " **Note:** instantiating a matrix does not require the commas between the elements. The following like will produce a 1x3 matrix and not a vector." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "490491f2-313b-41e2-9015-1ef7687beded", + "metadata": {}, + "outputs": [], + "source": [ + "m = [1 2 3]\n", + "@show typeof(m);\n" + ] + }, + { + "cell_type": "markdown", + "id": "9b91edb6-def2-4fa1-8b7a-b3db96e850be", + "metadata": {}, + "source": [ + "You can also explicitly check that a Vector is simply a 1d Array and that a Matrix is simply a 2d array." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c19aca9-a3ab-4ae7-9ecf-021ef89e73c8", + "metadata": {}, + "outputs": [], + "source": [ + "@show Vector{Any} === Array{Any, 1}\n", + "@show Matrix{Any} === Array{Any, 2}\n", + "@show Matrix{Any} === Array{Any, 3};\n" + ] + }, + { + "cell_type": "markdown", + "id": "00c7fd47-c3aa-41f7-81a4-d08510126d85", + "metadata": {}, + "source": [ + "**Note:** `Array` and `Vector` are always concrete types, independently from the type of the elements. So the usual type relations don't give the expected results:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c94e645f-1e50-4999-be3b-e97de198b2d9", + "metadata": {}, + "outputs": [], + "source": [ + "@show Vector{Float32} <: Vector{Real}\n", + "@show Vector{Real} <: Vector{Any};\n" + ] + }, + { + "cell_type": "markdown", + "id": "b9b86c55-2754-489e-87c6-851a3807d41d", + "metadata": {}, + "source": [ + "### Vectors\n", + "\n", + "Vectors can be created using square brakets `[]` or by using the `Vector` construct. The data type can be explicitly stated." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e9049f28-4a9f-4416-9f80-664e7d786bc1", + "metadata": {}, + "outputs": [], + "source": [ + "v1 = [1, 2, 3]\n", + "v2 = Float32[1, 2, 3]\n", + "@show typeof(v1)\n", + "@show typeof(v2);\n" + ] + }, + { + "cell_type": "markdown", + "id": "1a73ec49-da56-4724-af51-883dd3c92da9", + "metadata": {}, + "source": [ + "There are other short ways to generate arrays with usual content, like zeros, ones or random numbers." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0331ed6e-b857-4074-84bf-dc9eb9c95fc1", + "metadata": {}, + "outputs": [], + "source": [ + "v1 = zeros(5)\n", + "v2 = ones(5)\n", + "v3 = rand(5)\n", + "@show v1 v2 v3;\n" + ] + }, + { + "cell_type": "markdown", + "id": "95b897c2-f58c-48fa-a845-e0a6a8934b9f", + "metadata": {}, + "source": [ + "It is also possible to enforce a specific data type." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a0b81571-1044-48ab-9cf6-639c32b4738f", + "metadata": {}, + "outputs": [], + "source": [ + "v1 = zeros(Integer, 5)\n", + "v2 = ones(Float32, 5)\n", + "v3 = rand(Float32, 10)\n", + "@show v1 v2 v3;\n" + ] + }, + { + "cell_type": "markdown", + "id": "d6315e57-2614-4caf-a50c-0e192ac19672", + "metadata": {}, + "source": [ + "Standard mathematical operation can be performed with the usual notation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53a0f9b1-83ea-4914-9546-db5c248c7852", + "metadata": {}, + "outputs": [], + "source": [ + "v1 = [1, 2, 3]\n", + "v2 = [1, 1, 1]\n", + "\n", + "@show v1 - v2\n", + "@show v1 + 2*v2;\n" + ] + }, + { + "cell_type": "markdown", + "id": "09784b0e-9e8d-4271-a8d7-2c2ad409fad9", + "metadata": {}, + "source": [ + "The scalar product can be computed using the `dot` function, which is part of the `LinearAlgebra` package." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a98bac2e-9b09-4b6e-9666-f19eeddf2f67", + "metadata": {}, + "outputs": [], + "source": [ + "using LinearAlgebra\n", + "v = [1, 2, 3]\n", + "@show dot(v, v);\n" + ] + }, + { + "cell_type": "markdown", + "id": "4605b075-3754-46cc-9fbc-2c1bb22e95da", + "metadata": {}, + "source": [ + "Finally, the transpose can be accessed using the `'` operator." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91541224-d1ff-4b07-850f-7fc168851b39", + "metadata": {}, + "outputs": [], + "source": [ + "@show typeof(v) v\n", + "@show typeof(v') v';\n" + ] + }, + { + "cell_type": "markdown", + "id": "027dced2-896d-4070-93e3-1a175c537dc4", + "metadata": {}, + "source": [ + "### Matrices\n", + "\n", + "Matrices can be again initialized in various ways." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb41a853-5ce9-4c37-8cd4-62f54ff6312b", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = zeros(Integer, 3, 3)\n", + "m2 = ones(Float32, 3, 3)\n", + "m3 = rand(Float32, 3, 3)\n", + "m4 = Float32[1 2 3; 4 5 6]\n", + "@show m1 m2 m3 m4;\n" + ] + }, + { + "cell_type": "markdown", + "id": "19df2da4-a6fe-44d5-aacc-070e27086c37", + "metadata": {}, + "source": [ + "If you have the diagonal (vector) and you want to construct a diagonal matrix, you can use the `diagm` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "906b5a91-3a29-4c9c-947a-d8a88a06dec2", + "metadata": {}, + "outputs": [], + "source": [ + "@show diagm([1, 2, 3]);\n" + ] + }, + { + "cell_type": "markdown", + "id": "98f05747-23ba-46f1-afc1-31c5de94de8c", + "metadata": {}, + "source": [ + "The identity matrix is represented as a `I`. **Note**: this is not really a matrix, but rather a `UniformScaling` which brings the effect of the identity operation without needing allocated space. The uniform scalings automatically adapt to the size of the matrices they act on." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73a7cd9e-1586-4215-8623-cccd465f6979", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [1 2 3; 3 4 5; 6 7 8]\n", + "@show I*m1;\n" + ] + }, + { + "cell_type": "markdown", + "id": "0f341138-d1e7-425a-a54b-d5278ae1a48b", + "metadata": {}, + "source": [ + "Again the `+` and `-` operations can be readily used on matrices, but in this case also the `*` operation is defined." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cbcd610-9cbd-4c73-9632-c4a6d47b374a", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [1 2 3; 3 4 5; 6 7 8]\n", + "m2 = [1 0 0; 0 0 0; 0 0 0]\n", + "@show m1 * m2;\n" + ] + }, + { + "cell_type": "markdown", + "id": "06b6d25f-92a1-4768-bdd8-760fa9212879", + "metadata": {}, + "source": [ + "To invert the matrices it is possible to use the function `inv` or a more subtle `/` operation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70de8ba6-6f63-4a43-9ff2-efff2b9a1368", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [1 2; -1 2]\n", + "@show I/m1;\n", + "@show inv(m1);\n" + ] + }, + { + "cell_type": "markdown", + "id": "eab561b9-b034-49e6-a100-09b201ff4caa", + "metadata": {}, + "source": [ + "The transpose works also on matrices, and note that for complex numbers it is an adjoint." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3bbc37c-0bcd-4a54-891f-ec94ee437724", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [0 -1im ; 2im 0];\n", + "@show m1\n", + "@show m1';\n" + ] + }, + { + "cell_type": "markdown", + "id": "d827b0b8-ead4-48c7-83bd-399ef7927414", + "metadata": {}, + "source": [ + "Finally, it is also possible to compute the determinant and the trace using respectively the `det` and `tr` functions." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b52aabb-fc61-4006-99a8-73bd418e810a", + "metadata": {}, + "outputs": [], + "source": [ + "m1 = [1 2 3; 3 4 5; 6 7 8]\n", + "@show det(m1);\n", + "@show tr(m1);\n" + ] + }, + { + "cell_type": "markdown", + "id": "5c2d37bb-4417-4f9c-a894-352a2a5c741b", + "metadata": {}, + "source": [ + "## More advanced linear algebra\n", + "\n", + "The `LinearAlgebra` package implement various more advanced operations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "787b534f-57c4-47da-9eb2-cf5c8f8a8344", + "metadata": {}, + "outputs": [], + "source": [ + "m = [3 0.5 0.1; 0.1 5 0.2; 0.2 0.1 3]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0ac2f75-02c4-482a-b668-baff9aac3128", + "metadata": {}, + "outputs": [], + "source": [ + "λ, V = eigen(m)\n", + "m1 = V * diagm(λ) * inv(V)\n" + ] + }, + { + "cell_type": "markdown", + "id": "cba4ddfc-bcdf-4c3b-8fb4-1237ec15bf44", + "metadata": {}, + "source": [ + " - Singular value decomposition" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4724ed84-0ac8-41e9-affd-d3ed0b44172b", + "metadata": {}, + "outputs": [], + "source": [ + "U, λ, V = svd(m)\n", + "m1 = U * diagm(λ) * V'\n" + ] + }, + { + "cell_type": "markdown", + "id": "3ae3a97a-aa0d-41a4-b957-1346860ad638", + "metadata": {}, + "source": [ + " - LU decomposition" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4cfd0965-7f29-473c-86ab-24a50fb4e327", + "metadata": {}, + "outputs": [], + "source": [ + "L, U = lu(m)\n", + "m1 = L * U\n", + "@show L\n", + "@show U\n", + "@show m1;\n" + ] + }, + { + "cell_type": "markdown", + "id": "d9116b9e-7650-4421-8497-40a440a842b8", + "metadata": {}, + "source": [ + " - Cholesky (needs a Hermitian matrix)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ad8a144-0829-4f65-b036-8bec7199e939", + "metadata": {}, + "outputs": [], + "source": [ + "h = m + m'\n", + "L = cholesky(h)\n" + ] + }, + { + "cell_type": "markdown", + "id": "3f6ecf2e-0ca5-4fa4-ba39-541a7359564b", + "metadata": {}, + "source": [ + "For more information:\n", + "[https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/)" + ] + }, + { + "cell_type": "markdown", + "id": "bc8a12d1-a6af-4cd0-8f22-832d8b5eee92", + "metadata": {}, + "source": [ + "## Exercises\n", + "\n", + " - Write a function that computes the square root of a matrix." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5553cb6e-c0e4-49c6-b75b-586e14d89426", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + }, + { + "cell_type": "markdown", + "id": "62c05d6b-6772-407b-a3cd-581ef829af4d", + "metadata": {}, + "source": [ + " - Implement a solver for linear systems that uses the [Jacobi method](https://en.wikipedia.org/wiki/Jacobi_method). Then compare the result with the standard solution using matrix inversion." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6dc61c1a-5583-4238-b017-7202f8595789", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.9.3", + "language": "julia", + "name": "julia-1.9" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} -- GitLab