Matrizen & Grundoperationen
Matrizen & Vektoren erstellen
MATLAB (MATrix LABoratory) behandelt alle Variablen als Matrizen. Vektoren sind 1xN- oder Nx1-Matrizen. Leerzeichen oder Kommas trennen Elemente in einer Zeile, Semikolons erzeugen neue Zeilen. zeros, ones, eye, rand und magic erstellen häufige Testmatrizen. Der Doppelpunkt-Operator start:step:stop erzeugt Bereiche (Standard-Schritt 1). linspace(a, b, n) erstellt n gleichmäßig verteilte Punkte – ideal für Plot-Achsen.
% row vector
v = [1 2 3 4 5];
% column vector (semicolon = new row)
c = [1; 2; 3];
% 3x3 matrix
A = [1 2 3; 4 5 6; 7 8 9];
% special matrices
Z = zeros(3); % 3x3 zeros
O = ones(2, 4); % 2x4 ones
I = eye(3); % 3x3 identity
R = rand(2, 3); % 2x3 uniform random
N = randn(4); % 4x4 normal random
M = magic(4); % 4x4 magic square
D = diag([1 2 3]); % diagonal matrix
% linear spacing
l = linspace(0, 1, 5); % [0 0.25 0.5 0.75 1]
r = 0:0.5:2; % [0 0.5 1 1.5 2]Matrix-Indizierung & Slicing
MATLAB ist 1-indiziert (nicht 0-indiziert). Der Doppelpunkt : bedeutet 'alle' – A(:,2) ist die gesamte zweite Spalte. A(1:3, :) selektiert die Zeilen 1-3. 'end' bezieht sich auf den letzten Index in dieser Dimension. Logische Indizierung (A(A > 5)) ist extrem mächtig – sie extrahiert oder modifiziert Elemente, die einer Bedingung entsprechen. find gibt die Indizes von Nonzero/True-Elementen zurück und liefert mit zwei Ausgaben Zeile und Spalte separat.
A = magic(4); % 4x4 magic square
% single element (1-indexed!)
A(2, 3) % row 2, col 3
% entire row or column
A(1, :) % first row (all columns)
A(:, 2) % second column (all rows)
% submatrix
A(1:2, 2:4) % rows 1-2, cols 2-4
% linear indexing (column-major)
A(5) % 5th element counting down columns
% end keyword
A(end, :) % last row
A(:, end-1) % second-to-last column
% logical indexing
A(A > 10) % all elements > 10 (as vector)
A(A > 10) = 0; % set large elements to 0
% find indices
[r, c] = find(A == 16) % row and col of value 16Matrix-Arithmetik
Der Punkt vor einem Operator (.*) macht ihn elementweise statt matrixweise – dies ist die häufigste Fehlerquelle für Anfänger. A*B ist Matrixmultiplikation; A.*B multipliziert entsprechende Elemente. Der Backslash-Operator (\) löst lineare Systeme effizient und genau (LU-Zerlegung) – immer x = A\b gegenüber inv(A)*b bevorzugen. Der Apostroph (') transponiert; für komplexe Matrizen .' für nicht-konjugierte Transposition verwenden.
A = [1 2; 3 4];
B = [5 6; 7 8];
% matrix operations
C = A + B; % addition
D = A - B; % subtraction
E = A * B; % matrix multiplication
F = A'; % transpose
G = A^2; % matrix power (A * A)
% element-wise operations (use the dot!)
H = A .* B; % element-wise multiply
I = A ./ B; % element-wise divide
J = A .^ 2; % element-wise power
K = 2 * A; % scalar multiply
% matrix functions
det(A) % determinant
inv(A) % inverse
pinv(A) % pseudo-inverse
rank(A) % rank
trace(A) % trace (sum of diagonal)
% solving linear systems Ax = b
b = [5; 11];
x = A \ b; % left division: solves A*x = b
x = inv(A) * b; % equivalent but slowerMatrix-Manipulation
Konkatenation mit [A B] (Leerzeichen) fügt horizontal zusammen; [A; B] (Semikolons) fügt vertikal zusammen – spiegelt die Zeilen-Erstellungssyntax wider. reshape füllt spaltenmajor (erst unten dann quer). flipud/fliplr/rot90 reorientieren Matrizen. repmat kachelt eine Matrix in einem Rastermuster. Setzen einer Zeile oder Spalte auf [] löscht sie. size gibt Dimensionen zurück, length die größte Dimension, numel die Gesamtanzahl der Elemente.
A = [1 2; 3 4];
B = [5 6; 7 8];
% concatenation
C = [A B]; % horizontal: [1 2 5 6; 3 4 7 8]
D = [A; B]; % vertical: 4x4
% reshape
E = reshape(1:12, 3, 4); % 3x4 matrix from 1..12
% flip and rotate
F = flipud(A); % flip up-down
G = fliplr(A); % flip left-right
H = rot90(A); % rotate 90 degrees
% repmat (tile)
I = repmat([1 2], 2, 3); % repeat [1 2] in a 2x3 grid
% size and length
[m, n] = size(A); % m=2, n=2
len = length(A); % max dimension = 2
num = numel(A); % total elements = 4
% remove rows/cols
A(2, :) = []; % delete row 2
A(:, 1) = []; % delete column 1Elementweise Funktionen & Vektorisierung
MATLABs Stärke ist Vektorisierung – Operationen auf ganze Arrays gleichzeitig anzuwenden, was unter der Haube in optimiertem C/Fortran läuft. sin, exp, sqrt usw. arbeiten automatisch elementweise. sum/prod/max/min arbeiten standardmäßig spaltenweise (Dimension 1); Dimension 2 für zeilenweise übergeben. A(:) flacht eine Matrix zu einem Vektor ab. Vektorisierte Operationen immer gegenüber for-Schleifen für Performance bevorzugen – sie können 10-100x schneller sein.
% math functions operate element-wise
x = 0:0.1:2*pi;
y = sin(x); % sine of each element
z = exp(x); % exponential
w = sqrt(x); % square root
% rounding
round(3.7) % 4
floor(3.7) % 3
ceil(3.2) % 4
fix(-3.7) % -3 (toward zero)
% sums and products along dimensions
A = magic(3);
sum(A) % sum of each column (row vector)
sum(A, 2) % sum of each row (column vector)
sum(A(:)) % sum of ALL elements
prod(A) % product of each column
cumsum(A) % cumulative sum
% min, max, sort
[v, i] = max(A(:)) % max value and its index
sort(A, 'descend') % sort each column descending
% AVOID loops — vectorize!
% BAD: for i=1:1000, y(i)=sin(i); end
% GOOD:
i = 1:1000;
y = sin(i); % fast, vectorizedKontrollfluss & Logik
If / Elseif / Else
MATLAB verwendet if/elseif/else/end (Hinweis: elseif ist ein Wort). Logische Operatoren: && (skalares AND), || (skalares OR), & (elementweises AND), | (elementweises OR), ~ (NOT, nicht !). Für String-Vergleich strcmp/strcmpi verwenden (case-insensitiv) – der ==-Operator funktioniert nur für Character-Arrays gleicher Länge. Blöcke immer mit 'end' abschließen.
score = 85;
if score >= 90
grade = 'A';
elseif score >= 80
grade = 'B';
elseif score >= 70
grade = 'C';
else
grade = 'F';
end
disp(grade); % B
% logical operators: && (and), || (or), ~ (not)
if x > 0 && x < 10
disp('in range');
end
% compare strings with strcmp
if strcmp(name, 'Alice')
disp('hi Alice');
endFor- & While-Schleifen
for iteriert über jede Spalte des gegebenen Ausdrucks (bei Vektoren jedes Element). while läuft, solange die Bedingung wahr ist. IMMER Arrays vor Schleifen vorinitialisieren (result = zeros(1,N)) – das Wachsen eines Arrays in einer Schleife erzwingt jede Iteration Reallokation und ist extrem langsam. Der Doppelpunkt-Operator 1:5 erstellt [1 2 3 4 5]. fprintf gibt formatierten Output aus (wie C's printf).
% for loop over a range
for i = 1:5
fprintf('i = %d\n', i);
end
% iterate over a vector
v = [10 20 30];
for val = v
disp(val);
end
% nested loop over a matrix
A = zeros(3, 3);
for r = 1:3
for c = 1:3
A(r, c) = r * c;
end
end
% while loop
n = 10;
while n > 1
n = n / 2;
fprintf('%.2f\n', n);
end
% preallocate for speed (IMPORTANT!)
result = zeros(1, 1000);
for i = 1:1000
result(i) = i^2;
endSwitch & Break/Continue
switch gleicht einen Wert gegen case-Labels ab – kein break nötig (anders als C/Java). case kann ein Cell-Array für mehrere Werte annehmen. otherwise ist der Standardfall. break verlässt die innerste Schleife; continue springt zur nächsten Iteration. try/catch behandelt Fehler elegant; ME ist ein MException-Objekt mit .message und .identifier. MATLAB hat keinen ternären Operator – if/else oder Inline-Funktionen verwenden.
% switch statement
method = 'linear';
switch method
case 'linear'
disp('using linear');
case 'cubic'
disp('using cubic');
case {'nearest', 'spline'}
disp('using nearest or spline');
otherwise
disp('unknown method');
end
% break and continue
for i = 1:10
if i == 5
break % exit the loop entirely
end
if mod(i, 2) == 0
continue % skip to next iteration
end
disp(i); % prints 1 3
end
% try-catch for error handling
try
x = 1 / 0; % may error
catch ME
fprintf('Error: %s\n', ME.message);
endLogische Operationen & Indizierung
Logische Indizierung ist MATLABs Killer-Feature – A(condition) selektiert Elemente, bei denen das logische Array true ist. ~= ist 'nicht gleich' (nicht !=). & und | sind elementweise; && und || sind Short-Circuit (nur skalar, in if-Bedingungen bevorzugt). find gibt lineare Indizes von True-Werten zurück. any/all testen, ob alle Elemente true sind, optional entlang einer Dimension. Die is*-Familie testet Typen und spezielle Werte (NaN, Inf).
A = [1 2 3 4 5 6 7 8 9 10];
% comparison operators
A > 5 % logical array
A == 5
A ~= 5 % not equal (NOT !=)
A >= 3 & A <= 7 % element-wise AND
A < 3 | A > 7 % element-wise OR
% logical indexing (powerful!)
A(A > 5) % [6 7 8 9 10]
A(A > 5) = 0; % set elements > 5 to 0
A(mod(A, 2) == 0) % even numbers
% find indices
idx = find(A > 5); % indices of elements > 5
[r, c] = find(A > 5); % row and col (for matrices)
% any and all
any(A > 5) % true if ANY element > 5
all(A > 0) % true if ALL elements > 0
any(A > 5, 2) % per row
% is functions
isnan(x); isinf(x); isfinite(x);
isnumeric(x); ischar(x); iscell(x);Strings & Formatierung
MATLAB hat zwei String-Typen: Char-Arrays ('text', Legacy) und String-Skalare ("text", R2017+). String-Skalare sind flexibler für Manipulation. sprintf gibt einen formatierten String zurück; fprintf gibt auf Konsole oder Datei aus. Häufige Format-Spezifizierer: %s (String), %d (Integer), %f (Float), %.2f (2 Dezimalen), %e (wissenschaftlich). strsplit/strjoin behandeln delimite Listen. num2str/mat2str konvertieren Zahlen zu Strings.
% string creation
s1 = 'Hello'; % char array
s2 = "World"; % string scalar (R2017+)
% concatenation
greeting = [s1 ', ' s2 '!']; % char array concat
full = s1 + " " + s2; % string concat
% formatting
name = 'Alice';
age = 30;
fprintf('Name: %s, Age: %d\n', name, age);
str = sprintf('Pi is %.2f', pi); % returns string
% common string functions
upper('hello') % HELLO
lower('WORLD') % world
strlength("hello") % 5 (string)
length('hello') % 5 (char array)
strcmp('a', 'a') % true
strfind('hello', 'll') % 3 (index)
strrep('cat', 'c', 'b') % bat
strsplit('a,b,c', ',') % {'a','b','c'}
strjoin({'a','b'}, '-') % a-b
num2str(42) % '42'Funktionen & Skripte
Funktionsdefinition
Funktionen müssen in einer Datei mit demselben Namen stehen (add.m für Funktion add) oder am Ende einer Skriptdatei. Die erste Zeile ist die Funktionsdeklaration. Funktionen haben ihren eigenen Workspace (separat vom Base-Workspace). nargin/nargout ermöglichen optionale Argumente – nargin zählt tatsächliche Eingaben. Mehrere Ausgaben werden mit [a, b] = func() erfasst. Bei Aufruf mit weniger Ausgaben werden zusätzliche verworfen.
% function in a file named 'add.m'
function result = add(a, b)
% ADD returns the sum of a and b
result = a + b;
end
% with multiple inputs and outputs
function [mn, mx, avg] = stats(v)
mn = min(v);
mx = max(v);
avg = mean(v);
end
% calling functions
s = add(3, 4); % 7
[lo, hi, mu] = stats([1 2 3 4 5]);
% capture only first output
minimum = stats([1 2 3]); % gets mn only
% nargin and nargout (number of args)
function y = power(x, n)
if nargin < 2
n = 2; % default value
end
y = x .^ n;
endAnonyme & Inline-Funktionen
Anonyme Funktionen (@(args) expr) sind schnelle einzeilige Funktionen, die inline definiert werden – perfekt zum Übergeben an Solver (fzero, integral, ode45) ohne Dateien zu erstellen. Sie erfassen Workspace-Variablen zur Erstellungszeit. Function-Handles (@sin) ermöglichen das Übergeben von eingebauten oder Benutzerfunktionen als Argumente. Dies ist unerlässlich für numerisches Rechnen: integral(@(x) f(x), a, b) integriert jede Funktion, die man definiert.
% anonymous function (one-liner, no file needed)
square = @(x) x .^ 2;
square(5) % 25
square([1 2 3]) % [1 4 9]
% with multiple inputs
add = @(a, b) a + b;
add(3, 4) % 7
% capture variables from workspace
c = 10;
addc = @(x) x + c;
addc(5) % 15
% function handle to built-in
f = @sin;
f(pi/2) % 1
% pass functions as arguments
result = integral(@(x) x.^2, 0, 1); % integrate x^2 from 0 to 1
result = fzero(@(x) x^2 - 2, 1); % find root near 1
% array of function handles
funs = {@sin, @cos, @tan};
funs{1}(0) % 0Skripte & Live Scripts
Skripte sind Befehlssequenzen, die im Base-Workspace laufen (anders als Funktionen, die isolierte Workspaces haben). Der %%-Marker erstellt 'Zellen' (Abschnitte), die man unabhängig mit Ctrl+Enter ausführen kann – großartig für inkrementelle Entwicklung. Live Scripts (.mlx) sind wie Jupyter-Notebooks: Sie kombinieren Code, formatierten Text, Gleichungen und Inline-Plots in einem interaktiven Dokument. Für wiederverwendbaren Code Funktionen gegenüber Skripten bevorzugen.
% A script is just a sequence of commands in a .m file
% It shares the base workspace
% script: analyze_data.m
data = load('data.mat');
cleaned = data.values(data.values > 0);
mean_val = mean(cleaned);
fprintf('Mean: %.2f\n', mean_val);
plot(cleaned);
title('Cleaned Data');
% sections (cells) with %%
%% Initialize
x = linspace(0, 2*pi, 100);
%% Plot
plot(x, sin(x));
%% Analyze
disp(mean(sin(x)));
% Run a section: Ctrl+Enter (in editor)
% Live Scripts (.mlx): rich text, inline plots, equationsVerschachtelte & lokale Funktionen
Skripte können lokale Funktionen am Ende der Datei enthalten (seit R2016b) – sie sind nur innerhalb dieser Datei sichtbar. Verschachtelte Funktionen (innerhalb einer anderen Funktion definiert) teilen den Workspace des Parents und können dessen Variablen lesen und modifizieren – nützlich für Callbacks und Akkumulatoren, können aber Code schwerer verständlich machen. Lokale Funktionen in Funktionsdateien sind Helfer, die nur innerhalb dieser Datei sichtbar sind. Lokale Funktionen verwenden, um Skripte zu organisieren, ohne viele Dateien zu erstellen.
% local functions in a script (must be at the end)
% main_script.m
x = 1:10;
y = process(x);
disp(y);
function r = process(v)
r = normalize(scale(v)); % calls another local function
end
function s = scale(v)
s = v * 10;
end
function n = normalize(v)
n = v / max(v);
end
% nested function (inside another function)
function outer(x)
y = 0;
function inner()
y = y + x; % can access outer's variables
end
inner();
disp(y);
endVariablen-Scope & Global
MATLAB übergibt Argumente per Value (Copy-on-Modify), sodass Funktionen Aufrufer-Variablen nicht versehentlich ändern können – anders als C/Python. global für wirklich geteilten Zustand verwenden (in jeder Funktion deklarieren, die ihn nutzt), aber Argumentübergabe bevorzugen. persistente Variablen behalten ihren Wert zwischen Funktionsaufrufen (wie static in C) – nützlich für Zähler, Caches oder Memoisierung. Persistente Variablen mit isempty-Prüfung beim ersten Aufruf initialisieren. Globals zugunsten von Funktionsrückgaben oder verschachtelten Funktionen vermeiden.
% base workspace variables
x = 10;
% functions have their OWN workspace
function y = myfunc()
% x is NOT accessible here
y = 5;
end
% pass by value (modifications don't affect caller)
function y = modify(v)
v = v * 2; % local copy
y = v;
end
a = 5;
b = modify(a); % b=10, a still 5
% global variables (use sparingly!)
global COUNTER
COUNTER = 0;
function increment()
global COUNTER
COUNTER = COUNTER + 1;
end
% persistent variables (like static in C)
function counter()
persistent count
if isempty(count)
count = 0;
end
count = count + 1;
disp(count);
endDatenstrukturen
Cell-Arrays
Cell-Arrays sind MATLABs Container für gemischte Datentypen (wie Python-Listen). Geschweifte Klammern {} verwenden, um auf den INHALT einer Cell zuzugreifen, und runde Klammern (), um eine Cell zu erhalten (nützlich für Slicing). Diese Unterscheidung ist entscheidend: c{1} gibt den String; c(1) gibt eine Cell, die den String enthält. Cells sind unerlässlich für Strings unterschiedlicher Länge, variabel große Matrizen und gezackte Daten. num2cell/mat2cell konvertieren zwischen numerischen Arrays und Cells.
% cell arrays hold mixed data types
c = {'Alice', 30, [1 2 3], magic(2)};
% access with {} (content) vs () (cell)
c{1} % 'Alice' (the string itself)
c(1) % {'Alice'} (a 1x1 cell)
c{3}(2) % 2 (second element of third cell)
% modify and append
c{2} = 31;
c{end+1} = 'new'; % append
c{5} = 'skip'; % auto-fills gaps with []
% multi-dimensional cell array
c2 = {'a', 'b'; 'c', 'd'}; % 2x2 cell
% iterate over cells
for i = 1:numel(c)
disp(c{i});
end
% convert: cell2mat, mat2cell, num2cell
nums = num2cell(1:5); % {1, 2, 3, 4, 5}Structs & Tables
Structs gruppieren verwandte Daten mit benannten Feldern – wie Objekte ohne Methoden. Tables (R2013+) sind MATLABs Äquivalent von Dataframes: spaltenorientiert, mit benannten Variablen und Zeilennamen. Tables sind ideal für CSV/Excel-Daten. Auf Spalten nach Namen zugreifen (T.ages) oder per Index. Logische Indizierung funktioniert auf Zeilen: T(T.age > 25, :) filtert Zeilen. summary() gibt Statistiken für jede Spalte. Tables integrieren mit readtable/writetable für Daten-I/O.
% struct: named fields with any data
user.name = 'Alice';
user.age = 30;
user.scores = [90 85 88];
disp(user.name); % Alice
% struct constructor
s = struct('name', 'Bob', 'age', 25, 'active', true);
% array of structs
users(1) = struct('name', 'Alice', 'age', 30);
users(2) = struct('name', 'Bob', 'age', 25);
disp(users(2).name); % Bob
% table (like a dataframe) — great for tabular data
names = {'Alice'; 'Bob'; 'Carol'};
ages = [30; 25; 28];
scores = [90; 85; 88];
T = table(names, ages, scores);
% access table columns
T.ages % column as array
T(:, 2) % column as table
T(1:2, :) % first 2 rows
T.age > 26 % logical indexing
T(T.age > 26, :) % rows where age > 26
% summary statistics
summary(T)String-Arrays & Char-Behandlung
Modernes MATLAB (R2017+) bevorzugt String-Arrays ("text") gegenüber Char-Arrays ('text'). String-Arrays unterstützen vektorisierte Operationen: strlength, +, split, join, contains, matches, replace arbeiten alle elementweise. Char-Arrays sind in älterem Code noch häufig und für einige Funktionen erforderlich. String-Arrays für Text-Sammlungen verwenden; sie behandeln verschiedene Längen natürlich (anders als Char-Arrays, die Padding oder Cells benötigen).
% string array (R2017+) — recommended for text
names = ["Alice", "Bob", "Carol"];
names(1) % "Alice"
names' % column string array
strlength(names) % [5 3 5]
% char array (legacy)
c = 'Hello World';
c(1:5) % 'Hello'
size(c) % [1 11]
% cell array of char vectors (legacy mixed-length)
old = {'Alice', 'Bob', 'Carol'};
% convert between types
s = string('hello'); % char -> string
c = char("hello"); % string -> char
cellarr = cellstr(names); % string array -> cell of char
% combine and split
full = "Alice" + " " + "Smith"; % "Alice Smith"
parts = split("a,b,c", ","); % ["a", "b", "c"]
joined = join(["a" "b" "c"], "-"); % "a-b-c"
% pattern matching
matches(names, 'A*') % logical: [true false false]
contains(names, 'li') % [true false false]
replace("hello", 'l', 'L') % "heLLo"Containers.Map & Sets
containers.Map ist MATLABs Key-Value-Wörterbuch (Hash Map) – nützlich für Lookup-Tabellen und Konfiguration. Schlüssel können Strings oder Zahlen sein. isKey prüft Existenz; keys/values rufen alle ab. Set-Operationen (union, intersect, setdiff, setxor, ismember) arbeiten auf numerischen Arrays und Cell-Arrays von Strings. ismember testet Mitgliedschaft und gibt ein logisches Array zurück – großartig zum Filtern. Diese ergänzen logische Indizierung für Datenmanipulation.
% map (dictionary / hash table)
m = containers.Map;
m('name') = 'Alice';
m('age') = 30;
m('scores') = [90 85];
% access
m('name') % 'Alice'
isKey(m, 'name') % true
keys(m) % {'age', 'name', 'scores'}
values(m) % {30, 'Alice', [90 85]}
remove(m, 'age');
% create with initial values
m2 = containers.Map({'a','b','c'}, {1, 2, 3});
% set operations
A = [1 2 3 4 5];
B = [4 5 6 7 8];
union(A, B) % [1 2 3 4 5 6 7 8]
intersect(A, B) % [4 5]
setdiff(A, B) % [1 2 3]
setxor(A, B) % [1 2 3 6 7 8]
ismember(3, A) % true
ismember([1 6], A) % [true false]Categorical & Datetime
Categorical-Arrays speichern Textdaten effizient (als Integers mit einer Label-Map) und unterstützen Sortierung – ideal für Umfrageantworten, Bewertungen oder jede feste Menge von Kategorien. datetime/duration (R2014+) ersetzen die Legacy-Funktionen datenum/datestr durch ein modernes, zeitzonenbewusstes Datumssystem. Datumsarithmetik ist intuitiv: days(), hours(), minutes() hinzufügen. Diese Typen integrieren mit Tables und Plotting für Zeitreihenanalyse.
% categorical data (efficient for repeated strings)
colors = categorical({'red', 'blue', 'red', 'green', 'blue'});
categories(colors) % list of categories
summary(colors) % count per category
ord = categorical({'low','med','high'}, ...
{'low','med','high'}, 'Ordinal', true);
ord(1) < ord(2) % true (ordered)
% datetime
t = datetime('now') % current date and time
t = datetime(2024, 1, 15)
t.Format = 'yyyy-MM-dd HH:mm:ss';
% duration
d = duration(2, 30, 0); % 2 hours 30 min
d = hours(2) + minutes(30);
% date arithmetic
t2 = t + days(7); % add a week
t2 - t % duration of 7 days
% date strings and numbers
s = datestr(t, 'yyyy-mm-dd'); % to string (legacy)
n = datenum(t); % to serial number
t = datetime(n, 'ConvertFrom', 'datenum');
% generate date range
dates = datetime(2024,1,1) + days(0:6); % one weekPlotting & Visualisierung
Grundlegende 2D-Plots
plot() ist die zentrale 2D-Plotting-Funktion. Das dritte Argument spezifiziert Farbe und Stil ('b-' = blau durchgezogen). hold on ermöglicht das Überlagern mehrerer Plots; hold off hebt auf. Achsen immer beschriften und eine Legende hinzufügen. axis([xmin xmax ymin ymax]) setzt Grenzen. saveas/print exportieren Figuren – print mit -r300 ergibt 300 DPI. gcf gibt das aktuelle Figure-Handle. Die 'Location','best'-Option platziert die Legende automatisch.
x = linspace(0, 2*pi, 100);
% line plot
plot(x, sin(x), 'b-', 'LineWidth', 2);
hold on;
plot(x, cos(x), 'r--', 'LineWidth', 2);
hold off;
% labels and legend
xlabel('x (radians)');
ylabel('amplitude');
title('Sine and Cosine');
legend('sin(x)', 'cos(x)', 'Location', 'best');
grid on;
% line styles: b- blue solid, r-- red dashed
% g: green dotted, m-. magenta dash-dot
% markers: o circle, * star, s square, + plus
% axis control
axis([0 2*pi -1.5 1.5]); % [xmin xmax ymin ymax]
xlim([0 2*pi]);
ylim([-1.5 1.5]);
% save figure
saveas(gcf, 'plot.png');
print('-dpng', '-r300', 'plot.png');Mehrere Plots & Subplots
subplot(r, c, n) teilt die Figur in ein r-mal-c-Raster und selektiert die n-te Zelle für Plotting. tiledlayout (R2019+) ist der moderne Ersatz – saubererer Abstand und ein gemeinsamer Titel. nexttile springt zum nächsten Subplot. yyaxis erstellt Plots mit zwei y-Achsen (links und rechts) für Daten mit unterschiedlichen Skalen. Immer zuerst figure aufrufen, um ein neues Fenster zu öffnen, sonst überschreibt man den aktuellen Plot.
% subplot(rows, cols, index)
figure;
subplot(2, 2, 1);
plot(x, sin(x));
title('Sine');
subplot(2, 2, 2);
plot(x, cos(x));
title('Cosine');
subplot(2, 2, 3);
plot(x, tan(x));
title('Tangent');
ylim([-5 5]);
subplot(2, 2, 4);
plot(x, exp(-x));
title('Decay');
% tiledlayout (newer, cleaner)
figure;
t = tiledlayout(2, 2);
nexttile; plot(x, sin(x)); title('Sine');
nexttile; plot(x, cos(x)); title('Cosine');
nexttile; plot(x, tan(x)); title('Tangent');
nexttile; plot(x, exp(-x)); title('Decay');
title(t, 'Trig Functions'); % overall title
% multiple y-axes
yyaxis left; plot(x, sin(x));
yyaxis right; plot(x, 100*cos(x));Spezialisierte Plots
MATLAB hat Dutzende spezialisierter Plots: bar/barh (Balkendiagramme), histogram (ersetzt hist), scatter (mit optionaler Farb/Größen-Mapping), pie, area, stem, stairs, compass, feather. scatter(x, y, size, color, 'filled') ist besonders mächtig – das 4. Argument färbt Punkte nach einem Wert und offenbart eine dritte Dimension. histogram mit 'Normalization','pdf' normalisiert zu einer Wahrscheinlichkeitsdichte für Vergleich mit kontinuierlichen Verteilungen.
% bar chart
bar([1 2 3], [10 15 7]);
bar([1 2 3; 4 5 6], 'grouped'); % grouped bars
bar([1 2 3; 4 5 6], 'stacked'); % stacked bars
% histogram
data = randn(1000, 1);
histogram(data, 30); % 30 bins
histogram(data, 'Normalization', 'pdf');
% scatter plot
x = rand(100, 1);
y = 2*x + randn(100, 1)*0.1;
scatter(x, y, 50, 'filled');
% colored scatter
scatter(x, y, 50, y, 'filled'); % color by y value
colorbar;
% pie chart
pie([30 20 50], {'A', 'B', 'C'});
% area plot
area(1:5, [1 3 2 4 5]);
% stem (discrete)
stem(0:5, [1 4 9 16 25 36]);
% boxplot (requires Statistics toolbox)
boxplot(randn(100, 3));3D-Plots & Oberflächen
plot3 zeichnet 3D-parametrische Linien. Für Oberflächen zuerst ein Raster mit meshgrid erstellen, dann Z = f(X, Y) berechnen. surf zeichnet eine gefüllte Oberfläche; mesh zeichnet ein Wireframe; contour zeichnet 2D-Höhenkurven. colormap (jet, parula, hot, cool) steuert die Farbabbildung; colorbar fügt eine Legende hinzu. shading interp entfernt Gitterlinien für glatte Verläufe. view(az, el) setzt den Kamerawinkel. 'EdgeColor','none' verbirgt Mesh-Linien für ein sauberes Aussehen.
% 3D line plot
t = 0:0.1:10*pi;
plot3(sin(t), cos(t), t);
xlabel('x'); ylabel('y'); zlabel('z');
% meshgrid for surface plots
[X, Y] = meshgrid(-2:0.1:2);
Z = X .* exp(-X.^2 - Y.^2);
% surface plots
figure;
subplot(1, 3, 1);
surf(X, Y, Z); % surface
title('surf');
subplot(1, 3, 2);
mesh(X, Y, Z); % wireframe
title('mesh');
subplot(1, 3, 3);
contour(X, Y, Z, 20); % contour lines
title('contour');
% colored surface with colorbar
figure;
surf(X, Y, Z, 'EdgeColor', 'none');
colorbar;
colormap jet;
shading interp; % smooth colors
% view angle
view(45, 30); % azimuth, elevation
axis equal;Plot-Anpassung & Export
Fast jeder visuelle Aspekt ist über Name-Value-Paare oder set() anpassbar. Farben sind RGB-Tripel [r g b] von 0-1. set(gca, ...) modifiziert die aktuellen Achsen (Schrift, Skala, Grenzen). MATLAB unterstützt LaTeX in Titeln/Labels mit 'Interpreter','latex'. exportgraphics (R2020+) ist die moderne Export-Funktion mit Vektor- und High-DPI-Optionen. Figure-Handles (f1, f2) verwenden, um mehrere Fenster zu verwalten. annotation() fügt Pfeile, Textboxen und Formen hinzu.
% customize line appearance
plot(x, y, ...
'Color', [0.2 0.6 0.8], ... % RGB 0-1
'LineWidth', 2, ...
'Marker', 'o', ...
'MarkerSize', 8, ...
'MarkerFaceColor', 'r');
% annotations
text(1, 0.5, 'important point');
annotation('arrow', [0.3 0.5], [0.3 0.5]);
% figure and axes properties
set(gcf, 'Position', [100 100 800 600]);
set(gca, 'FontSize', 14, 'FontName', 'Arial');
set(gca, 'XScale', 'log'); % log scale
% latex in labels
title('Function: \\alpha + \\beta^2', 'Interpreter', 'latex');
% export high quality
exportgraphics(gcf, 'plot.pdf', 'ContentType', 'vector');
exportgraphics(gcf, 'plot.png', 'Resolution', 300);
% legend customization
legend('show', 'Location', 'northwest', ...
'FontSize', 12, 'Box', 'off');
% multiple figures
f1 = figure; plot(x, sin(x));
f2 = figure; plot(x, cos(x));
figure(f1); % switch back to f1Datenanalyse & Statistik
Deskriptive Statistik
MATLAB bietet umfassende Statistikfunktionen. mean/median/mode für zentrale Tendenz; std/var/range/iqr für Streuung. Standardmäßig arbeiten diese entlang der ersten Dimension (Spalten). 'omitnan' verwenden, um NaN-Werte zu überspringen (wichtig für echte Daten). quantile/prctile geben Perzentile. Die Statistics and Machine Learning Toolbox ergänzt geomean, harmmean, zscore und Verteilungsfunktionen. Vor der Analyse immer auf NaNs prüfen – sie propagieren durch die meisten Operationen.
data = [1 2 3 4 5 6 7 8 9 10];
% central tendency
mean(data) % 5.5
median(data) % 5.5
mode(data) % 1 (first mode)
geomean(data) % geometric mean (Stats toolbox)
harmmean(data) % harmonic mean
% dispersion
std(data) % standard deviation
var(data) % variance
range(data) % max - min
iqr(data) % interquartile range
mad(data) % mean absolute deviation
% extremes and quantiles
min(data); max(data);
quantile(data, 0.25) % 25th percentile
prctile(data, 95) % 95th percentile
% along dimensions
A = randn(100, 3);
mean(A) % mean of each column
mean(A, 2) % mean of each row
mean(A, 'all') % overall mean
% ignoring NaNs
data(5) = NaN;
mean(data, 'omitnan') % skip NaN values
nanmean(data) % legacy equivalentKurvenanpassung & Regression
polyfit passt ein Polynom gegebenen Grades an; polyval wertet es aus. Für lineare Regression gibt regress() Koeffizienten plus Statistiken (R², F-Statistik, p-Wert). corrcoef gibt die volle Korrelationsmatrix zurück. Die Curve Fitting Toolbox bietet fit() für interaktive und programmatische Anpassung mit benutzerdefinierten Modellen. lsqcurvefit (Optimization Toolbox) passt beliebige nichtlineare Modelle an. Immer den Fit gegen Daten plotten, um die Qualität zu prüfen – hochgradige Polynome können überanpassen.
% polynomial fit
x = 0:0.5:10;
y = 2*x + 1 + randn(size(x))*2; % noisy linear data
% linear least squares (degree 1)
p = polyfit(x, y, 1); % [slope, intercept]
yfit = polyval(p, x);
plot(x, y, 'o', x, yfit, '-');
% higher-order polynomial
p3 = polyfit(x, y, 3);
yfit3 = polyval(p3, x);
% fit with fittype (Curve Fitting Toolbox)
f = fit(x', y', 'poly2'); % quadratic
plot(f, x, y);
% custom model fit
% fit y = a*exp(b*x) using lsqcurvefit
model = @(p, x) p(1)*exp(p(2)*x);
params = lsqcurvefit(model, [1 0.1], x, y);
% correlation
r = corrcoef(x, y); % correlation matrix
r = corr(x, y); % correlation coefficient
% linear regression with stats
X = [ones(size(x)) x']; % design matrix
[b, bint, r, rint, stats] = regress(y', X);
% stats = [R^2, F, p, error_var]Interpolation & Resampling
interp1 interpoliert 1D-Daten – 'linear' ist schnell, 'spline' ist glatt (kann überschwingen), 'pchip' erhält die Form (kein Überschwingen). interp2 macht dasselbe für 2D-Raster. Für wiederholte Abfragen ist griddedInterpolant effizienter (einmal bauen, oft abfragen). resample ändert die Abtastrate eines Signals (erfordert Signal Processing Toolbox). Methode immer basierend auf Daten wählen: spline für glatte Funktionen, pchip für monotone Daten, nearest für kategorische.
% 1D interpolation
x = 0:5;
y = [0 1 4 9 16 25];
xi = 0:0.5:5;
yi = interp1(x, y, xi, 'linear'); % linear (default)
yi = interp1(x, y, xi, 'spline'); % cubic spline
yi = interp1(x, y, xi, 'pchip'); % shape-preserving
yi = interp1(x, y, xi, 'nearest'); % nearest neighbor
% extrapolation
yi = interp1(x, y, xi, 'linear', 'extrap');
% 2D interpolation
[X, Y] = meshgrid(0:2:10);
Z = X.^2 + Y.^2;
[Xi, Yi] = meshgrid(0:0.5:10);
Zi = interp2(X, Y, Z, Xi, Yi, 'spline');
% resample signal to new rate
y_resampled = resample(y, 3, 2); % 3/2 times the rate
% griddedInterpolant (efficient for repeated queries)
F = griddedInterpolant(x, y, 'spline');
y1 = F(2.5);
y2 = F([1.5 3.5 4.5]);FFT & Signalverarbeitung
fft berechnet die Fast Fourier Transform – die Grundlage der Frequenzanalyse. Die Ausgabe ist komplex; abs() für die Magnitude nehmen. Zur einseitigen Spektrum konvertieren, indem die erste Hälfte genommen und verdoppelt wird (außer DC und Nyquist). Frequenzen reichen von 0 bis fs/2 (Nyquist). ifft invertiert zurück in den Zeitbereich. Filtern im Frequenzbereich (Nullen unerwünschter Frequenzen) ist einfach, kann aber Ringing verursachen; designfilt für richtige Filter verwenden. spectrogram zeigt Frequenzinhalt über die Zeit.
% generate a signal with two frequencies
fs = 1000; % sampling rate (Hz)
t = 0:1/fs:1-1/fs; % 1 second of time
x = 2*sin(2*pi*50*t) + 1*sin(2*pi*120*t);
% compute FFT
N = length(x);
Y = fft(x);
P2 = abs(Y/N); % two-sided spectrum
P1 = P2(1:N/2+1); % one-sided spectrum
P1(2:end-1) = 2*P1(2:end-1);
f = fs*(0:(N/2))/N;
% plot
plot(f, P1);
xlabel('Frequency (Hz)');
ylabel('Amplitude');
title('Single-Sided Spectrum');
% filtering (simple low-pass)
cutoff = 100; % Hz
Y_filt = Y;
Y_filt(f > cutoff) = 0; % zero out high freqs (simplified)
x_filtered = real(ifft(Y_filt));
% spectrogram
spectrogram(x, 128, 120, 128, fs, 'yaxis');Optimierung & Nullstellenfindung
fzero findet Nullstellen von 1D-Funktionen (benötigt ein Intervall oder einen Schätzwert). fminbnd minimiert eine 1D-Funktion auf einem beschränkten Intervall; fminsearch verwendet Nelder-Mead für multivariate unbeschränkte Optimierung. fmincon (Optimization Toolbox) behandelt Constraints. linprog löst lineare Programme. Immer einen guten Startwert (x0) für iterative Solver angeben. Das exitflag-Ausgabe prüfen, um Konvergenz zu bestätigen. Für globale Optimierung GlobalSearch oder MultiStart verwenden.
% find root of f(x) = 0
f = @(x) x^2 - 2;
x_root = fzero(f, 1); % ~1.4142 (sqrt(2))
x_root = fsolve(f, 1); % alternative
% minimize a function
fun = @(x) (x-3)^2 + 1;
[x_min, f_min] = fminbnd(fun, 0, 5); % bounded 1D
% x_min = 3, f_min = 1
% multivariate minimization
fun2 = @(x) x(1)^2 + x(2)^2; % sphere function
x0 = [1, 1];
[x_opt, f_opt] = fminsearch(fun2, x0);
% x_opt ≈ [0, 0]
% constrained optimization (Optimization Toolbox)
% minimize fun subject to A*x <= b
A = []; b = []; Aeq = []; beq = [];
lb = [0 0]; ub = [];
[x, fval] = fmincon(fun2, x0, A, b, Aeq, beq, lb, ub);
% linear programming
% minimize f'*x subject to A*x <= b
f = [-1; -1]; % maximize x+y
A = [1 1; -1 0; 0 -1];
b = [2; 0; 0];
[x, fval] = linprog(f, A, b);Datei-I/O & Datenimport
MAT-Dateien & Save/Load
.mat ist MATLABs natives Binärformat – schnell, kompakt und erhält alle Variablentypen. save/load sind die primären Befehle. -v7.3 für Dateien über 2GB verwenden (HDF5-basiert). -ascii exportiert zu menschenlesbarem Text (verliert Typinformation). Laden in ein Struct (s = load(...)) vermeidet das Verschmutzen des Workpaces. clear entfernt Variablen; clearvars -except behält angegebene. In langen Berechnungen immer Zwischenergebnisse speichern, um Fortsetzen zu ermöglichen.
% save variables to a .mat file
x = 1:10;
y = sin(x);
save('data.mat'); % save ALL variables
save('data.mat', 'x', 'y'); % save specific variables
save('data.mat', '-append'); % add more variables
% load variables
load('data.mat'); % load all into workspace
loaded = load('data.mat'); % load into a struct
loaded.x % access via struct
% save with compression
save('data.mat', 'x', 'y', '-v7.3'); % large files (>2GB)
save('data.mat', '-v7'); % compressed (default)
% save specific format
save('data.txt', 'x', '-ascii'); % plain text
save('data.csv', 'x', '-ascii', '-double');
% clear variables
clear x y; % remove specific
clear all; % remove everything
clearvars -except x; % keep only xText- & CSV-Dateien lesen
readtable ist der moderne Weg, CSV/Excel zu lesen – es gibt eine Table mit benannten Spalten zurück und behandelt Header automatisch. readmatrix liest numerische Daten in eine Matrix. Für volle Kontrolle fopen/fgetl/fprintf/fclose verwenden (immer Dateien schließen!). fscanf liest formatierte Daten wie C. Immer fid auf Fehler prüfen: wenn fid == -1, konnte die Datei nicht geöffnet werden. readcell behandelt gemischte Daten, die nicht in eine Matrix oder Table passen.
% readtable (recommended for tabular data)
T = readtable('data.csv');
T = readtable('data.xlsx', 'Sheet', 'Sheet1');
T = readtable('data.csv', 'Delimiter', ',');
% access columns by name
T.Var1; T.age;
% readmatrix (numeric data)
M = readmatrix('numbers.csv');
M = readmatrix('data.txt', 'Delimiter', '\t');
% readcell (mixed data)
C = readcell('mixed.csv');
% low-level file I/O
fid = fopen('data.txt', 'r');
while ~feof(fid)
line = fgetl(fid);
disp(line);
end
fclose(fid);
% read formatted data
fid = fopen('data.txt', 'r');
data = fscanf(fid, '%f %f', [2, inf]);
fclose(fid);
% write text
fid = fopen('output.txt', 'w');
fprintf(fid, 'Result: %.2f\n', 3.14159);
fclose(fid);Excel & Spreadsheet-I/O
readtable/writetable sind die empfohlenen Funktionen für Excel-I/O. Sie behandeln Header, Typen und Sheets automatisch. detectImportOptions ermöglicht Anpassung, wie Spalten geparst werden (z.B. eine Spalte zu int32 oder String erzwingen). 'Range' verwenden, um spezifische Zellen zu lesen/schreiben. 'WriteMode','append' fügt Zeilen zu einem bestehenden Sheet hinzu. Für große Excel-Dateien CSV (schneller) oder .mat (nativ) in Betracht ziehen. Die Spreadsheet Link-Toolbox verbindet MATLAB direkt mit Excel.
% read Excel files
T = readtable('data.xlsx');
T = readtable('data.xlsx', 'Sheet', 'Sales', 'Range', 'A1:D100');
% numeric data only
M = readmatrix('data.xlsx', 'Sheet', 1);
% write to Excel
writetable(T, 'output.xlsx');
writetable(T, 'output.xlsx', 'Sheet', 'Results');
% write matrix
writematrix(M, 'output.xlsx', 'Sheet', 1);
% cell array (mixed types)
C = {'Name','Age'; 'Alice',30; 'Bob',25};
writecell(C, 'people.xlsx');
% append to existing sheet
writetable(T, 'data.xlsx', 'Sheet', 1, 'WriteMode', 'append');
% read specific range
T = readtable('data.xlsx', 'Range', 'B2:D10');
% detect import options (customize parsing)
opts = detectImportOptions('data.csv');
opts = setvartype(opts, 'age', 'int32');
T = readtable('data.csv', opts);Arbeiten mit Pfaden & Verzeichnissen
dir() gibt ein Struct-Array mit .name, .date, .bytes, .isdir, .datenum für jede Datei zurück. fullfile fügt Pfade portabel zusammen (verwendet den richtigen Separator auf jedem OS). fileparts teilt einen Pfad in Verzeichnis, Name und Erweiterung. exist('name', 'file') prüft, ob eine Datei existiert. addpath fügt Verzeichnisse zu MATLABs Suchpfad hinzu, sodass Funktionen darin zugänglich sind; savepath persistiert dies. Diese sind unerlässlich für die Stapelverarbeitung von Dateien in Ordnern.
% current directory
pwd
cd('C:\\Users\\data')
% list files
files = dir(); % struct array of files
files = dir('*.mat'); % filter by pattern
files = dir('subdir/'); % list a subdirectory
% access file info
for i = 1:length(files)
if ~files(i).isdir
fprintf('%s - %d bytes\n', files(i).name, files(i).bytes);
end
end
% path operations
fullfile('data', '2024', 'file.csv') % data/2024/file.csv
[filepath, name, ext] = fileparts('C:\\data\\test.csv')
% filepath = 'C:\data', name = 'test', ext = '.csv'
% create and remove directories
mkdir('output');
rmdir('output', 's'); % remove recursively
% file existence
if exist('data.mat', 'file')
load('data.mat');
end
% add folder to path
addpath('C:\\myfunctions');
savepath(); % save for future sessionsBilder & Audio
imread/imshow/imwrite behandeln Bilder (JPEG, PNG, TIFF, BMP). Bilder werden als uint8-Matrizen (0-255) oder doubles (0-1) gespeichert. rgb2gray konvertiert Farbe zu Graustufen. Die Image Processing Toolbox ergänzt imresize, imrotate, imfilter, Kantenerkennung und morphologische Operationen. audioread/audiowrite/sound behandeln Audiodateien. Bilder und Audio sind nur Matrizen, sodass alle MATLAB-Mathe- und Plotting-Tools direkt anwendbar sind.
% read and display an image
img = imread('photo.jpg');
imshow(img);
[m, n, c] = size(img); % dimensions, c=3 for RGB
% write image
imwrite(img, 'output.png');
imwrite(img, 'output.jpg', 'Quality', 90);
% convert to grayscale
if size(img, 3) == 3
gray = rgb2gray(img);
imshow(gray);
end
% image processing
img2 = imresize(img, 0.5); % scale 50%
img3 = imrotate(img, 45); % rotate 45 degrees
img4 = imadjust(img, [0.2 0.8], []); % contrast adjust
% audio
[y, fs] = audioread('song.wav'); % y = samples, fs = sample rate
sound(y, fs); % play audio
audiowrite('output.wav', y, fs);
% record audio
recObj = audiorecorder(44100, 16, 1);
recordblocking(recObj, 3); % record 3 seconds
y = getaudiodata(recObj);Symbolische Mathematik & Fortgeschrittenes
Symbolische Variablen & Vereinfachung
Die Symbolic Math Toolbox ermöglicht exakte (nicht numerische) Berechnung. syms deklariert symbolische Variablen. simplify, expand, factor, collect manipulieren algebraische Ausdrücke. subs substituiert Werte oder Variablen. vpa (Variable-Precision Arithmetic) rechnet mit beliebiger Genauigkeit – nützlich, wenn Floating-Point-Rundungsfehler wichtig sind. Symbolische Ergebnisse sind exakt (z.B. sqrt(2) bleibt sqrt(2), nicht 1.4142...). Bei Bedarf mit double() zu numerisch konvertieren.
% create symbolic variables (Symbolic Math Toolbox)
syms x y z
% symbolic expressions
f = x^2 + 2*x + 1;
g = sin(x)^2 + cos(x)^2;
% simplify
simplify(f) % (x + 1)^2
simplify(g) % 1
expand((x+1)^3) % x^3 + 3*x^2 + 3*x + 1
factor(x^2 - 1) % (x - 1)*(x + 1)
collect(x^2 + 2*x + x^2)% 2*x^2 + 2*x
% substitute values
subs(f, x, 3) % 16 (f at x=3)
subs(f, x, y) % y^2 + 2*y + 1
% pretty print
pretty(f)
disp(f)
% convert between numeric and symbolic
double(sym('1/3')) % 0.3333
sym(0.5) % 1/2
vpa(pi, 50) % 50-digit pi: 3.1415926535897...Analysis: Ableitungen & Integrale
diff differenziert (zweites Argument für Ableitungen höherer Ordnung übergeben). int integriert – ohne Grenzen gibt es die Stammfunktion zurück; mit Grenzen berechnet es das bestimmte Integral. limit berechnet Grenzwerte (einschließlich einseitiger mit 'left'/'right'). taylor entwickelt eine Funktion als Taylor-Reihe um einen Punkt. Diese geben symbolische Ausdrücke zurück; double() oder vpa() für numerische Ergebnisse verwenden. Symbolische Analysis ist exakt und vermeidet numerische Rundungsfehler.
syms x
% differentiation
f = x^3 + 2*x^2 + x;
df = diff(f) % 3*x^2 + 4*x + 1
d2f = diff(f, 2) % second derivative: 6*x + 4
diff(f, x, 3) % third derivative: 6
% partial derivatives
syms x y
g = x^2 * y + sin(x*y);
diff(g, x) % 2*x*y + y*cos(x*y)
diff(g, y) % x^2 + x*cos(x*y)
% integration
int(x^2) % x^3/3 (indefinite)
int(x^2, x, 0, 1) % 1/3 (definite, 0 to 1)
int(sin(x), x, 0, pi) % 2
% limits
limit(sin(x)/x, x, 0) % 1
limit(1/x, x, inf) % 0
limit(1/x, x, 0, 'left') % -inf
% Taylor series
taylor(exp(x), x, 0, 'Order', 6)
% 1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120Gleichungen lösen
solve findet exakte (symbolische) Lösungen für algebraische Gleichungen und Systeme. Für Gleichungen ohne geschlossene Form vpasolve (numerisch) verwenden. dsolve löst gewöhnliche Differentialgleichungen symbolisch – Anfangs-/Randbedingungen für eine partikuläre Lösung angeben. Ergebnisse sind symbolisch; mit double/vpa für Plotting konvertieren. Für komplexe ODEs, die nicht symbolisch lösbar sind, ode45 (numerischer Solver) verwenden. Immer prüfen, ob solve leer zurückgab (keine Lösung gefunden).
syms x y
% solve algebraic equations
solve(x^2 - 4 == 0, x) % [2; -2]
solve(x^2 + 1 == 0, x) % [i; -i] (complex roots)
% solve a system
sol = solve([x + y == 5, x - y == 1], [x, y]);
sol.x % 3
sol.y % 2
% solve with parameters
syms a b c
r = solve(a*x^2 + b*x + c == 0, x);
% r = -(b + (b^2 - 4*a*c)^(1/2))/(2*a), ...
% numerical solve (no closed form)
vpasolve(x^5 - 3*x + 1 == 0, x)
% differential equations
syms y(t) t
ode = diff(y, t) == -k*y; % dy/dt = -k*y
cond = y(0) == y0;
ySol(t) = dsolve(ode, cond); % y0*exp(-k*t)
% system of ODEs
syms x(t) y(t)
eq1 = diff(x,t) == y;
eq2 = diff(y,t) == -x;
sol = dsolve([eq1, eq2]);Laplace- & Fourier-Transformationen
laplace/ilaplace berechnen das Laplace-Transformationspaar – unerlässlich zum Lösen linearer ODEs und Analysieren von Regelungssystemen. fourier/ifourier machen dasselbe für die Fourier-Transformation (kontinuierliche Frequenz). ztrans/iztrans behandeln diskrete Signale (digitale Filter). Der Workflow zum Lösen von ODEs via Laplace: ODE zu algebraisch transformieren, nach Y(s) lösen, dann Rücktransformation. Dies sind exakte symbolische Operationen; für numerische Transformationen fft verwenden.
syms t s w
% Laplace transform
f = exp(-a*t);
F = laplace(f) % 1/(a + s)
% default: f(t) -> F(s)
% inverse Laplace
f2 = ilaplace(1/(s+1)) % exp(-t)
% Fourier transform
g = exp(-t^2);
G = fourier(g) % pi^(1/2)*exp(-w^2/4)
% inverse Fourier
g2 = ifourier(G)
% Z-transform (for discrete signals)
syms n z
h = a^n;
H = ztrans(h) % -z/(a - z) (for |z| > |a|)
h2 = iztrans(z/(z-a)) % a^n
% apply transform to solve ODE
% y'' + y = 0, y(0)=0, y'(0)=1
syms y(t) Y(s)
ode = diff(y, t, 2) + y == 0;
% take Laplace of both sides, solve for Y(s), then invertNumerische ODE-Solver
ode45 ist der Standard-ODE-Solver – eine Runge-Kutta-(4,5)-Methode, die genau und adaptiv ist. Für Systeme ist der Zustand ein Vektor v, und die Funktion gibt einen Spaltenvektor von Ableitungen zurück. ode15s ist für steife Probleme (wo Dynamiken auf sehr unterschiedlichen Zeitskalen operieren). odeset konfiguriert Toleranzen und Events. Zum Übergeben von Parametern eine anonyme Funktion verwenden, die sie erfasst. Immer die Lösung plotten, um zu verifizieren, dass sie sinnvoll aussieht. Für Randwertprobleme bvp4c verwenden.
% solve dy/dt = f(t, y) numerically with ode45
% define the ODE as a function
f = @(t, y) -2*y; % dy/dt = -2y (exponential decay)
% solve on [0, 5] with y(0) = 1
[t, y] = ode45(f, [0 5], 1);
plot(t, y);
xlabel('t'); ylabel('y');
% system of ODEs (Lotka-Volterra predator-prey)
% dx/dt = 1.5x - xy, dy/dt = -0.7y + 0.1xy
ode_sys = @(t, v) [1.5*v(1) - v(1)*v(2);
-0.7*v(2) + 0.1*v(1)*v(2)];
[t, V] = ode45(ode_sys, [0 20], [10; 5]);
plot(t, V(:,1), 'b', t, V(:,2), 'r');
legend('Prey', 'Predator');
% stiff ODE solver (for fast dynamics)
[t, y] = ode15s(f, [0 5], 1);
% set options
opts = odeset('RelTol', 1e-6, 'AbsTol', 1e-9);
[t, y] = ode45(f, [0 5], 1, opts);
% pass parameters via anonymous function
a = 0.5;
f = @(t, y, a) -a*y;
[t, y] = ode45(@(t,y) f(t,y,a), [0 10], 1);Matrix-Operationen Deep Dive
Lineare Gleichungen & Zerlegungen
Der Backslash-Operator (\) ist MATLABs bevorzugter linearer Solver – er wählt automatisch LU, QR oder Cholesky basierend auf der Matrix. Niemals inv(A)*b verwenden, außer man braucht tatsächlich die Inverse; es ist langsamer und numerisch weniger stabil. lu, qr und chol geben die Standard-Matrixfaktorisierungen zurück. eig berechnet Eigenwerte/Eigenvektoren, und svd gibt die Singulärwertzerlegung – fundamental für PCA, Pseudo-Inversen und Niedrig-Rang-Approximationen.
% solve Ax = b
A = [3 2 -1; 2 -2 4; -1 0.5 -1];
b = [1; -2; 0];
x = A \ b; % backslash: preferred solver
x = inv(A) * b; % explicit inverse (slower, less stable)
x = linsolve(A, b); % optimized linear solver
% LU, QR, Cholesky decompositions
[L, U, P] = lu(A); % PA = LU
[Q, R] = qr(A); % QR factorization
R = chol(A'*A); % Cholesky (needs SPD matrix)
% eigenvalues and eigenvectors
[V, D] = eig(A); % A*V = V*D
eigenvalues = diag(D);
% singular value decomposition
[U, S, V] = svd(A); % A = U*S*V'Sparse Matrizen
Sparse Matrizen speichern nur Nonzero-Einträge – unerlässlich beim Arbeiten mit 100k+ dimensionalen Matrizen, die meist Nullen sind (häufig in Finite-Elemente-Methoden, Graph-Algorithmen und PDEs). sparse(i,j,v) baut aus Triplet-Form; full konvertiert zurück. Arithmetik zwischen Sparse-Matrizen bleibt sparse. nnz zählt Nonzeros und spy plottet das Sparsity-Muster. Sparse lineare Lösungen (A\b) verwenden automatisch spezialisierte Solver wie UMFPACK.
% create sparse matrix (memory efficient for large, mostly-zero)
S = sparse(10000, 10000);
S(1, 1) = 5;
S(2, 3) = 10;
% from triplets (row, col, value)
i = [1 2 2 3];
j = [1 1 3 3];
v = [4 5 7 9];
S = sparse(i, j, v, 3, 3);
% convert sparse <-> full
F = full(S);
S2 = sparse(F);
% sparse identity and diagonal
I = speye(1000);
D = spdiags(ones(1000,1), 0, 1000, 1000);
% operations preserve sparsity
nnz(S) % number of nonzeros
spy(S) % visualize sparsity patternMatrix-Funktionen & Reshaping
reshape arrangiert Elemente spaltenmajor (erst Spalten runter) – eine häufige Fehlerquelle beim Portieren von Row-Major-Sprachen. flipud/fliplr/rot90 sind praktisch zum Umkehren oder Transponieren auf nicht-standardmäßige Weise. repmat kachelt eine Matrix; repelem dupliziert einzelne Elemente. Konkatenation verwendet [A; B] (vertikal) und [A B] (horizontal), oder horzcat/vertcat für programmatische Verwendung. arrayfun wendet eine Funktion elementweise an, wenn Vektorisierung nicht möglich ist.
A = [1 2 3; 4 5 6];
% reshape (column-major order!)
B = reshape(A, 3, 2); % [1 5; 4 3; 2 6]
C = reshape(A, 6, 1); % column vector
% flip and rotate
flipud(A) % flip up-down
fliplr(A) % flip left-right
rot90(A) % rotate 90 degrees
rot90(A, 2) % rotate 180 degrees
% repmat and repelem
repmat([1 2], 2, 3) % tile 2x3
repelem([1 2 3], 2) % [1 1 2 2 3 3]
% concatenation
[A; A] % vertical (must have same # cols)
[A A] % horizontal (must have same # rows)
horzcat(A, A); vertcat(A, A);
% matrix functions (apply element-wise via fun)
arrayfun(@(x) x^2, A)Broadcasting & Vektorisierung
Seit R2016b broadcastet MATLAB automatisch (expandiert) Dimensionen der Größe 1, um zum anderen Operanden zu passen – kein Bedarf für bsxfun oder repmat. Vektorisierung (Operationen auf ganzen Arrays statt elementweisen Schleifen) ist der größte Performance-Gewinn in MATLAB, weil die zugrunde liegenden BLAS/LAPACK-Routinen hoch optimiert sind. Arrays immer vor dem Füllen in einer Schleife vorinitialisieren; dynamisches Wachsen von Arrays erzwingt Reallokation bei jeder Iteration und ist O(n^2).
% MATLAB implicitly expands (broadcasts) since R2016b
A = [1 2 3; 4 5 6]; % 2x3
b = [10 20 30]; % 1x3
C = A + b; % 2x3: b added to each row
c = [1; 2]; % 2x1
D = A + c; % 2x3: c added to each column
% vectorized operations (much faster than loops)
x = linspace(0, 2*pi, 1e6);
y = sin(x) .* cos(x); % element-wise, no loop needed
% avoid growing arrays in loops
% BAD: for k=1:1e6, s(k) = k; end
% GOOD: preallocate
s = zeros(1, 1e6);
for k = 1:1e6
s(k) = k;
end
% even better: vectorize
s = 1:1e6;
% bsxfun (legacy, before auto-broadcasting)
E = bsxfun(@plus, A, b);Numerische Lineare-Algebra-Anwendungen
Der Backslash-Operator löst automatisch Least-Squares-Probleme, wenn A rechteckig ist (mehr Zeilen als Spalten). polyfit/polyval passen Polynome an und werten sie aus. PCA wird am stabilsten via SVD der zentrierten Datenmatrix berechnet – die Spalten von V sind Hauptrichtungen und diag(S) gibt die Standardabweichungen. cond(A) misst numerische Sensitivität; Werte über 1e12 bedeuten, dass die Matrix für Double-Precision-Arithmetik im Wesentlichen singulär ist.
% least-squares fit (overdetermined system)
A = [1 1; 1 2; 1 3; 1 4];
b = [6; 5; 7; 10];
x = A \ b; % least-squares solution
% polynomial curve fitting
t = 0:0.1:5;
y = 2*t.^2 + 1 + 0.5*randn(size(t));
p = polyfit(t, y, 2); % degree-2 fit
yfit = polyval(p, t);
% PCA via SVD
X = randn(100, 5);
Xc = X - mean(X); % center
[U, S, V] = svd(Xc, 0);
scores = Xc * V; % principal components
variances = diag(S).^2 / (size(X,1)-1);
% condition number (numerical stability)
cond(A) % large = ill-conditioned2D- & 3D-Plotting Deep Dive
Linien-Plots & Anpassung
plot ist die Arbeitspferd-2D-Plotting-Funktion. Linien-Spec-Strings wie 'r--' (rot gestrichelt) kombinieren Farbe, Marker und Stil. hold on ermöglicht das Überlagern mehrerer Plots. subplot(m,n,k) erstellt ein m-mal-n-Raster und selektiert die k-te Zelle (zeilenmajor). set(gca, ...) modifiziert die aktuellen Achsen; gcf ist die aktuelle Figur. print mit -dpng und -r300 exportiert ein 300-DPI-PNG – viel höhere Qualität als saveas.
x = linspace(0, 2*pi, 200);
y1 = sin(x); y2 = cos(x);
figure;
plot(x, y1, 'b-', 'LineWidth', 2); hold on;
plot(x, y2, 'r--', 'LineWidth', 1.5);
hold off;
% annotations
xlabel('Angle (rad)');
ylabel('Amplitude');
title('Sine and Cosine');
legend('sin(x)', 'cos(x)', 'Location', 'best');
grid on;
% axis control
axis([0 2*pi -1.2 1.2]);
set(gca, 'FontSize', 12, 'FontName', 'Arial');
% multiple subplots
subplot(2, 1, 1); plot(x, y1);
subplot(2, 1, 2); plot(x, y2);
% save figure
saveas(gcf, 'plot.png');
print('-dpng', '-r300', 'plot_hi.png');3D-Oberflächen-, Mesh- & Kontur-Plots
meshgrid erstellt die X-, Y-Koordinatenraster, die für Oberflächen-Plots benötigt werden. surf zeichnet eine gefüllte Oberfläche, mesh zeichnet ein Wireframe, und contour projiziert auf 2D-Höhenkurven. colormap ändert die Farbabbildung (jet, parula, hot, cool, gray); parula ist die moderne Standardeinstellung. shading interp glättet Farbübergänge. plot3 zeichnet 3D-parametrische Kurven. view(az, el) setzt den Kamerawinkel; axis equal verhindert Verzerrung.
[X, Y] = meshgrid(-2:0.1:2);
Z = X .* exp(-X.^2 - Y.^2);
figure;
subplot(2,2,1); surf(X, Y, Z); title('surf');
subplot(2,2,2); mesh(X, Y, Z); title('mesh');
subplot(2,2,3); contour(X, Y, Z, 20); title('contour');
subplot(2,2,4); surfc(X, Y, Z); title('surfc');
% color mapping
colormap(jet(256)); colorbar;
shading interp; % smooth colors
% 3D line plot (parametric)
t = 0:0.01:10;
plot3(sin(t), cos(t), t, 'LineWidth', 2);
xlabel('x'); ylabel('y'); zlabel('z');
% view angle
view(45, 30); % azimuth, elevation
axis equal;Statistische & spezialisierte Plots
histogram (R2014b+) ersetzt hist mit mehr Funktionen wie 'Normalization' für PDFs. boxplot vergleicht Verteilungen über Gruppen. scatterhist zeigt einen Scatter-Plot mit marginalen Histogrammen – großartig zum Visualisieren von Korrelationen. bar unterstützt gruppierte und gestapelte Layouts. errorbar fügt Unsicherheitsvisualisierung hinzu. Diese spezialisierten Plots sind unerlässlich für wissenschaftliche Datenpräsentation und explorative Analyse.
data = randn(1000, 1);
% histogram (modern)
histogram(data, 30, 'Normalization', 'pdf');
hold on; x = -4:0.1:4; plot(x, normpdf(x), 'r-', 'LineWidth', 2);
% box plot by group
g = randi([1 3], 100, 1);
boxplot(data, g);
% scatter with marginal histograms
x = randn(200,1); y = x + 0.5*randn(200,1);
scatterhist(x, y);
% bar chart
sales = [10 25 30; 20 15 40];
bar(sales); legend('Q1','Q2','Q3');
% pie chart
pie([30 20 50], {'A','B','C'});
% error bars
y = [1 2 3 4]; e = [0.1 0.2 0.15 0.3];
errorbar(y, e, 'o-');Animationen & interaktive Grafiken
Animationen aktualisieren Plot-Daten innerhalb einer Schleife und rufen drawnow auf, um zu aktualisieren. Für flüssige Performance den Plot einmal erstellen und XData/YData aktualisieren statt neu zu plotten. getframe erfasst die aktuelle Figur; movie spielt eine Sequenz ab. VideoWriter exportiert zu MP4 oder AVI – nützlich zum Teilen von Ergebnissen. Achsengrenzen immer außerhalb der Schleife setzen, um Auto-Rescaling-Jitter zu verhindern.
% animated line plot
figure;
h = plot(NaN, NaN);
axis([0 10 -1 1]); xlabel('t'); ylabel('y');
for t = 0:0.1:10
set(h, 'XData', [get(h,'XData') t], ...
'YData', [get(h,'YData') sin(t)]);
drawnow;
end
% getframe to capture animation
frames = [];
for k = 1:50
plot(sin(linspace(0, k*pi/10, 200)));
axis([0 200 -1 1]);
frames = [frames, getframe];
end
movie(frames, 1, 30); % play once at 30 fps
% write to video file
v = VideoWriter('anim.mp4', 'MPEG-4');
v.FrameRate = 30; open(v);
for k = 1:50
plot(sin(linspace(0, k*pi/10, 200)));
writeVideo(v, getframe);
end
close(v);Grafikobjekte & Handle-Anpassung
MATLAB-Grafiken basieren auf einem Baum von Handle-Objekten (figure → axes → lines, text, patches). set/get modifizieren Properties; findobj lokalisiert Objekte nach Property. Die 'Interpreter'-Option ermöglicht TeX- oder vollständiges LaTeX-Rendering für mathematische Notation. exportgraphics (R2020a+) produziert publikationsqualitative Vektor-PDFs mit engen Bounding-Boxes – viel besser als das alte print zum Einbetten in Papieren.
% everything in MATLAB graphics is a handle object
h = plot(1:10, 'r-');
set(h, 'LineWidth', 3, 'Marker', 'o', 'MarkerSize', 8);
get(h, 'Color') % returns [1 0 0]
% find objects
ax = gca; % current axes
fig = gcf; % current figure
lines = findobj(ax, 'Type', 'line');
% property exploration
get(ax) % list all axes properties
set(ax) % list possible values
% text annotations with LaTeX
text(2, 0.5, '\alpha^2 + \beta^2', 'Interpreter', 'tex');
title('$\int_0^1 x^2 dx$', 'Interpreter', 'latex');
% legend with custom location and orientation
legend({'data1','data2'}, 'Location','northwest','Orientation','horizontal');
% export with tight bounding box
exportgraphics(gcf, 'fig.pdf', 'ContentType','vector');Simulink-Grundlagen
Simulink-Modelle erstellen & ausführen
Simulink modelliert dynamische Systeme mit Blockdiagrammen. Während die meisten Benutzer Modelle interaktiv im Simulink-Editor erstellen, kann man sie auch mit new_system, add_block, set_param und add_line skripten – nützlich für Parameter-Sweeps und automatische Modellgenerierung. sim führt die Simulation aus. Jeder Block hat Parameter, die über set_param/get_param zugänglich sind. Der Block-Pfad ist 'library/Sublibrary/Block' für Quellen und 'model/Block' für Instanzen.
% create a new Simulink model programmatically
mdl = 'my_model';
new_system(mdl);
open_system(mdl);
% add blocks
add_block('simulink/Sources/Sine Wave', [mdl '/Sine']);
add_block('simulink/Sinks/Scope', [mdl '/Scope']);
add_block('simulink/Math Operations/Gain', [mdl '/Gain']);
% set block parameters
set_param([mdl '/Gain'], 'Gain', '2');
% connect blocks (port handles)
sine_out = get_param([mdl '/Sine'], 'PortHandles');
gain_in = get_param([mdl '/Gain'], 'PortHandles');
gain_out = get_param([mdl '/Gain'], 'PortHandles');
scope_in = get_param([mdl '/Scope'], 'PortHandles');
add_line(mdl, sine_out.Outport(1), gain_in.Inport(1));
add_line(mdl, gain_out.Outport(1), scope_in.Inport(1));
% set simulation time and run
set_param(mdl, 'StopTime', '10');
sim(mdl);Solver & Simulation konfigurieren
Die Solver-Wahl beeinflusst Genauigkeit und Geschwindigkeit: ode45 (variable Schrittweite Runge-Kutta) ist Standard für nicht-steife Probleme; ode15s für steife Systeme; Fixed-Step-Solver (ode4) sind für Codegenerierung und Echtzeit-Targets erforderlich. sim gibt ein SimulationOutput-Objekt zurück, das tout, yout und logs enthält. SimulationInput-Objekte ermöglichen das Überschreiben von Parametern und Eingaben pro Lauf – unerlässlich für Monte-Carlo-Studien. Der Rapid-Accelerator-Modus kompiliert das Modell vor für schnelle wiederholte Simulationen.
% configure solver
set_param(mdl, 'Solver', 'ode45');
set_param(mdl, 'StopTime', '20');
set_param(mdl, 'MaxStep', '0.1');
set_param(mdl, 'RelTol', '1e-4');
% variable-step vs fixed-step
% variable-step: ode45, ode15s, ode23tb (auto-adjusts)
% fixed-step: ode1, ode4, ode5 (real-time/hardware)
% simulate and capture output
out = sim(mdl, 'ReturnWorkspaceOutputs', 'on');
t = out.tout;
y = out.yout;
% simulate from workspace with input
set_param([mdl '/In1'], 'VariableName', 'u');
simIn = Simulink.SimulationInput(mdl);
simIn = setExternalInput(simIn, [t, u]);
out = sim(simIn);
% rapid accelerator for repeated runs
rtp = Simulink.BlockDiagram.buildRapidAcceleratorTarget(mdl);Subsysteme & Masking
Subsysteme gruppieren verwandte Blöcke hierarchisch und verbessern die Lesbarkeit. Masking ermöglicht das Exponieren von Parametern im Dialog eines Subsystems, sodass Benutzer es konfigurieren können, ohne die Interna zu öffnen – die Grundlage wiederverwendbarer benutzerdefinierter Blöcke. Library-Blöcke (in .slx-Bibliotheken gespeichert) können in mehrere Modelle gezogen und zentral aktualisiert werden. Model-References verlinken separate .slx-Dateien für groß angelegte modulare Entwicklung. Variant-Subsysteme wählen zwischen Implementierungen zur Kompilierzeit.
% create a subsystem
add_block('simulink/Ports & Subsystems/Subsystem', [mdl '/Controller']);
% mask a subsystem to expose parameters
Simulink.Mask.create([mdl '/Controller']);
mask = Simulink.Mask.get([mdl '/Controller']);
mask.addParameter('Type', 'edit', 'Name', 'Kp', 'Prompt', 'Proportional gain');
mask.addParameter('Type', 'edit', 'Name', 'Ki', 'Prompt', 'Integral gain');
% use the mask parameter inside the subsystem
set_param([mdl '/Controller/Gain'], 'Gain', 'Kp');
% library blocks (reusable)
% save model as .slx library: save_system(mdl, 'my_lib.slx');
% set_param(mdl, 'BlockDiagramType', 'Library');
% model reference (separate .slx file)
set_param(mdl, 'ModelReferenceSimulationMode', 'normal');
% variant subsystems (compile-time selection)
add_block('simulink/Ports & Subsystems/Variant Subsystem', [mdl '/Var']);Stateflow für Zustandsautomaten
Stateflow (in Simulink enthalten) ergänzt endliche Zustandsautomaten und Flussdiagramme für ereignisgesteuerte Logik – häufig in Embedded-Controllern, Mode-Supervisoren und Protokoll-Implementierungen. Zustände haben entry/during/exit-Aktionen. Transitionen feuern bei Ereignissen oder Bedingungen. Die MATLAB-API (sfroot, Stateflow.State usw.) ermöglicht das programmatische Generieren von Charts. Stateflow ist unerlässlich für hybride Systeme, die kontinuierliche Dynamik (Simulink) mit diskreter Mode-Logik kombinieren.
% Stateflow charts model event-driven logic
% add a Stateflow chart to a model
sf = sfnew;
chart = sfroot.find('-isa', 'Stateflow.Chart');
% MATLAB API to add states and transitions
s1 = Stateflow.State(chart);
s1.Name = 'Off';
s1.Position = [50 50 80 60];
s1.LabelString = 'entry: led = 0;';
s2 = Stateflow.State(chart);
s2.Name = 'On';
s2.Position = [200 50 80 60];
s2.LabelString = 'entry: led = 1;';
% transition from Off to On on event 'press'
t = Stateflow.Transition(chart);
t.Source = s1; t.Destination = s2;
t.Event = 'press';
% simulate chart from MATLAB
% chart inputs: events and data defined in the chartCodegenerierung & Deployment
Simulink Coder generiert C/C++ aus Modellen; Embedded Coder produziert produktionsqualitativen Code mit Optimierungen für spezifische Prozessoren. Dies ermöglicht Ingenieuren, vom Blockdiagramm zum deployten Embedded-Controller ohne manuelles Codieren zu gelangen. Fixed-Point-Konvertierung (via fxptool) bereitet Modelle für Integer-only-Hardware wie Mikrocontroller vor. PLC Coder generiert IEC 61131-3-Code für industrielle Controller. Echtzeit-Target-Unterstützung (Speedgoat, dSPACE) ermöglicht Hardware-in-the-Loop-Testing.
% generate C/C++ code from a Simulink model
set_param(mdl, 'SystemTargetFile', 'grt.tlc'); % generic real-time
slbuild(mdl); % build
% embed code generation
set_param(mdl, 'SystemTargetFile', 'ert.tlc'); % embedded coder
slbuild(mdl);
% configure for specific hardware
set_param(mdl, 'HardwareImplementation', ...
'Manufacturer', 'ARM Compatible', 'Type', 'Cortex-M');
% fixed-point conversion (for integer-only hardware)
fxp_cfg = fxptool(mdl);
% generate PLC code (industrial controllers)
plcgeneratecode(mdl);
% deploy to Speedgoat, dSPACE, or other real-time targets
% via vendor-specific blocks and target files
% HIL (hardware-in-the-loop) testing
slrealtime('Speedgoat');GUI & App Designer
App Designer Grundlagen
App Designer (gestartet mit appdesigner) ist das moderne visuelle Tool zum Erstellen von MATLAB-GUIs und speichert .mlapp-Dateien, die Layout und Code bündeln. Für programmatische UIs erstellt uifigure (R2014b+) moderne Figure-Fenster mit uibutton, uilabel, uieditfield, uislider, uidropdown und uiaxes. Callbacks sind Function-Handles, die Properties wie ButtonPushedFcn zugewiesen werden. Der ältere GUIDE ist veraltet; neuer Code sollte uifigure-basierte Komponenten oder App Designer verwenden.
% App Designer (appdesigner command) creates .mlapp files
% Modern replacement for GUIDE (deprecated in R2020a)
% programmatic UI (alternative to App Designer)
f = uifigure('Name', 'My App', 'Position', [100 100 600 400]);
% add components
btn = uibutton(f, 'Text', 'Click Me', ...
'Position', [50 300 100 30]);
lbl = uilabel(f, 'Text', 'Hello', ...
'Position', [50 250 200 30]);
fld = uieditfield(f, 'text', 'Position', [50 200 200 30]);
% slider and drop-down
sld = uislider(f, 'Position', [50 150 200 3]);
dd = uidropdown(f, 'Items', {'A','B','C'}, ...
'Position', [50 100 100 30]);
% axes for plotting
ax = uiaxes(f, 'Position', [300 100 250 250]);
plot(ax, 1:10, rand(1,10));
% callback
btn.ButtonPushedFcn = @(src,event) clickHandler(lbl);
function clickHandler(lbl)
lbl.Text = ['Clicked at ' datestr(now)];
endLayout-Manager & Container
uigridlayout (R2018b+) ist der moderne responsive Layout-Manager – Zeilen und Spalten können fixed, proportional ('1x') oder fit-content sein. uitabgroup/uitab erstellen Tabbed-Interfaces. uipanel gruppiert verwandte Komponenten visuell. uiscrollbox fügt Scrolling für Inhalte hinzu, die das Fenster überschreiten. Dialog-Funktionen (uigetfile, inputdlg, msgbox, questdlg) behandeln Standard-Dateiauswahl, Eingabe und Benachrichtigungen. Diese Layout-Tools sind unerlässlich für professionelle, skalierbare MATLAB-Anwendungen.
f = uifigure;
% grid layout (responsive)
g = uigridlayout(f, [3 2]);
g.RowHeight = {'1x', '2x', '1x'};
g.ColumnWidth = {'1x', '2x'};
btn1 = uibutton(g); btn1.Layout.Row = 1; btn1.Layout.Column = 1;
btn2 = uibutton(g); btn2.Layout.Row = 1; btn2.Layout.Column = 2;
% tab group
tg = uitabgroup(f);
t1 = uitab(tg, 'Title', 'Plot');
t2 = uitab(tg, 'Title', 'Data');
ax = uiaxes(t1); plot(ax, rand(5));
% panel for grouping
p = uipanel(f, 'Title', 'Settings', 'Position', [20 20 200 150]);
% scrollable container for long content
sf = uiscrollbox(f);
% add many components inside sf
% dialog windows
uigetfile('*.mat', 'Select MAT file');
inputdlg({'Name','Age'}, 'Enter data');
msgbox('Operation complete');Callbacks & Event-Behandlung
Modernes MATLAB verwendet Function-Handle-Callbacks mit zwei Argumenten (src, event), wobei event strukturierte Daten wie event.Value oder event.Key trägt. ValueChangingFcn feuert kontinuierlich während der Interaktion; ValueChangedFcn feuert einmal am Ende. addlistener erstellt persistente Listener auf jeder Property. timer-Objekte führen Callbacks nach Zeitplan aus – nützlich für Live-Datenakquisitions-UIs. Listener und Timer immer aufräumen (delete), um Memory-Leaks zu vermeiden.
% value-changing callback (slider)
sld = uislider(f);
sld.ValueChangingFcn = @(src,event) onSlider(src, event);
function onSlider(src, event)
disp(['Dragging: ' num2str(event.Value)]);
end
% value-changed callback (final value)
sld.ValueChangedFcn = @(src,event) disp(['Final: ' num2str(event.Value)]);
% button callback with event data
btn.ButtonPushedFcn = @onButton;
function onButton(src, event)
fprintf('Button %s pushed
', src.Text);
end
% keyboard callback on figure
f.WindowKeyPressFcn = @(src,event) onKey(event);
function onKey(event)
fprintf('Key: %s
', event.Key);
end
% listener pattern (any property change)
lh = addlistener(btn, 'Text', 'PostSet', @(src,event) disp('Text changed'));
delete(lh); % remove listener
% timer for periodic updates
t = timer('ExecutionMode','fixedRate','Period',1, ...
'TimerFcn',@(~,~) disp('tick'));
start(t);Apps für Distribution paketieren
matlab.apputil.package bündelt eine App-Designer-App in eine .mlappinstall-Datei, die Benutzer über den Apps-Tab installieren. Der Application Compiler (deploytool) produziert Standalone-Executables (.exe), die mit der kostenlosen MATLAB Runtime laufen – keine MATLAB-Lizenz auf dem Ziel nötig. Web Apps (R2020a+) deployen zu einem MATLAB Web App Server und laufen in jedem Browser. Diese Distribution-Pipeline ermöglicht das Teilen von MATLAB-Anwendungen mit Nicht-MATLAB-Benutzern.
% package an App Designer app as a .mlappinstall file
% using the Application Compiler (deploytool app)
% programmatically create a packaged app
appFile = matlab.apputil.package(...
'Name', 'MyPlotTool', ...
'Summary', 'A simple plotting utility', ...
'Description', 'Plots user-supplied data.', ...
'MainFile', 'MyPlotTool.mlapp', ...
'FolderPath', 'my_app_package');
% install the app
matlab.apputil.install('MyPlotTool.mlappinstall');
% list installed apps
apps = matlab.apputil.getInstalledApps;
% uninstall
matlab.apputil.uninstall('MyPlotTool');
% standalone desktop app (MATLAB Runtime required)
% deploytool -> Application Compiler -> produce .exe
% web app (runs in browser, MATLAB Web App Server)
% deploytool -> Web AppHäufige UI-Muster
drawnow limitrate aktualisiert Grafiken ohne Blockieren – kritisch für Live-Datenanzeigen. uitable zeigt tabellarische Daten mit sortierbaren Spalten. uiprogressdlg zeigt eine modale Fortschrittsleiste für lange Operationen. uicontextmenu fügt Rechtsklick-Menüs zu jeder Komponente hinzu. Diese Muster decken die häufigsten UI-Bedürfnisse: Live-Updates, Datentabellen, Fortschrittsfeedback und kontextsensitive Aktionen. Für High-Throughput-Live-Plots animatedline in Betracht ziehen, das für Streaming-Daten optimiert ist.
% live plot update from worker
f = uifigure; ax = uiaxes(f); h = plot(ax, NaN, NaN);
for k = 1:100
set(h, 'XData', 1:k, 'YData', rand(1,k));
drawnow limitrate; % throttle for performance
end
% table display
tdata = table({'A';'B';'C'}, [1;2;3], 'VariableNames', {'Name','Val'});
uit = uitable(f, 'Data', tdata.Variables, ...
'ColumnName', tdata.Properties.VariableNames, ...
'Position', [20 20 200 150]);
% progress dialog
d = uiprogressdlg(f, 'Title', 'Working', 'Message', 'Processing...');
for k = 1:100
pause(0.01);
d.Value = k;
d.Message = sprintf('%d%% complete', k);
end
close(d);
% context menu
cm = uicontextmenu(f);
m1 = uimenu(cm, 'Text', 'Reset', 'MenuSelectedFcn', @reset);
ax.UIContextMenu = cm;Image Processing Toolbox
Bilder lesen, schreiben & anzeigen
imread unterstützt PNG, JPEG, TIFF, BMP und viele wissenschaftliche Formate. Bild-Datentypen sind wichtig: uint8 (0-255) ist häufig für Dateien, double (0-1) für Verarbeitung. Immer im2double/im2uint8 (was reskaliert) statt double()/uint8() (was abschneidet) verwenden. im2gray (R2020b+) ersetzt rgb2gray. imwrite unterstützt formatspezifische Optionen wie JPEG-Qualität. imfinfo liest Metadaten ohne Pixel-Daten zu laden.
% read and display an image
img = imread('peppers.png');
imshow(img);
title('RGB image');
% image types
% uint8 (0-255), uint16, double (0-1), logical (binary)
whos img
class(img) % uint8
size(img) % rows x cols x channels
% convert between types
d = im2double(img); % scale to [0,1]
u = im2uint8(d); % scale to [0,255]
g = im2gray(img); % RGB to grayscale (R2020b+, replaces rgb2gray)
% write to file
imwrite(g, 'gray.png');
imwrite(g, 'gray.jpg', 'Quality', 90);
% info without loading
info = imfinfo('peppers.png');
disp(info.Width);
% montage of multiple images
fileList = dir('*.png');
montage({fileList.name});Filterung & Verbesserung
imgaussfilt ist der moderne Gauß-Blur (ersetzt fspecial('gaussian') + imfilter). medfilt2 entfernt Salt-and-Pepper-Rauschen ohne Kanten zu verwischen. fspecial erstellt vordefinierte Kernel (sobel, prewitt, laplacian, gaussian). imsharpen verbessert Kanten via Unsharp-Masking. histeq führt globale Histogramm-Equalization durch; adapthisteq (CLAHE) macht es lokal für besseren Kontrast in nicht-einheitlichen Bildern. imadjust mappt Intensitätsbereiche für Helligkeits-/Kontrastkorrektur.
img = im2double(imread('cameraman.tif'));
% Gaussian blur
h = imgaussfilt(img, 2); % sigma = 2
h2 = imgaussfilt(img, [3 3], 1.5);
% median filter (salt-and-pepper noise)
noisy = imnoise(img, 'salt & pepper', 0.05);
m = medfilt2(noisy, [3 3]);
% custom 2D filter
kernel = fspecial('sobel');
edge_img = imfilter(img, kernel);
% unsharp masking (sharpen)
sharp = imsharpen(img, 'Amount', 0.8, 'Radius', 1.5);
% histogram equalization
eq = histeq(img); % global
eq2 = adapthisteq(img); % CLAHE (local)
% image arithmetic
bright = imadd(img, 0.1);
contrast = imadjust(img, [0.3 0.7], []);Morphologische Operationen & Segmentierung
Morphologische Operationen (erode, dilate, open, close) verarbeiten binäre Bilder mit Strukturierenden Elementen (strel). Opening entfernt kleine Objekte; Closing füllt kleine Löcher. bwconncomp findet verbundene Regionen; regionprops extrahiert Messungen (Area, Centroid, BoundingBox) für jede. watershed segmentiert sich berührende Objekte. edge erkennt Grenzen (Canny ist am robustesten). graythresh berechnet Otsus globalen Schwellenwert; multithresh macht Multi-Level. Diese Tools bilden den Kern der Computer-Vision-Vorverarbeitung.
bw = imread('text.png');
bw = imbinarize(bw);
% morphological operations
se = strel('disk', 3);
er = imerode(bw, se); % shrink objects
di = imdilate(bw, se); % grow objects
op = imopen(bw, se); % erode then dilate (removes small noise)
cl = imclose(bw, se); % dilate then erode (fills small holes)
% connected components
cc = bwconncomp(bw);
stats = regionprops(cc, 'Area', 'Centroid', 'BoundingBox');
[areas, idx] = sort([stats.Area], 'descend');
% watershed segmentation
grad = imgradient(bw);
D = -bwdist(~bw);
L = watershed(D);
% edge detection
edges = edge(bw, 'canny');
edges2 = edge(bw, 'sobel');
% thresholding
T = graythresh(img); % Otsu's method
bw2 = imbinarize(img, T);Feature-Erkennung & Transformationen
Feature-Erkennung findet markante Punkte für Matching und Tracking. Harris-Corners sind schnell, aber nicht skaleninvariant; SURF und ORB sind skalen-/rotationsinvariant für robustes Matching über Ansichten. extractFeatures berechnet Deskriptoren an erkannten Punkten. Die Hough-Transformation erkennt Linien (und Kreise) via Voting im Parameterraum – nützlich für Dokument-Skew-Korrektur und Spurerkennung. imregtform führt intensitätsbasierte Bildregistrierung durch und berechnet die geometrische Transformation, die zwei Bilder ausrichtet.
img = imread('cameraman.tif');
% corner detection (Harris)
corners = detectHarrisFeatures(img);
[~, strength] = corners;
imshow(img); hold on; plot(corners);
% SURF features (scale-invariant)
points = detectSURFFeatures(img);
[f1, vpts1] = extractFeatures(img, points);
% ORB features (faster, binary)
points = detectORBFeatures(img);
% Hough transform for line detection
bw = edge(img, 'canny');
[H, T, R] = hough(bw);
P = houghpeaks(H, 5);
lines = houghlines(bw, T, R, P);
% image registration
% (find transform between two images)
moving = imread('rotated.png');
fixed = img;
[optimizer, metric] = imregconfig('monomodal');
tform = imregtform(moving, fixed, 'affine', optimizer, metric);
registered = imwarp(moving, tform);Stapelverarbeitung & große Bilder
Für Stapelverarbeitung parallelisiert parfor über Bilder. blockproc verarbeitet große Bilder in Kacheln – unerlässlich, wenn das vollständige Bild nicht in den Speicher passt; die 'Destination'-Option streamt Output auf Disk. imageDatastore verwaltet Sammlungen, die zu groß zum manuellen Enumerieren sind, und integriert mit tall Arrays und dem MapReduce-Framework für Out-of-Core-Berechnung. bigTIFF-Unterstützung behandelt Gigapixel-Mikroskopie und Fernerkundungs-Bilder.
% process many images in a folder
fileList = dir('*.tif');
parfor k = 1:numel(fileList)
img = imread(fileList(k).name);
result = processImage(img);
imwrite(result, ['out_' fileList(k).name]);
end
% block processing for large images
fun = @(block) std2(block);
B = blockproc('large.tif', [256 256], fun);
B = blockproc('large.tif', [256 256], fun, 'Destination', 'out.tif');
% work with very tall/wide images without loading all
% (bigTIFF, multiresolution)
t = Tiff('big.tif', 'r');
imgInfo = t.getImageInfo;
% image datastore for huge collections
imds = imageDatastore('images/', 'IncludeSubfolders', true);
imds.ReadSize = 10; % read 10 at a time
while hasdata(imds)
[imgs, info] = read(imds);
% process batch
end
% tall arrays (out-of-core) for pixel statistics
t = tall(imds);Optimization Toolbox
Unbeschränkte & beschränkte Optimierung
fminunc löst glatte unbeschränkte Probleme; fmincon behandelt Bounds, lineare und nichtlineare Constraints. linprog und quadprog sind spezialisiert auf lineare und quadratische Zielfunktionen mit linearen Constraints – viel schneller als allgemeine Solver. optimoptions konfiguriert Solver-Verhalten (Algorithmus, Toleranzen, Display). Der 'interior-point'-Algorithmus ist robust für große Probleme; 'sqp' ist gut für nichtlineare Constraints. Analytische Gradienten angeben, wenn verfügbar, für Geschwindigkeit und Genauigkeit.
% unconstrained minimization
f = @(x) (x(1)-2)^2 + (x(2)-3)^2;
x0 = [0 0];
[x, fval] = fminunc(f, x0);
% constrained (with fmincon)
A = []; b = []; Aeq = []; beq = [];
lb = [0 0]; ub = [];
nonlcon = @(x) deal([], x(1) + x(2) - 4); % x1+x2 <= 4
[x, fval] = fmincon(f, x0, A, b, Aeq, beq, lb, ub, nonlcon);
% linear programming
f_lp = [-1 -1]; % minimize -x1 - x2
A_lp = [1 1; -1 1]; b_lp = [4; 2];
[x, fval] = linprog(f_lp, A_lp, b_lp, [], [], [0;0]);
% quadratic programming
H = [1 -1; -1 2]; c = [-2; -6];
[x, fval] = quadprog(H, c, [], [], [], [], [0;0]);
% set optimization options
opts = optimoptions('fmincon', 'Algorithm','interior-point', ...
'Display','iter', 'MaxIterations', 200);
[x, fval] = fmincon(f, x0, A, b, Aeq, beq, lb, ub, nonlcon, opts);Globale & Multiobjective-Optimierung
Lokale Solver (fminunc, fmincon) können in lokalen Minima stecken bleiben. GlobalSearch und MultiStart führen einen lokalen Solver von vielen Startpunkten aus. ga (genetischer Algorithmus), particleswarm und simulannealbnd sind derivatfreie globale Methoden – langsamer, aber arbeiten auf unstetigen oder verrauschten Zielfunktionen. gamultiobj findet die Pareto-Front für Multiobjective-Probleme und gibt eine Menge nicht-dominierter Lösungen zurück. Wahl basierend auf Problem-Glattheit, Dimensionalität und ob globale Optimalitäts-Garantien benötigt werden.
% GlobalSearch / MultiStart for non-convex problems
f = @(x) x(1)^2 + x(2)^2 + 10*sin(x(1)) + 10*sin(x(2));
opts = optimoptions('fmincon', 'Algorithm','sqp');
problem = createOptimProblem('fmincon','objective',f, ...
'x0',[0 0],'lb',[-5 -5],'ub',[5 5],'options',opts);
gs = GlobalSearch;
[x, fval] = run(gs, problem);
% genetic algorithm
[x, fval] = ga(f, 2, [], [], [], [], [-5 -5], [5 5]);
% particle swarm
[x, fval] = particleswarm(f, 2, [-5 -5], [5 5]);
% simulated annealing
[x, fval] = simulannealbnd(f, [0 0], [-5 -5], [5 5]);
% multiobjective (Pareto front)
f_multi = @(x) [x(1)^2 + x(2)^2, (x(1)-1)^2 + (x(2)-1)^2];
[x, fval] = gamultiobj(f_multi, 2, [], [], [], [], [-2 -2], [2 2]);
plot(fval(:,1), fval(:,2), 'o');Kurvenanpassung & Parameter-Schätzung
fittype definiert benutzerdefinierte parametrische Modelle; fit führt die Regression mit automatischen Startpunkt-Heuristiken durch. lsqcurvefit ist der niedrigere nichtlineare Least-Squares-Solver – nützlich, wenn feine Kontrolle oder benutzerdefinierte Jacobi-Matrizen benötigt werden. confint und predint geben Konfidenz- und Vorhersageintervalle für Unsicherheitsquantifizierung. Die Curve Fitter-App (cftool) bietet eine interaktive Oberfläche zum Erkunden von Fits. Immer Residuen auf systematische Struktur prüfen, die Modell-Fehlspezifikation vermuten lässt.
% fit a custom model to data
x = linspace(0, 5, 50);
y = 2*exp(-0.5*x) + 0.1*randn(size(x));
% define model and fit
model = fittype('a*exp(-b*x)', 'independent', 'x', ...
'coefficients', {'a','b'});
f = fit(x', y', model, 'StartPoint', [1 1]);
plot(f, x, y);
% predefined models
f2 = fit(x', y', 'exp2'); % two-term exponential
f3 = fit(x', y', 'poly2'); % quadratic polynomial
% nonlinear least squares with lsqcurvefit
fun = @(p, xdata) p(1)*exp(-p(2)*xdata);
[p, resnorm] = lsqcurvefit(fun, [1 1], x, y);
% confidence intervals
ci = confint(f, 0.95);
predint(f, x', 0.95, 'observation', 'functional');
% smoothing spline
sf = fit(x', y', 'smoothingspline');Integer- & kombinatorische Optimierung
intlinprog löst gemischt-ganzzahlige lineare Programme – das Arbeitspferd für Scheduling-, Routing- und Zuweisungsprobleme. matchpairs löst das Zuweisungsproblem optimal in O(n^3). Das Problem des Handlungsreisenden erfordert iterative Subtour-Eliminierung, da die Constraint-Menge exponentiell ist. surrogateopt ist für teure Black-Box-Funktionen (z.B. Simulationen, die Minuten pro Evaluation brauchen) – es baut ein Surrogatmodell und probt intelligent. Für kombinatorische Probleme, die zu groß für exakte Methoden sind, ga oder benutzerdefinierte Heuristiken in Betracht ziehen.
% mixed-integer linear programming (TSP-like problems)
f = [-3 -2]; % maximize 3x + 2y
A = [1 1; 2 1]; b = [4; 6];
intcon = 1:2; % both variables integer
[x, fval] = intlinprog(f, intcon, A, b, [], [], [0;0]);
% assignment problem (Hungarian algorithm)
cost = [4 1 3; 2 3 4; 3 4 1];
[assignment, cost_total] = matchpairs(cost, false);
% traveling salesman via intlinprog
n = 8; % cities
distances = rand(n, n); distances = distances + distances';
% (build subtour elimination constraints iteratively)
% knapsack
weights = [2 3 4 5]; values = [3 4 5 6];
W = 5;
f = -values;
A = weights; b = W;
intcon = 1:4;
[x, fval] = intlinprog(f, intcon, A, b, [], [], zeros(4,1), ones(4,1));
% surrogate optimization (expensive black-box)
obj = @(x) expensive_eval(x);
[x, fval] = surrogateopt(obj, lb, ub);Optimierungs-Workflow & Best Practices
Die Wahl des richtigen Solvers ist die wichtigste Entscheidung – fmincon auf ein lineares Programm zu verwenden, verschwendet Größenordnungen an Performance. Analytische Gradienten (via Problem-based-Framework oder optimoptions) dramatisch verbessern Geschwindigkeit und Zuverlässigkeit. Skalierung von Variablen auf Größenordnung 1 verbessert Konditionierung. exitflag und firstorderopt prüfen, um Konvergenz zu verifizieren. Das Problem-based-Framework (optimproblem, optimvar) ist lesbarer und lässt MATLAB den Solver automatisch wählen – bevorzugt für neuen Code.
% 1. choose solver based on problem type
% smooth? -> fminunc/fmincon
% linear? -> linprog/intlinprog
% integer? -> intlinprog
% nonsmooth/global? -> ga/particleswarm/GlobalSearch
% 2. provide gradients and Jacobians when possible
f = @(x) x(1)^2 + x(2)^2;
gradf = @(x) [2*x(1); 2*x(2)];
prob = optimproblem('Objective', f);
prob.Objective.Gradient = gradf;
% 3. scale variables to ~[1, 1]
x_scaled = (x - x0) / scale;
% 4. check optimality and feasibility
output.exitflag % 1 = converged
output.firstorderopt % should be near 0
% 5. warm start sequential problems
opts = optimoptions('quadprog','ObjectiveLimit',1e-8);
x_new = quadprog(H, c, A, b, [], [], lb, ub, x_old, opts);
% 6. use problem-based framework (cleaner)
x = optimvar('x', 2, 'LowerBound', 0);
prob = optimproblem('Objective', x(1)^2 + x(2)^2);
prob.Constraints.c1 = x(1) + x(2) >= 1;
sol = solve(prob);Paralleles Rechnen
parfor-Schleifen & Parallel Pools
parfor ist der einfachste Weg zu Parallelismus – es verteilt Schleifen-Iterationen über Worker. Iterationen müssen unabhängig sein (keine Iteration k abhängig von k-1). Variablen werden klassifiziert: Schleifenvariablen (k), sliced (nur nach k indiziert auf erster/letzter Dimension), broadcast (read-only) und reduction (kombiniert mit assoziativer Operation wie + oder *). Kommunikations-Overhead bedeutet, dass parfor nur hilft, wenn jede Iteration substanzielle Arbeit leistet. Pool einmal starten; über parfor-Schleifen wiederverwenden, um Startup-Kosten zu vermeiden.
% start a parallel pool (workers = CPU cores)
pool = gcp('nocreate');
if isempty(pool)
parpool; % start default pool
end
% parfor: parallel for loop
n = 1e6;
results = zeros(1, n);
parfor k = 1:n
results(k) = expensive_computation(k);
end
% restrictions:
% - iterations must be independent (no data dependencies)
% - variables classified as loop, sliced, broadcast, reduction
% - cannot break/continue
% reduction variables (combine results)
total = 0;
parfor k = 1:n
total = total + compute(k);
end
% sliced variables (each iteration writes distinct element)
out = zeros(n, 1);
parfor k = 1:n
out(k) = k^2;
end
% control pool size
delete(gcp('nocreate')); % shut down
parpool('local', 4); % 4 workersspmd & Distributed Arrays
spmd führt denselben Code auf allen Workern aus, wobei labidx jeden identifiziert – nützlich für datenparallele Algorithmen, wo jeder Worker einen Chunk verarbeitet. Composite-Variablen (A{1}, A{2}) halten per-Worker-Ergebnisse. Distributed Arrays verteilen ein einzelnes logisches Array über Worker; localpart gibt den lokalen Chunk. labSendrecv und gcat/gplus ermöglichen Inter-Worker-Kommunikation. spmd für feinkörnigen Parallelismus verwenden, den parfor nicht ausdrücken kann (z.B. iterative Algorithmen, die Kommunikation benötigen).
% spmd: single program, multiple data
spmd
labidx % worker index (1 to n)
numlabs % total workers
A = rand(1000) * labidx;
% each lab has its own A
end
% access Composite (per-worker data)
A{1} % A from worker 1
A{2} % A from worker 2
% distributed arrays (spread across workers)
D = distributed.rand(10000);
size(D) % 10000x10000 total
L = localpart(D); % this worker's chunk
% communicate between labs
spmd
data = rand(100, 1);
% send to next lab, receive from previous
next_lab = mod(labidx, numlabs) + 1;
prev_lab = mod(labidx - 2, numlabs) + 1;
rcvd = labSendrecv(data, next_lab, prev_lab);
end
% gather distributed to local
D = distributed.rand(1000);
full_matrix = gather(D);GPU-Computing
gpuArray überträgt Daten zur GPU; nachfolgende Operationen werden dort ausgeführt und bleiben auf der GPU, bis gather() Ergebnisse zurückholt. Die meisten elementweisen und Lineare-Algebra-Funktionen sind GPU-fähig. arrayfun führt benutzerdefinierte elementweise Funktionen auf der GPU aus (aber nur mit skalaren Operationen). Für Multi-GPU-Systeme jedem parfor-Worker eine andere GPU via gpuDevice(k) zuweisen. GPU-Computing glänzt bei großer dichter Lineare-Algebra und elementweisen Operationen; der Overhead des Datentransfers macht es ineffizient für kleine Arrays.
% move data to GPU
A = gpuArray(rand(10000));
B = gpuArray(eye(10000));
% operations execute on GPU
C = A * B; % GPU matrix multiply
D = A + B;
E = sum(A, 1);
% gather results back to CPU
C_cpu = gather(C);
% many built-in functions are GPU-enabled
x = gpuArray.linspace(-10, 10, 1e6);
y = sin(x) .* exp(-x.^2);
% arrayfun on GPU (custom element-wise functions)
f = @(a, b) a.^2 + b.^2;
result = arrayfun(f, A, B);
% check GPU
gpuDevice % info about current GPU
gpuDeviceCount % number of available GPUs
% page multiple GPUs
parfor k = 1:4
gpuDevice(k);
A = gpuArray(rand(5000));
% ... compute on GPU k
endbatch & Job-Scheduling
batch führt eine Funktion asynchron im Hintergrund aus – nützlich für lange Berechnungen, die man nicht blockieren will. batch mit 'Pool'-Option führt eine Funktion aus, die selbst parfor verwendet. Die niedrigere Job/Task-API gibt feine Kontrolle über Scheduling. parcluster wählt ein Cluster-Profil; MATLAB integriert mit SLURM, PBS und LSF via der generischen Scheduler-Schnittstelle der Parallel Computing Toolbox. Für HPC Daten auf Dateien speichern und Skripte einreichen, statt sich auf Shared Memory zu verlassen.
% run a function in background
job = batch(@my_function, 0, {arg1, arg2});
% check status
job.State % 'queued', 'running', 'finished'
wait(job); % block until done
load(job); % retrieve results
% batch with parfor inside
job = batch(@my_parfor_func, 1, {input_data}, 'Pool', 4);
% job and task objects (lower-level)
job = createJob(pool);
task = createTask(job, @my_func, 1, {arg1});
submit(job);
wait(job);
result = fetchOutputs(task);
% cluster types
% 'local' - on this machine
% 'MJS' - MATLAB Job Scheduler (server cluster)
% 'SLURM'/'PBS' - HPC scheduler integration
c = parcluster('local');
c.NumWorkers = 8;
c.saveProfile;Performance & Profiling von parallelem Code
Parallelen Code mit profile on -parallel profilen, um per-Worker-Zeitpläne zu sehen. Speedup ist durch Amdahls Gesetz begrenzt: wenn 10% des Codes seriell sind, ist der maximale Speedup 10x unabhängig von der Worker-Anzahl. Häufige Fallstricke: zu kleine Iterationen (Overhead übersteigt Arbeit), große Broadcast-Variablen (Transfer-Kosten) und exzessive Reduction-Operationen. parallel.pool.DataQueue ermöglicht Live-Fortschritts-Updates von Workern ohne Blockieren – nützlich zum Überwachen langer paralleler Jobs. Immer vorher und nachher messen, um zu verifizieren, dass Parallelismus tatsächlich hilft.
% profile parallel code
profile on -parallel
parfor k = 1:100
compute(k);
end
profile off
profview % visualize
% measure speedup
tic;
serial_result = serial_compute();
t_serial = toc;
tic;
parfor_result = parallel_compute();
t_parallel = toc;
speedup = t_serial / t_parallel;
fprintf('Speedup: %.2fx using %d workers
', speedup, pool.NumWorkers);
% avoid common pitfalls:
% 1. too little work per iteration (overhead dominates)
% 2. large broadcast variables (transfer cost)
% 3. false sharing via reduction variables
% data queue for live updates from workers
Q = parallel.pool.DataQueue;
afterEach(Q, @update_plot);
parfor k = 1:n
% ... compute ...
send(Q, partial_result);
endObjektorientierte Programmierung
Klassen & Properties
MATLAB-Klassen leben in Dateien namens ClassName.m. Der classdef-Block enthält Properties und Methoden. Property-Attribute steuern den Zugriff: SetAccess=protected bedeutet, dass nur Klassenmethoden schreiben können; Constant definiert Klassen-Level-Konstanten. Der Konstruktor ist eine Methode mit dem Klassennamen. MATLAB verwendet standardmäßig Value-Semantik (Objekte werden bei Zuweisung kopiert) – handle-Klassen für Referenz-Semantik verwenden. Überladene Methoden wie disp passen Standardverhalten an.
% class definition in a file named Point.m
classdef Point
properties
x = 0 % public, with default
y = 0
end
properties (SetAccess = protected)
id % settable only by class methods
end
properties (Constant)
PI = 3.14159
end
methods
function obj = Point(x, y)
if nargin > 0
obj.x = x;
obj.y = y;
end
obj.id = randi(1e6);
end
function r = distance(obj)
r = sqrt(obj.x^2 + obj.y^2);
end
function disp(obj)
fprintf('Point(%.2f, %.2f) [id=%d]
', ...
obj.x, obj.y, obj.id);
end
end
end
% usage
p = Point(3, 4);
p.distance() % 5
disp(p)Handle- vs Value-Klassen
Die Wahl zwischen Value- und handle-Klassen ist fundamental. Value-Klassen (Standard) kopieren bei Zuweisung und Methodenaufrufen – sicherer für immutable Daten. handle-Klassen (Subclass handle) sind Referenzen: Zuweisungen und Kopien zeigen auf dasselbe Objekt, wie Java/Python-Objekte. handle-Klassen werden für Dinge wie GUI-Komponenten, File-Handles und über Aufrufer geteilten mutablen Zustand benötigt. Value-Klassen für mathematische Objekte (Vektoren, Matrizen) verwenden, wo Immutabilität wünschenswert ist.
% value class (default): copies on assignment
classdef Vec
properties
data
end
methods
function obj = Vec(d)
obj.data = d;
end
end
end
v1 = Vec([1 2 3]);
v2 = v1; % COPY
v2.data = [4 5 6];
disp(v1.data) % still [1 2 3]
% handle class: references shared
classdef HVec < handle
properties
data
end
methods
function obj = HVec(d)
obj.data = d;
end
end
end
h1 = HVec([1 2 3]);
h2 = h1; % REFERENCE (same object)
h2.data = [4 5 6];
disp(h1.data) % [4 5 6] - changed!
% handle classes support delete method
% isequal(h1, h2) -> true (same object)Vererbung & Polymorphismus
Vererbung verwendet < in der classdef-Zeile; obj@SuperClass(args) ruft den Superklassen-Konstruktor. MATLAB unterstützt Mehrfachvererbung, aber sie ist selten und kann zu Diamant-Problemen führen. Abstrakte Methoden (deklariert in methods (Abstract)) müssen von Unterklassen implementiert werden; die Basisklasse kann nicht instanziiert werden. Polymorphismus funktioniert natürlich: Methode auf jedem Objekt aufrufen und MATLAB dispatcht zur richtigen Implementierung. isa(obj, 'ClassName') und isprop/ismethod für Runtime-Typprüfungen verwenden.
% single inheritance
classdef Dog < Animal
methods
function obj = Dog(name)
obj@Animal(name); % call superclass constructor
end
function sound(obj)
disp([obj.name ' says Woof']);
end
end
end
% multiple inheritance
classdef FlyingFish < Fish & Bird
methods
function obj = FlyingFish(name)
obj@Fish(name);
obj@Bird(name);
end
end
end
% abstract methods and classes
classdef Shape
methods (Abstract)
area(obj)
perimeter(obj)
end
end
classdef Circle < Shape
properties
radius
end
methods
function obj = Circle(r)
obj.radius = r;
end
function a = area(obj)
a = pi * obj.radius^2;
end
function p = perimeter(obj)
p = 2 * pi * obj.radius;
end
end
end
% polymorphism
shapes = {Circle(2), Square(3)};
for k = 1:numel(shapes)
fprintf('Area: %.2f
', shapes{k}.area());
endEvents & Listener
Das Events-Modell implementiert das Observer-Pattern: Klassen deklarieren Events, Listener registrieren Callbacks, und notify feuert Events. Dies entkoppelt Producer von Consumern – unerlässlich für GUIs, Simulationen und reaktive Systeme. Property-Set-Methoden (set.PropertyName) fangen Zuweisungen ab und können Events auslösen. Listener können temporär (addlistener, an Objekt-Lebensdauer gebunden) oder persistent (Listener-Objekt in Variable gehalten) sein. Listener immer aufräumen, wenn fertig, um Memory-Leaks zu verhindern.
classdef TemperatureSensor < handle
properties
Temperature = 20
end
events
TemperatureChanged
Overheated
end
methods
function set.Temperature(obj, t)
obj.Temperature = t;
notify(obj, 'TemperatureChanged');
if t > 100
notify(obj, 'Overheated');
end
end
function obj = TemperatureSensor()
% nothing
end
end
end
% create sensor and listen
s = TemperatureSensor();
addlistener(s, 'TemperatureChanged', @onTempChanged);
addlistener(s, 'Overheated', @onOverheat);
function onTempChanged(src, event)
fprintf('Temp now: %.1f
', src.Temperature);
end
function onOverheat(src, event)
warning('Overheated at %.1f!', src.Temperature);
end
% trigger
s.Temperature = 25; % prints "Temp now: 25.0"
s.Temperature = 105; % prints temp + warningOperator-Überladung & Indizierung
Operator-Überladung ermöglicht Benutzerklassen mit +, *, [] usw. zu arbeiten. Jeder Operator mappt zu einer Funktion (plus, mtimes, minus, mrdivide, horzcat, vertcat). subsref und subsasgn passen Indizierung an (obj(i), obj.field, obj{i}). Modernes MATLAB bevorzugt Dot-Notation für Property-Zugriff, aber subsref/subsasgn werden noch für Fake-Indizierungs-Pattern benötigt (z.B. eine Tensor-Bibliothek, wo T(1,2,3) ein Element extrahiert). disp für lesbaren Output überladen und end/numel für benutzerdefinierte Indizierungs-Semantik.
classdef Complex
properties
re
im
end
methods
function obj = Complex(re, im)
obj.re = re; obj.im = im;
end
function r = plus(a, b) % a + b
r = Complex(a.re + b.re, a.im + b.im);
end
function r = mtimes(a, b) % a * b
r = Complex(a.re*b.re - a.im*b.im, ...
a.re*b.im + a.im*b.re);
end
function r = abs(obj) % |obj|
r = sqrt(obj.re^2 + obj.im^2);
end
function disp(obj)
fprintf('%.2f %+.2fi
', obj.re, obj.im);
end
end
methods
function r = subsref(obj, S) % obj(...)
if strcmp(S(1).type, '()')
r = obj.re + 1i*obj.im;
end
end
function obj = subsasgn(obj, S, val) % obj(...) = val
% custom assignment
end
end
end
c1 = Complex(1, 2); c2 = Complex(3, 4);
c3 = c1 + c2; % uses plus
c4 = c1 * c2; % uses mtimes
abs(c1) % uses absDebugging & Performance-Tuning
Debugger & Breakpoints
dbstop setzt Breakpoints – das mächtigste Debugging-Tool. Bedingte Breakpoints (dbstop ... if condition) pausieren nur, wenn ein Prädikat gilt, unerlässlich zum Finden von Bugs in großen Schleifen. dbstop if error macht jede nicht abgefangene Ausnahme zu einer Debug-Pause, sodass man den Workspace am Fehlerpunkt inspizieren kann. Das ME (MException)-Objekt in catch-Blöcken trägt .message, .identifier und .stack für umfangreiches Fehler-Handling. dbstack verwenden, um den Call-Stack zu navigieren, und dbup/dbdown, um Aufrufer-Workspaces zu inspizieren.
% set breakpoints in the Editor or programmatically
dbstop in my_function at 42 % line 42 of my_function.m
dbstop in my_function at 42 if x > 10 % conditional
dbstop if error % pause on any error
dbstop if naninf % pause on NaN/Inf
dbstop if warning % pause on warnings
dbclear all % clear all breakpoints
dbclear in my_function % clear in one file
% at a breakpoint, the command window enters debug mode K>>
whos % inspect workspace
x % view variables
dbstep % step to next line
dbstep in % step into function
dbstep out % step out of function
dbcont % continue execution
dbstack % show call stack
dbup / dbdown % move up/down stack frames
dbquit % exit debug mode
% error recovery
try
risky_operation();
catch ME
fprintf('Error: %s
', ME.message);
fprintf('Stack:
');
for k = 1:numel(ME.stack)
fprintf(' %s (line %d)
', ME.stack(k).name, ME.stack(k).line);
end
endProfiling & Hotspot-Erkennung
Der Profiler (profile on/off + profile viewer) zeigt, wo Zeit verbracht wird, Zeile für Zeile – das wichtigste Tool zur Optimierung. Immer vor dem Optimieren profilen; Intuition über Bottlenecks ist oft falsch. timeit ist genauer als tic/toc für Microbenchmarks, weil es die Funktion mehrmals ausführt und Overhead berücksichtigt. Die -memory-Option verfolgt Allokationen, nützlich zum Finden von Memory-Leaks oder exzessivem Kopieren. Optimierungsaufwand auf die obersten Hot-Lines konzentrieren für maximalen Impact.
% profile a script or function
profile on
my_expensive_script();
profile off
% view results
profile viewer % GUI
p = profile('info'); % structure
profsave(p, 'profile_results'); % HTML report
% time individual operations
tic; A = rand(5000); A = A * A; toc; % ~0.5s
% timeit for accurate single-function timing
f = @() sort(rand(1e6,1));
t = timeit(f);
% memory profiling
profile on -memory
% ... run code ...
profile viewer % shows memory allocation
% identify bottlenecks
% 1. profile viewer shows time per function/line
% 2. focus on the top few hottest lines
% 3. vectorize, preallocate, or use MEX for thoseVektorisierung & Preallocation
Die drei größten Performance-Gewinne in MATLAB: (1) Arrays vorinitialisieren, bevor sie in Schleifen gefüllt werden (zeros, NaN, cell), (2) Operationen vektorisieren, um BLAS/LAPACK zu nutzen, und (3) JIT-freundliche Muster verwenden (einfache Schleifen sind jetzt schnell, aber Array-Wachsen ist immer noch O(n^2)). Logische Indizierung ersetzt if/else-Schleifen durch eine einzige vektorisierte Zuweisung. arrayfun vermeiden, außer wenn GPU-Unterstützung benötigt wird – einfache vorinitialisierte Schleifen sind oft schneller. Mit tic/toc oder timeit messen, um Verbesserungen zu verifizieren.
% BAD: growing array in loop
tic;
s = [];
for k = 1:100000
s = [s, k^2]; % reallocates every iteration!
end
toc; % ~10 seconds
% GOOD: preallocate
tic;
s = zeros(1, 100000);
for k = 1:100000
s(k) = k^2;
end
toc; % ~0.01 seconds
% BEST: vectorize
tic;
s = (1:100000).^2;
toc; % ~0.001 seconds
% vectorize conditional logic
x = rand(10000, 1);
% BAD:
% for k = 1:numel(x)
% if x(k) > 0.5, y(k) = 1; else, y(k) = 0; end
% end
% GOOD:
y = double(x > 0.5);
% vectorize with logical indexing
y = zeros(size(x));
y(x > 0.5) = 1;
y(x > 0.8) = 2;
% use arrayfun/gpuArray only when truly needed
% (loops with preallocation are often faster than arrayfun)MEX-Dateien & C-Integration
MEX-Dateien ermöglichen das Aufrufen von C/C++/Fortran aus MATLAB – unerlässlich, wenn eine kritische Schleife nicht vektorisiert werden kann oder beim Wrappen bestehender Bibliotheken. mex kompiliert eine C-Datei in eine .mexw64 (Windows) oder .mexa64 (Linux)-Binärdatei. Die moderne C++ MATLAB Data API (R2018a+) ist typsicher und sauberer als die alte mxGetPr/mxCreate-API. Zum Aufrufen von MATLAB aus externen Anwendungen die MATLAB Engine API oder MATLAB Compiler SDK verwenden. loadlibrary wrappt generische Shared Libraries ohne Kompilierung. Zuerst profilen – nur den tatsächlichen Bottleneck MEX-ifizieren.
% call C/C++/Fortran code from MATLAB via MEX
% write a C file (my_func.c):
/*
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
double *x = mxGetPr(prhs[0]);
size_t n = mxGetNumberOfElements(prhs[0]);
plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL);
double *y = mxGetPr(plhs[0]);
for (size_t k = 0; k < n; k++) y[k] = x[k] * x[k];
}
*/
% compile
mex my_func.c % produces my_func.mexw64
% usage:
y = my_func([1 2 3]); % [1 4 9]
% C++ with MATLAB Data API (modern, R2018a+)
% #include "mex.hpp", "mexAdapter.hpp"
% use matlab::data::TypedArray<double>
% call MATLAB from C/C++ application (MATLAB Engine API)
% #include "engine.h"
% eng = engOpen("");
% engPutVariable(eng, "x", x);
% engEvalString(eng, "y = sqrt(x)");
% loadlibrary for generic shared libraries
loadlibrary('mylib.dll', 'mylib.h');
calllib('mylib', 'my_function', arg);
unloadlibrary('mylib');Memory-Management & große Daten
Memory ist oft der Bottleneck für große Berechnungen. single statt double verwenden, um Memory zu halbieren und Throughput zu verdoppeln. Sparse-Matrizen speichern nur Nonzeros. memmapfile mappt eine Binärdatei in Memory, ohne sie zu laden – perfekt für riesige Datensätze, die sequenziell zugegriffen werden. tall Arrays (mit datastore) verarbeiten Daten in Chunks, die nicht in den RAM passen, und verwenden MapReduce unter der Haube. Seit R2018b kann MATLAB einige In-Place-Operationen (A = A + 1) ohne Kopieren durchführen, aber explizites A(:) = ... garantiert es. Große Variablen immer aufräumen, wenn fertig.
% check memory usage
[usr, sys] = memory;
disp(usr.PhysicalMemory.Available);
% view variable sizes
whos % all variables with sizes
[x_size, x_bytes] = compute_size(x);
% clear large variables when done
clear big_array;
% use single precision when possible
A = rand(5000, 'single'); % half the memory of double
B = A * A; % single precision matmul
% sparse for mostly-zero matrices
S = sparse(1e5, 1e5);
S(1, 1) = 1;
% memory-mapped files for huge data
m = memmapfile('large.bin', 'Format', 'double', 'Offset', 0, ...
'Repeat', 1e8);
m.Data(1) % access without loading all
% tall arrays for out-of-core
ds = datastore('big.csv');
t = tall(ds);
mean_t = mean(t.Var1);
gather(mean_t); % triggers computation
% avoid copies: in-place operations
A = A + 1; % may modify A in place (since R2018b)
A(:) = A(:) + 1; % definitely in placePlotting Fortgeschritten
Subplots und tiledlayout
tiledlayout (R2019b+) ist der moderne Ersatz für subplot – besserer Abstand, einfacheres Spanning und gemeinsame Titel via title(..., 'tiledtitle'). nexttile([1 2]) spannt über mehrere Kacheln. subplot(n, m, k) funktioniert noch für Legacy-Code, ist aber weniger flexibel.
% tiledlayout (R2019b+) replaces subplot
tiledlayout(2, 3, 'TileSpacing', 'compact', 'Padding', 'compact');
nexttile; plot(1:10);
nexttile; scatter(rand(1, 50), rand(1, 50));
nexttile; bar(rand(5, 3));
nexttile; imagesc(magic(10));
nexttile; histogram(randn(1000, 1), 30);
nexttile; pie([30 20 50]);
% span multiple tiles
nexttile(7, [1 2]); plot(sin(0:0.1:2*pi));
% shared title and labels
title('Dashboard Demo');
xlabel('X'); ylabel('Y');
% legacy subplot
subplot(2, 2, 1); plot(1:10);
subplot(2, 2, 2); plot(10:-1:1);Achsen anpassen
Die meisten Achsen-Properties sind über das Axes-Handle (gca) zugänglich. xlim/ylim setzen Grenzen; xticks/xticklabels steuern Tick-Positionen und -Labels. TeX-Markup wie \pi rendert griechische Buchstaben. set(gca, ...) ist die Legacy-Syntax; ax.Property = value ist das moderne (R2014b+) Äquivalent.
x = linspace(0, 2*pi, 100);
plot(x, sin(x));
% axis limits
xlim([0 2*pi]); ylim([-1.2 1.2]);
% ticks and labels
xticks(0:pi/2:2*pi);
xticklabels({'0', '\pi/2', '\pi', '3\pi/2', '2\pi'});
% grid and minor grid
grid on; grid minor on;
% axis appearance
box on;
ax = gca;
ax.FontSize = 12;
ax.FontName = 'Courier';
ax.LineWidth = 1.5;
ax.XColor = [0.5 0.5 0.5];
ax.YDir = 'reverse';
% log scale
semilogy(1:100, 2.^(1:100));
set(gca, 'YScale', 'log');Mehrere Plots und Legende
hold on ermöglicht das Überlagern mehrerer Plots auf denselben Achsen – immer mit hold off beenden, um Überraschungen zu vermeiden. 'Location', 'best' wählt die am wenigsten überlappende Ecke. Die 'Interpreter', 'latex'-Option ermöglicht vollständiges LaTeX-Mathe. Spezifische Linien-Handles an legend übergeben, um nur einige Plots einzuschließen.
x = linspace(0, 2*pi, 100);
y1 = sin(x); y2 = cos(x); y3 = sin(x) + cos(x);
% hold on for multiple lines
plot(x, y1, 'r-', 'LineWidth', 2); hold on;
plot(x, y2, 'b--', 'LineWidth', 2);
plot(x, y3, 'g:', 'LineWidth', 2); hold off;
% legend with location
legend('sin(x)', 'cos(x)', 'sin+cos', ...
'Location', 'best', 'Orientation', 'horizontal');
% legend with TeX
legend('$\sin(x)$', '$\cos(x)$', 'Interpreter', 'latex');
% specify which lines to include
h1 = plot(x, y1); hold on;
h2 = plot(x, y2);
h3 = plot(x, y3);
legend([h1 h3], 'sin', 'sin+cos');3D-Plotting
surf zeichnet eine gefärbte Oberfläche; mesh zeichnet ein Wireframe. contour und contourf zeigen 2D-Projektionen; clabel fügt Labels hinzu. plot3 zeichnet 3D-parametrische Kurven. view(az, el) setzt den Kamerawinkel (Azimut, Elevation in Grad). shading interp glättet Farbübergänge.
[X, Y] = meshgrid(-2:0.1:2, -2:0.1:2);
Z = X .* exp(-X.^2 - Y.^2);
% surface plot
figure;
surf(X, Y, Z);
colorbar; shading interp;
% mesh plot (wireframe)
figure;
mesh(X, Y, Z);
hidden off; % show hidden lines
% contour
figure;
contour(X, Y, Z, 20); colorbar;
contourf(X, Y, Z, 20); colorbar; % filled
[c, h] = contour(X, Y, Z, 20); clabel(c, h);
% 3D parametric
t = 0:0.01:10;
plot3(sin(t), cos(t), t);
xlabel('x'); ylabel('y'); zlabel('z');
view(45, 30); % azimuth, elevationAnimationen und Filme
Animationen aktualisieren Plot-Daten innerhalb einer Schleife mit drawnow, um zu aktualisieren. Für flüssiges Video VideoWriter verwenden (ersetzt das veraltete avifile). getframe erfasst die aktuelle Figur als Bild. FrameRate vor dem Öffnen des Videos setzen. Immer close(v) aufrufen, wenn fertig, um die Datei zu flushen.
% animate a sine wave
figure;
h = plot(NaN, NaN);
xlim([0 2*pi]); ylim([-1 1]);
for k = 1:100
x = linspace(0, 2*pi, k);
set(h, 'XData', x, 'YData', sin(x));
drawnow;
end
% capture frames and save as video
v = VideoWriter('animation.mp4', 'MPEG-4');
v.FrameRate = 30; open(v);
for k = 1:60
plot(sin(0:0.1:k/10));
frame = getframe(gcf);
writeVideo(v, frame);
end
close(v);
% getframe for static snapshots
figure; plot(1:10);
frame = getframe; % struct with cdataMatrix-Operationen Deep
Lineare Algebra Grundlagen
Immer A\b (Backslash) verwenden, um lineare Systeme zu lösen – es dispatcht zur richtigen Faktorisierung (LU, Cholesky, QR) basierend auf der Matrix. inv(A)*b ist langsamer und numerisch schlechter. eig gibt Eigenvektoren als Spalten von V und Eigenwerte auf der Diagonalen von D zurück. expm ist die Matrix-Exponentialfunktion (anders als elementweises exp).
A = [1 2; 3 4];
b = [5; 6];
% solve Ax = b
x = A \ b; % preferred (LU-based)
x = inv(A) * b; % avoid — slower, less stable
% factorizations
[L, U, P] = lu(A); % PA = LU
[Q, R] = qr(A); % A = QR
[V, D] = eig(A); % A V = V D
[U, S, V] = svd(A); % A = U S V'
% properties
det(A); trace(A); rank(A); cond(A);
null(A); % null space
orth(A); % orthonormal basis of range
% matrix functions
expm(A); logm(A); sqrtm(A); % matrix (not element-wise)Elementweise vs Matrix-Operationen
Das Dot-Präfix (.*) bedeutet elementweise; ohne es sind Operationen Matrix-Operationen. Der häufigste MATLAB-Bug: x*x, wo x ein Zeilenvektor ist – x*x' für Skalarprodukt oder x.*x für elementweises Quadrat verwenden. ' ist konjugierte Transposition (kehrt Vorzeichen der Imaginärteile um); .' ist einfache Transposition.
A = [1 2; 3 4];
B = [5 6; 7 8];
% element-wise (use .)
A .* B % [5 12; 21 32]
A ./ B % element-wise divide
A .^ 2 % [1 4; 9 16]
A .^ B % element-wise power
% matrix ops (no .)
A * B % matrix product
A / B % A * inv(B)
A \ B % inv(A) * B
A^2 % A * A (matrix power)
A' % conjugate transpose
A.' % non-conjugate transpose
% common gotcha
x = [1 2 3];
x * x % ERROR: inner dims mismatch
x * x' % 14 (dot product)
x .* x % [1 4 9] (element-wise)Reshaping und Indizierung
MATLAB speichert Matrizen spaltenmajor, also ist A(5) in einer 4x4 A(1, 2). Logische Indizierung (A(mask)) ist mächtig und schnell – Elemente extrahieren oder modifizieren, die einer Bedingung entsprechen, ohne Schleifen. reshape erfordert, dass die Gesamtanzahl der Elemente übereinstimmt. permute verallgemeinert Transposition auf N-D-Arrays.
A = magic(4); % 4x4 matrix
% linear indexing (column-major)
A(5) % A(1, 2)
A(:) % column vector of all elements
A(2:5) % elements 2-5
% submatrix
A(1:2, 2:4) % rows 1-2, cols 2-4
A(:, 3) % all rows, col 3
A(end, :) % last row
A(1:2:end, :) % odd rows (stride)
% logical indexing
mask = A > 10;
A(mask) % flat list of values > 10
A(A > 10) = 0; % threshold in-place
% reshape, permute, flip
B = reshape(A, 2, 8);
C = permute(A, [2 1]); % transpose N-D
flip(A); flipud(A); fliplr(A);
repmat(A, 2, 3); % tile 2x3Sparse-Matrizen
Sparse-Matrizen speichern nur Nonzero-Elemente – unerlässlich für große Matrizen, die meist Null sind (z.B. aus PDE-Diskretisierungen). Operationen erhalten Sparsity, wenn möglich. Der Backslash S\b verwendet einen Sparse-Direct-Solver (UMFPACK) – viel schneller und memory-effizienter als full()\b für große Sparse-Systeme. spy visualisiert das Sparsity-Muster.
% create sparse
S = sparse(1000, 1000);
S(1, 1) = 5;
S(500, 500) = 10;
% from triplets
i = [1 2 3 4];
j = [1 2 3 4];
v = [10 20 30 40];
S = sparse(i, j, v, 4, 4);
% sparse identity and diagonal
S = speye(1000);
S = spdiags(ones(1000, 1), 0, 1000, 1000);
% operations stay sparse
S = S + S';
S = S * S;
x = S \ b; % uses sparse solver
% convert
F = full(S); % sparse -> full
S = sparse(F); % full -> sparse
nnz(S) % count non-zeros
spy(S) % visualize sparsityBroadcasting (implizite Expansion)
Seit R2016b broadcastet MATLAB automatisch (wie NumPy) – Dimensionen der Größe 1 expandieren, um zu passen. Vorher brauchte man bsxfun. Broadcasting macht Code sauberer: M - mean(M, 2) zentriert jede Zeile ohne repmat. Dimensionen müssen kompatibel sein (gleich oder eine davon ist 1).
% R2016b+ — automatic broadcasting
A = magic(3); % 3x3
b = [1 2 3]; % 1x3
% older MATLAB: error (dims mismatch)
% modern MATLAB: b is broadcast across rows
C = A + b; % 3x3 result
C = A - b';
C = A .* b;
% common uses
x = (1:5)'; % column
y = (1:5); % row
outer = x * y; % 5x5 outer product
grid = x + y; % 5x5 addition grid
% mean across rows
M = magic(5);
row_means = mean(M, 2); % 5x1
centered = M - row_means; % broadcast subtraction
% bsxfun (legacy, pre-R2016b)
C = bsxfun(@plus, A, b); % same as A + bCell Arrays & Structs
Cell Arrays
Cell Arrays halten gemischte Typen. {} verwenden, um auf Inhalte zuzugreifen (droppt die Cell-Wrapper) und () für eine Sub-Cell. cellfun wendet eine Funktion auf jede Cell an – 'UniformOutput', false übergeben, wenn Ergebnisse heterogen sind. Cell Arrays sind der Standardweg, Strings unterschiedlicher Länge zu halten (vor String-Arrays).
% heterogeneous container
C = {'hello', 42, [1 2 3], magic(3)};
% access
C{1} % 'hello' (contents)
C(1) % {1x1 cell} (cell)
C{4}(2, 2) % access inside
% build dynamically
C = {};
for k = 1:5
C{k} = rand(k);
end
% multi-element
[a, b, c] = C{1:3}; % unpack
C{1:3} % comma-separated list
% cellfun
nums = {1, 2, 3, 4};
squared = cellfun(@(x) x^2, nums);
lengths = cellfun(@length, C);
% convert
cell([1 2 3]) % {1, 2, 3}
cell2mat({1 2; 3 4}) % [1 2; 3 4]
mat2cell(magic(4), [2 2], [2 2]) % 2x2 cell of blocksStruct-Arrays
Structs gruppieren benannte Felder beliebigen Typs. Struct-Arrays halten mehrere Datensätze – {arr.field} sammelt ein Feld über alle Elemente in eine Cell, [arr.field] in ein reguläres Array (wenn kompatibel). Verschachtelte Felder verwenden Dot-Chaining. fieldnames listet Felder; rmfield gibt eine Kopie ohne das Feld zurück.
% scalar struct
s.name = 'Alice';
s.age = 30;
s.scores = [90 85 92];
% struct constructor
s = struct('name', 'Bob', 'age', 25, 'scores', {[80 70]});
% struct array
students(1).name = 'Alice';
students(1).age = 30;
students(2).name = 'Bob';
students(2).age = 25;
% access across array
names = {students.name}; % all names (cell)
ages = [students.age]; % all ages (vector)
% nested
s.course.code = 'CS101';
s.course.credits = 3;
s.course.instructor.name = 'Dr. Smith';
% field operations
fieldnames(s) % list fields
isfield(s, 'age') % check field
rmfield(s, 'age') % remove field
orderfields(s) % sort fieldsTables (tabellarische Daten)
Tables (R2013b+) sind der moderne Weg, tabellarische Daten zu halten – wie ein DataFrame in pandas. Auf Spalten nach Namen zugreifen (T.Age) oder per Index (T.(2)). sortrows sortiert nach einer oder mehreren Spalten. readtable/writetable behandeln CSV, Excel usw. summary gibt Statistiken pro Spalte. Tables gegenüber rohen Matrizen für heterogene Daten bevorzugen.
% create table
Names = {'Alice'; 'Bob'; 'Carol'};
Age = [30; 25; 42];
Score = [90; 80; 95];
T = table(Names, Age, Score);
% access
T.Age % column as vector
T.(2) % column by index
T{1, 2} % row 1, col 2 (cell-style)
T(1:2, :) % first 2 rows
% add/remove columns
T.Grade = {'A'; 'B'; 'A'};
T.Grade = []; % remove column
% filtering
T(T.Age > 26, :) % rows where Age > 26
find(T.Age > 26);
% sorting
T = sortrows(T, 'Age');
T = sortrows(T, {'Age', 'Score'}, 'descend');
% summary
summary(T)
T.Properties.VariableNames
% read/write
T = readtable('data.csv');
writetable(T, 'out.csv')Timetables
Timetables (R2016b+) sind Tables mit Zeilen-Zeitstempeln. retime resampelt/aggregiert (z.B. 'hourly', 'daily' oder benutzerdefinierter TimeStep). synchronize richtet mehrere Timetables an einem gemeinsamen Zeitvektor aus. lag/lead verschieben Spalten. Viel sauberer als manuelles Verwalten von Zeit-Indizes in Matrizen.
% create timetable with timestamps
Time = datetime(2024, 1, 1) + hours(0:23)';
Temp = 20 + 5 * randn(24, 1);
TT = timetable(Time, Temp);
% indexing by time
TT.timerange(datetime(2024,1,1,6,0,0), datetime(2024,1,1,12,0,0))
TT(datetime(2024,1,1,10,0,0), :) % row at specific time
TT('2024-01-01 10:00:00', :)
% resample / synchronize
TT_30min = retime(TT, 'regular', 'mean', 'TimeStep', minutes(30));
TT_hourly = retime(TT, 'hourly', 'mean');
% aggregate
TT_daily = retime(TT, 'daily', @mean);
TT_daily_max = retime(TT, 'daily', 'max');
% combine timetables
TT2 = synchronize(TT1, TT2, 'union');
% lagging
TT.PrevTemp = lag(TT.Temp, 1);Maps (Wörterbücher)
containers.Map ist die Legacy-Hash-Map – funktioniert in allen MATLAB-Versionen, ist aber langsamer und untypisiert. dictionary (R2022b+) ist der moderne Ersatz: typisiert, schneller und unterstützt vektorisiertes Lookup. Maps verwenden, wenn O(1)-Key-Lookup statt Durchsuchen eines Struct-Arrays oder Cell benötigt wird.
% containers.Map (pre-R2022b)
m = containers.Map;
m('apple') = 1;
m('banana') = 2;
m('cherry') = 3;
% access
m('apple') % 1
m.Keys % {'apple', 'banana', 'cherry'}
m.Values % [1, 2, 3]
isKey(m, 'apple') % true
remove(m, 'banana');
% iterate
keys = m.keys;
for k = 1:length(keys)
fprintf('%s -> %d\n', keys{k}, m(keys{k}));
end
% R2022b+ dictionary (faster, typed)
d = dictionary({'apple', 'banana'}, [1, 2]);
d('cherry') = 3;
d('apple') % 1
keys(d); values(d)Optimierung
fmincon beschränkte Optimierung
fmincon ist das Arbeitspferd für beschränkte nichtlineare Minimierung. Die nonlcon-Funktion muss [c, ceq] zurückgeben, wobei c <= 0 (Ungleichheit) und ceq = 0 (Gleichheit). deal ist ein sauberer Weg, mehrere Ausgaben aus einer anonymen Funktion zurückzugeben. Algorithmus basierend auf Problemtyp setzen: 'interior-point' (allgemein), 'sqp' (klein/mittel, oft schneller).
% minimize objective with constraints
% min f(x) s.t. A*x <= b, Aeq*x = beq, lb <= x <= ub, c(x) <= 0, ceq(x) = 0
fun = @(x) (x(1) - 2)^2 + (x(2) - 3)^2;
% linear inequality: x1 + x2 <= 4
A = [1 1]; b = 4;
% linear equality: x1 - x2 = 0
Aeq = [1 -1]; beq = 0;
% bounds
lb = [0 0]; ub = [5 5];
% nonlinear: x1^2 + x2^2 >= 1 (so -(x1^2 + x2^2 - 1) <= 0)
nonlcon = @(x) deal(-(x(1)^2 + x(2)^2 - 1), []);
x0 = [1 1];
[x, fval, exitflag, output] = fmincon(fun, x0, A, b, Aeq, beq, lb, ub, nonlcon);
% options
opts = optimoptions('fmincon', 'Display', 'iter', ...
'Algorithm', 'interior-point');
[x, fval] = fmincon(fun, x0, A, b, Aeq, beq, lb, ub, nonlcon, opts);fminunc unbeschränkt
fminunc minimiert unbeschränkte nichtlineare Funktionen. Bereitstellen des Gradienten (via SpecifyObjectiveGradient) verbessert Geschwindigkeit und Genauigkeit dramatisch. Die Standard-BFGS-Hessian-Approximation funktioniert gut für glatte Probleme; für große 'lbfgs' verwenden, um Memory zu begrenzen. exitflag prüfen (>0 = konvergiert) und firstorderopt (sollte winzig sein).
% unconstrained minimization
fun = @(x) 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2; % Rosenbrock
x0 = [-1.2 1];
[x, fval, flag, out] = fminunc(fun, x0);
% with gradient (faster, more accurate)
syms x1 x2
f = 100*(x2 - x1^2)^2 + (1 - x1)^2;
grad = gradient(f, [x1, x2]);
fun_grad = matlabFunction(f, grad, 'Vars', {x1, x2});
opts = optimoptions('fminunc', 'SpecifyObjectiveGradient', true, ...
'Display', 'iter');
[x, fval] = fminunc(@(x) fun_grad(x(1), x(2)), x0, opts);
% check optimality
disp(out.firstorderopt) % should be near 0
% Hessian option
opts.Hessian = 'bfgs'; % quasi-Newton (default)
opts.Hessian = 'lbfgs'; % for large sparse problemslinprog Lineare Programmierung
linprog löst lineare Programme. Für Integer-/Binärvariablen intlinprog verwenden (ersetzt das veraltete bintprog). intcon listet, welche Variablen ganzzahlig beschränkt sind. lb=0, ub=1 für binär setzen. Der Dual-Simplex-Algorithmus ist Standard und am schnellsten für die meisten Probleme.
% min f'*x s.t. A*x <= b, Aeq*x = beq, lb <= x <= ub
% example: min -x1 - 2*x2
% s.t. x1 + x2 <= 4
% x1 + 3*x2 <= 6
% x1, x2 >= 0
f = [-1; -2];
A = [1 1; 1 3];
b = [4; 6];
lb = [0; 0];
opts = optimoptions('linprog', 'Display', 'iter');
[x, fval, exitflag, output] = linprog(f, A, b, [], [], lb, [], opts);
% integer programming (intlinprog)
intcon = 1:2; % variables 1 and 2 are integers
[x, fval] = intlinprog(f, intcon, A, b, [], [], lb, []);
% binary variables: set lb=0, ub=1, and add to intcon
lb = [0; 0]; ub = [1; 1];
[x, fval] = intlinprog(f, intcon, A, b, [], [], lb, ub);lsqcurvefit und Kurvenanpassung
lsqcurvefit passt parametrische Modelle an Daten via Least Squares an. polyfit ist die einfache Wahl für Polynome. Für R² (Bestimmtheitsmaß) manuell berechnen: 1 - SSE/SST. Der Levenberg-Marquardt-Algorithmus ist gut für unbeschränkte Probleme; trust-region-reflective behandelt Bounds.
% fit y = a*exp(b*x) to data
xdata = linspace(0, 5, 50)';
ydata = 2.5 * exp(-0.7 * xdata) + 0.05 * randn(50, 1);
model = @(p, x) p(1) * exp(p(2) * x);
x0 = [1, -1];
[params, resnorm, residual, exitflag] = lsqcurvefit(model, x0, xdata, ydata);
% with bounds
lb = [0, -5]; ub = [10, 0];
[params, resnorm] = lsqcurvefit(model, x0, xdata, ydata, lb, ub);
% polyfit for polynomials
p = polyfit(xdata, ydata, 3); % cubic
yfit = polyval(p, xdata);
% fit with custom output
opts = optimoptions('lsqcurvefit', 'Display', 'off', ...
'Algorithm', 'levenberg-marquardt');
[params, resnorm] = lsqcurvefit(model, x0, xdata, ydata, [], [], opts);
% goodness of fit
sse = sum((ydata - model(params, xdata)).^2);
sst = sum((ydata - mean(ydata)).^2);
r2 = 1 - sse / sst;Globale Optimierung
Globale Optimierungs-Tools (in der Global Optimization Toolbox) helfen bei nicht-konvexen Problemen, wo lokale Solver stecken bleiben. MultiStart führt einen lokalen Solver von vielen zufälligen Starts aus. GlobalSearch ist intelligenter – es filtert vielversprechende Starts. ga (genetischer Algorithmus) und simulannealbnd sind derivatfrei. patternsearch ist gut für nicht-glatte Probleme.
% MultiStart: run local solver from many points
fun = @(x) x(1)^2 + x(2)^2 + 10*sin(x(1)) + 10*sin(x(2));
ms = MultiStart('Display', 'iter');
opts = optimoptions('fmincon', 'Algorithm', 'interior-point');
problem = createOptimProblem('fmincon', 'objective', fun, ...
'x0', [0 0], 'lb', [-5 -5], 'ub', [5 5]);
[x, fval] = run(ms, problem, 50); % 50 starting points
% GlobalSearch: smarter, fewer starts
gs = GlobalSearch;
[x, fval] = run(gs, problem);
% ga (genetic algorithm)
[x, fval] = ga(fun, 2, [], [], [], [], [-5 -5], [5 5]);
% simulannealbnd (simulated annealing)
[x, fval] = simulannealbnd(fun, [0 0], [-5 -5], [5 5]);
% patternsearch
[x, fval] = patternsearch(fun, [0 0]);Bildverarbeitung
Bilder lesen und anzeigen
imread gibt uint8-Arrays für die meisten Bildformate zurück. rgb2gray konvertiert RGB zu Graustufen. im2double skaliert zu [0, 1] – dies (nicht double()) vor Float-Verarbeitung verwenden. imshow auto-skaliert Double-Bilder: [0, 1] ist der erwartete Bereich. imwrite unterstützt Qualitäts-/Kompressionsoptionen.
% read and display
img = imread('photo.jpg');
imshow(img);
% info
size(img) % rows x cols x channels
class(img) % usually uint8
imfinfo('photo.jpg') % metadata
% convert types
gray = rgb2gray(img); % RGB -> gray
img_double = im2double(img); % uint8 [0,255] -> double [0,1]
img_uint8 = im2uint8(img_double);
% write
imwrite(gray, 'gray.png');
imwrite(img, 'compressed.jpg', 'Quality', 80);
% display multiple
figure;
subplot(1, 2, 1); imshow(img); title('Original');
subplot(1, 2, 2); imshow(gray); title('Grayscale');
% pixel info
impixelinfo; % interactive pixel values
img(100, 200, :) % pixel at (row, col)Filterung und Faltung
imgaussfilt ist der moderne Gauß-Blur (ersetzt fspecial('gaussian') + imfilter). medfilt2 ist die richtige Wahl für Salt-and-Pepper-Rauschen (Mean-Filter verwischt es nur). fspecial erstellt häufige Kernel (sobel, prewitt, laplacian, gaussian, disk, motion). imfilter macht standardmäßig Korrelation – 'conv' für echte Faltung übergeben.
img = imread('cameraman.tif');
img = im2double(img);
% Gaussian blur
blurred = imgaussfilt(img, 2); % sigma = 2
blurred = imgaussfilt(img, 2, 'FilterSize', 7);
% median filter (great for salt-and-pepper noise)
noisy = imnoise(img, 'salt & pepper', 0.05);
denoised = medfilt2(noisy, [3 3]);
% custom kernel
h = fspecial('sobel'); % edge detection
edges = imfilter(img, h);
h = fspecial('laplacian', 0);
sharpened = img - imfilter(img, h);
% 2D convolution vs correlation
out_conv = imfilter(img, h, 'conv');
out_corr = imfilter(img, h, 'corr'); % default
% unsharp masking
sharp = imsharpen(img, 'Amount', 1.5, 'Radius', 2);Morphologische Operationen
Morphologische Operationen arbeiten auf binären Bildern. Erode schrumpft Objekte; dilate vergrößert sie. Open (erode dann dilate) entfernt kleines Rauschen; close (dilate dann erode) füllt kleine Lücken. strel erstellt strukturierende Elemente – disk/square/line/octagon. bwareaopen entfernt kleine Objekte; imfill füllt Löcher; bwperim extrahiert Grenzen.
bw = imread('text.png');
bw = imbinarize(bw); % grayscale -> binary
% basic ops
eroded = imerode(bw, strel('square', 3));
dilated = imdilate(bw, strel('disk', 2));
opened = imopen(bw, strel('square', 5));
closed = imclose(bw, strel('square', 5));
% structuring elements
se = strel('square', 3);
se = strel('disk', 5);
se = strel('line', 10, 45); % length 10, angle 45 deg
se = strel('octagon', 3);
% remove small objects
clean = bwareaopen(bw, 50); % remove <50 pixels
% skeleton
skel = bwmorph(bw, 'skel', Inf);
% fill holes
filled = imfill(bw, 'holes');
% boundary
boundary = bwperim(bw);Kantenerkennung und Segmentierung
edge mit 'canny' ist der robusteste Kantendetektor ([low high]-Schwellenwerte und Sigma angeben). imbinarize mit 'adaptive' behandelt ungleichmäßige Beleuchtung. bwconncomp findet verbundene Komponenten; regionprops extrahiert Messungen (Area, Centroid, BoundingBox usw.). watershed trennt sich berührende Objekte – auf dem Gradient berechnen, um Grenzen zu finden.
img = imread('coins.png');
img = im2double(img);
% edges
edges_sobel = edge(img, 'sobel');
edges_canny = edge(img, 'canny', [0.1 0.2], 1.5);
edges_prewitt = edge(img, 'prewitt');
% thresholding
bw = imbinarize(img);
bw_otsu = imbinarize(img, 'adaptive'); % local threshold
% connected components
cc = bwconncomp(bw);
stats = regionprops(cc, 'Area', 'Centroid', 'BoundingBox');
areas = [stats.Area];
[~, idx] = sort(areas, 'descend');
biggest = stats(idx(1));
% watershed segmentation
grad = imgradient(img);
L = watershed(grad);
L(L == 0) = NaN;
imshow(img); hold on; imshow(L, []);Farbe und Transformationen
rgb2hsv, rgb2lab konvertieren Farbräume – HSV ist intuitiv für Farbauswahl; L*a*b* trennt Luminanz von Farbe (gut für Farbunterschied). fft2 + fftshift zentrieren das Spektrum zum Filtern. imresize/imrotate/imcrop sind geometrische Operationen – 'bilinear' (Standard) ist meistens am besten; 'nearest' ist am schnellsten, aber blockig.
img = imread('peppers.png');
% color space conversion
hsv = rgb2hsv(img);
lab = rgb2lab(img);
gray = rgb2gray(img);
rgb = hsv2rgb(hsv);
% extract channels
R = img(:, :, 1);
G = img(:, :, 2);
B = img(:, :, 3);
% Fourier transform
f = fft2(double(gray));
f = fftshift(f); % center zero freq
mag = log(1 + abs(f));
imshow(mag, []);
% inverse
f_filtered = f;
f_filtered(abs(f) < 100) = 0; % low-pass filter
filtered = real(ifft2(ifftshift(f_filtered)));
imshow(filtered, []);
% resize, rotate
small = imresize(img, 0.5);
rotated = imrotate(img, 45, 'bilinear', 'crop');
cropped = imcrop(img, [50 50 200 150]); % [x y w h]GUI/App Designer
App Designer Grundlagen
App Designer (R2016a+) ist das moderne GUI-Tool, das GUIDE ersetzt. Komponenten werden über app.<Name> zugegriffen. Callbacks erhalten (app, event). Benutzerdefinierte Properties (in der Code View) teilen Zustand zwischen Callbacks. Als .mlapp (binär) speichern oder zu .m exportieren. Durch Eingeben des App-Namens im Command Window ausführen.
% Open App Designer:
% >> appdesigner
% Drag components from the left, set properties on the right.
% Callback structure (auto-generated):
function ButtonPushed(app, event)
x = linspace(0, 2*pi, 100);
plot(app.UIAxes, x, sin(x));
app.ResultEditField.Value = 'Plot done';
end
% Access components via app.<ComponentName>
% app.UIAxes, app.Button, app.EditField, app.Slider, ...
% Property panel: add custom properties
properties (Access = private)
data; % shared between callbacks
end
% Startup callback:
function startupFcn(app)
app.data = rand(10);
app.Slider.Value = 50;
end
% Save as .mlapp, run with:
% >> myApp (if named myApp.mlapp)
% Or export to a standalone .m file.Programmatische UI mit uifigure
uifigure (R2016b+) ist das moderne programmatische UI-Framework – unterstützt moderne Widgets (gauge, knob, switch, tree), die figure nicht bietet. Callbacks via *Fcn-Properties mit anonymen Funktionen @(src, event) ... setzen. uiwait blockiert, bis die Figur schließt; uiresume gibt sie frei.
% modern uifigure (R2016b+) — preferred
fig = uifigure('Name', 'My App', 'Position', [100 100 600 400]);
ax = uiaxes(fig, 'Position', [200 100 350 250]);
plot(ax, 1:10);
btn = uibutton(fig, 'Text', 'Plot', 'Position', [50 100 100 30]);
btn.ButtonPushedFcn = @(~,~) plot(ax, rand(1, 10));
slider = uislider(fig, 'Position', [50 200 100 3]);
slider.ValueChangedFcn = @(s,~) disp(s.Value);
% dropdown
dd = uidropdown(fig, 'Items', {'a', 'b', 'c'}, 'Position', [50 250 100 30]);
dd.ValueChangedFcn = @(s,~) fprintf('Selected: %s\n', s.Value);
% list box
lb = uilistbox(fig, 'Items', {'one', 'two', 'three'}, ...
'Multiselect', 'on', 'Position', [50 50 100 80]);
% wait for user to close
uiwait(fig);Häufige UI-Komponenten
Moderne UI-Komponenten: uieditfield (Text oder numerisch), uibuttongroup (verwaltet Radio-Buttons), uicheckbox, uitable (bindet an eine Table), uitabgroup/uitab (Tabs). Alle nehmen einen Parent als erstes Argument und verwenden Name-Value-Paare für Properties. Callbacks feuern bei Benutzerinteraktion; neue Werte über das source-Argument abrufen.
fig = uifigure;
% label
lbl = uilabel(fig, 'Text', 'Enter value:', 'Position', [20 200 100 22]);
% edit field
ef = uieditfield(fig, 'numeric', 'Value', 42, 'Position', [130 200 100 22]);
ef.ValueChangedFcn = @(s,~) fprintf('New: %g\n', s.Value);
% button group with radio buttons
bg = uibuttongroup(fig, 'Title', 'Mode', 'Position', [20 100 200 80]);
r1 = uiradiobutton(bg, 'Text', 'A', 'Position', [10 40 100 22]);
r2 = uiradiobutton(bg, 'Text', 'B', 'Position', [10 10 100 22]);
r1.Value = true;
% check box
cb = uicheckbox(fig, 'Text', 'Enable', 'Position', [20 50 100 22]);
% table
tdata = table({'A'; 'B'}, [1; 2], 'VariableNames', {'Name', 'Value'});
uit = uitable(fig, 'Data', tdata, 'Position', [250 50 200 150]);
% tab group
tg = uitabgroup(fig);
t1 = uitab(tg, 'Title', 'Tab 1');
t2 = uitab(tg, 'Title', 'Tab 2');
plot(uiaxes(t1), 1:10);Dialoge und Prompts
inputdlg sammelt Texteingabe; questdlg für Ja/Nein/Abbrechen; listdlg für Auswahl; uigetfile/uiputfile für Datei-Picker; msgbox/errordlg/warndlg für Benachrichtigungen. fullfile fügt Pfade portabel zusammen (besser als String-Konkatenation). Immer prüfen, dass der Benutzer nicht abgebrochen hat (leere Rückgabe oder ok == false).
% input dialog
answer = inputdlg({'Name:', 'Age:'}, 'User Info', [1 50; 1 10]);
if ~isempty(answer)
name = answer{1};
age = str2double(answer{2});
end
% question dialog
btn = questdlg('Save changes?', 'Confirm', 'Yes', 'No', 'Cancel', 'Yes');
switch btn
case 'Yes', save_data();
case 'No', % discard
case 'Cancel', return;
end
% list dialog
[sel, ok] = listdlg('PromptString', 'Select items:', ...
'ListString', {'Apple', 'Banana', 'Cherry'}, ...
'SelectionMode', 'multiple');
% file dialogs
[file, path] = uigetfile('*.csv', 'Select CSV');
[file, path] = uiputfile('*.mat', 'Save as');
fullpath = fullfile(path, file);
% message dialog
msgbox('Done!', 'Info', 'help');
errordlg('Something went wrong', 'Error');
warndlg('Check this', 'Warning');Teilen und Deployment
Zum Teilen: .mlapp-Dateien erfordern MATLAB; Standalone-Apps (via MATLAB Compiler) laufen ohne MATLAB, benötigen aber die kostenlose MATLAB Runtime; Web-Apps laufen in einem Browser via MATLAB Web App Server. Export zu .m gibt lesbaren Quellcode. Als Toolbox für Distribution via Add-Ons paketieren.
% Run as standalone app
% 1. In App Designer: Designer Tab > App Store Details > Save as .mlapp
% 2. Share the .mlapp file — others open it in MATLAB
% Create standalone app (requires MATLAB Compiler)
% >> mcr.build('myApp.mlapp') % R2024a+
% or
% >> deploytool % legacy
% Web App (requires MATLAB Web App Server)
% >> compiler.build.webApp('myApp.mlapp')
% Export to code (readable .m)
% In App Designer: Designer Tab > Export > Export to .m file
% Pack as toolbox (for sharing with colleagues)
% >> matlab.addons.toolbox.packageToolbox('myApp.prj)
% Tips:
% - Use try/catch in callbacks to avoid silent failures
% - Set app.UIFigure.Name to identify your app
% - Test on a clean MATLAB session before deployingDatei-I/O Fortgeschritten
Low-Level-Datei-I/O
fopen gibt -1 bei Fehlern zurück – immer prüfen. fgetl liest eine Zeile ohne Newline; fgets behält sie. fscanf liest formatierte Daten; fread liest binär. fseek/ftell navigieren. Immer fclose, wenn fertig (onCleanup für Sicherheit verwenden: c = onCleanup(@() fclose(fid));).
fid = fopen('data.txt', 'r'); % r, w, a, r+, w+
if fid == -1; error('Cannot open file'); end
% read line by line
while ~feof(fid)
line = fgetl(fid); % without newline
fprintf('%s\n', line);
end
% formatted read
% data.txt: "Alice 30 90.5"
A = fscanf(fid, '%s %d %f', [3 1]);
% formatted write
fprintf(fid, '%s, %d, %.2f\n', 'Bob', 25, 85.3);
% binary I/O
data = fread(fid, [10 5], 'double'); % 10x5 doubles
fwrite(fid, data, 'double');
% position
fseek(fid, 0, 'bof'); % beginning
fseek(fid, 0, 'eof'); % end
pos = ftell(fid);
fclose(fid); % ALWAYS closetextscan für gemischte Daten
textscan ist flexibler als fscanf – behandelt gemischte Typen, benutzerdefinierte Delimiter und gibt ein Cell-Array von Spalten zurück. 'TreatAsEmpty' konvertiert Platzhalter zu NaN. 'CollectOutput' gruppiert gleichartige Spalten in ein Array. fileread liest die ganze Datei als String – praktisch für kleine Dateien oder Regex-Verarbeitung.
fid = fopen('data.csv', 'r');
% skip header line
header = fgetl(fid);
% parse remaining
% Format: Alice,30,90.5,B+
C = textscan(fid, '%s %d %f %s', ...
'Delimiter', ',', ...
'MultipleDelimsAsOne', true, ...
'TreatAsEmpty', {'NA', 'N/A'}, ...
'HeaderLines', 0);
fclose(fid);
names = C{1}; ages = C{2}; scores = C{3}; grades = C{4};
% alternative: read whole file at once
str = fileread('data.txt');
% from string
C = textscan('1 2 3\n4 5 6', '%d %d %d');
% C{1} = [1; 4], C{2} = [2; 5], C{3} = [3; 6]
% collectoutput (group columns of same type)
C = textscan(fid, '%s %d %d %f', 'CollectOutput', true);
% C{2} = [ages, more_ints] as one matrixMAT-Dateien und save/load
save/load mit .mat-Dateien erhalten Variablentypen und -struktur. -v7.3 unterstützt Dateien > 2GB (und ist Standard in modernem MATLAB). -append fügt Variablen hinzu ohne neu zu schreiben. Für riesige Dateien nur nach Namen laden, was benötigt wird. Für Textexport -ascii (begrenzt) oder writematrix/writetable für mehr Kontrolle verwenden.
A = magic(5);
B = struct('name', 'Alice', 'age', 30);
C = rand(100);
% save variables
save('data.mat', 'A', 'B', 'C');
save('data.mat', 'A', 'B', '-v7.3'); % large files > 2GB
save('data.mat', '-append', 'C'); % add to existing
% load
loaded = load('data.mat'); % struct with variables
loaded.A
loaded.B.age
% or load into workspace
load('data.mat'); % A, B, C now in workspace
% partial load (huge files)
info = whos('-file', 'bigdata.mat');
loaded = load('bigdata.mat', 'A'); % only A
% save specific format
save('data.txt', 'A', '-ascii', '-double');
save('data.csv', 'A', '-ascii', '-delimiter', ',');
% compressed
save('data.mat', 'A', '-v7.3', '-nocompression');HDF5 und wissenschaftliche Formate
HDF5 ist der Standard für große numerische Datensätze – unterstützt Chunking, Kompression und erweiterbare Dimensionen. h5read mit start/count ermöglicht das Lesen von Slices ohne die ganze Datei zu laden. NetCDF ist häufig in Klima-/Ozeanwissenschaft; FITS in Astronomie. MATLAB unterstützt auch TIFF, DICOM, Audio- und Videoformate nativ.
% HDF5 (great for large scientific datasets)
% write
h5create('data.h5', '/dataset1', [100 50 20]);
data = rand(100, 50, 20);
h5write('data.h5', '/dataset1', data);
% read
info = h5info('data.h5');
data = h5read('data.h5', '/dataset1');
partial = h5read('data.h5', '/dataset1', [1 1 1], [10 10 5]);
% append (extendable datasets)
h5create('data.h5', '/growable', [100 Inf], 'ChunkSize', [100 100]);
for k = 1:5
h5write('data.h5', '/growable', rand(100, 100), [1 (k-1)*100+1]);
end
% NetCDF (climate/ocean data)
ncid = netcdf.open('data.nc', 'NC_NOWRITE');
varid = netcdf.inqVarID(ncid, 'temperature');
data = netcdf.getVar(ncid, varid);
netcdf.close(ncid);
% FITS (astronomy)
fitsdisp('image.fits');
data = fitsread('image.fits');JSON und XML
jsonencode/jsondecode (R2016b+) behandeln JSON nativ. Structs werden JSON-Objekte; Cell-Arrays werden Arrays. Für XML gibt xmlread ein Java-DOM-Objekt zurück – Java-Methoden zum Traversieren verwenden. xmlwrite serialisiert ein DOM zurück in eine Datei. Für komplexes XML das Drittanbieter-xml2struct oder die DOM-API direkt in Betracht ziehen.
% JSON (R2016b+)
data = struct('name', 'Alice', 'age', 30, 'scores', [90 80 85]);
txt = jsonencode(data, 'PrettyPrint', true);
disp(txt);
decoded = jsondecode(txt);
decoded.name % 'Alice'
% JSON with cell arrays for mixed types
data = struct('items', {{'apple', 42, [1 2 3]}});
txt = jsonencode(data);
% read JSON file
txt = fileread('config.json');
config = jsondecode(txt);
% XML
doc = xmlread('data.xml');
root = doc.getDocumentElement;
children = root.getChildNodes;
for k = 0:children.getLength - 1
node = children.item(k);
if node.getNodeType == doc.ELEMENT_NODE
fprintf('%s: %s\n', node.getNodeName, char(node.getTextContent));
end
end
% write XML
doc = com.mathworks.xml.XMLUtils.createDocument('root');
root = doc.getDocumentElement;
child = doc.createElement('item');
child.appendChild(doc.createTextNode('hello'));
root.appendChild(child);
xmlwrite('out.xml', doc);Paralleles Rechnen
parfor-Schleifen
parfor führt Schleifen-Iterationen parallel über Worker aus. Iterationen müssen unabhängig sein. Variablen werden klassifiziert: sliced (jede Iteration berührt einen eindeutigen Index), broadcast (read-only), reduction (kombiniert mit assoziativer Operation wie + oder *) und temp (intern erstellt). Die Klassifizierung bestimmt, was erlaubt ist.
% requires Parallel Computing Toolbox
% start pool
pool = gcp('nocreate');
if isempty(pool), parpool; end
% parfor: parallel for loop
N = 1000;
results = zeros(1, N);
parfor k = 1:N
results(k) = some_expensive_function(k);
end
% constraints:
% - iterations must be independent (no order dependency)
% - body cannot contain break/return
% - variables classified as sliced, broadcast, reduction, temp
% reduction variables
total = 0;
parfor k = 1:N
total = total + compute(k);
end
% sliced variables (independent indexing)
data = rand(N, 100);
out = zeros(N, 1);
parfor k = 1:N
out(k) = mean(data(k, :));
endspmd und Distributed Arrays
spmd führt denselben Code auf allen Workern aus, wobei labindex jeden identifiziert. Verwenden für datenparallele Algorithmen, bei denen Worker kommunizieren (z.B. MPI-Stil). Distributed Arrays verteilen eine große Matrix über Worker – Operationen darauf bleiben verteilt; gather() bringt das Ergebnis zum Client zurück. Composite speichert per-Worker-Werte.
% spmd: single program, multiple data
spmd
% code runs on every worker
% labindex: this worker's ID (1 to numlabs)
% numlabs: total workers
fprintf('Worker %d of %d\n', labindex, numlabs);
% each worker computes a chunk
local_data = rand(100, 1);
local_sum = sum(local_data);
end
% combine results
total = sum([local_sum{:}]);
% distributed arrays (split across workers)
D = distributed.rand(10000, 10000); % huge matrix
local_size = size(D, 'local') % each worker's chunk
total_size = size(D) % logical total
% operations auto-distribute
S = D * D';
S_local = gather(S); % pull to client (if fits)
% Composite (cell-like, one per worker)
C = Composite();
spmd
C{labindex} = magic(labindex + 1);
end
C{1} % access worker 1's valuegpuArray
gpuArray verschiebt Daten zur GPU; Operationen auf gpuArrays laufen automatisch auf der GPU. gather() bringt Daten zurück. Elementweise und Matrix-Multiplikations-Operationen sehen den größten Speedup; skalarer oder verzweigender Code nicht. arrayfun auf gpuArrays ermöglicht das Ausführen benutzerdefinierter elementweiser Funktionen auf der GPU ohne CUDA zu schreiben.
% requires GPU support (most NVIDIA GPUs)
% move data to GPU
A = gpuArray(rand(10000));
B = gpuArray(rand(10000));
% operations run on GPU
C = A * B; % still on GPU
D = sin(A) + cos(B);
E = sum(A, 1);
% bring back to CPU
C_cpu = gather(C);
% check GPU
gpuDevice % info about current GPU
gpuDeviceCount % number of available GPUs
gpuDevice(1) % select device 1
% element-wise ops are typically fastest on GPU
% matrix multiply also very fast (cuBLAS)
% custom kernels (PTX)
k = parallel.gpu.CUDAKernel('my_kernel.ptx', 'my_kernel.cu');
result = feval(k, A, B);
% arrayfun on GPU (element-wise custom functions)
f = @(x) x^2 + sin(x);
result = arrayfun(f, A);batch und job
batch führt eine Funktion oder ein Skript im Hintergrund aus – nützlich für lange Jobs, die man nicht blockieren will. wait(job) blockiert bis fertig; fetchOutputs ruft Ergebnisse ab. Immer delete(job), um Ressourcen freizugeben. 'Pool', N verwendet N zusätzliche Worker für parfor innerhalb der batch-Funktion.
% run a function in background
job = batch(@my_function, 0, {arg1, arg2});
% check status
job.State % 'queued', 'running', 'finished'
wait(job); % block until done
% get results
results = fetchOutputs(job);
delete(job); % clean up
% batch script
job = batch('my_script.m');
% with pool
job = batch(@my_func, 1, {x}, 'Pool', 4); % 4 extra workers
% batch with attached files
job = batch(@my_func, 1, {x}, ...
'AttachedFiles', {'data.mat', 'helper.m'}, ...
'CurrentFolder', '/path/to/work');
% list jobs
jobs = findJob(pool);
for j = jobs
fprintf('Job %d: %s\n', j.ID, j.State);
end
% parallel pool settings
parpool('local', 4); % 4 workers
delete(gcp('nocreate')); % shut down poolPerformance-Tipps
Arrays vorinitialisieren (zeros/ones) – das Wachsen von Arrays in Schleifen ist der #1 MATLAB-Performance-Killer. Vektorisieren (sin(x) statt Schleifen) – klarer und oft schneller. Der JIT macht einfache Schleifen schnell, aber Vektorisierung gewinnt immer noch bei Mathe. profile viewer findet Bottlenecks. single-Precision für riesige Daten verwenden; MEX-Dateien für echte Hotspots schreiben.
% 1. Preallocate arrays
% BAD
for k = 1:1000
x(k) = k^2; % grows array each iteration
end
% GOOD
x = zeros(1, 1000);
for k = 1:1000
x(k) = k^2;
end
% 2. Vectorize instead of looping
% BAD
for k = 1:length(x)
y(k) = sin(x(k));
end
% GOOD
y = sin(x); % one vectorized call
% 3. Use JIT-friendly patterns
% simple loops are now fast (JIT), but vectorize for clarity
% 4. Profile to find bottlenecks
profile on;
my_function();
profile viewer;
% 5. Prefer single precision for huge data
A = rand(10000, 'single'); % half the memory
% 6. MEX for critical sections
% compile C code: mex my_func.cObjektorientiert
Klassendefinition
classdef in einer Datei namens <ClassName>.m speichern. Properties halten Daten; Methoden definieren Verhalten. Der Konstruktor muss nach der Klasse benannt sein und nargin==0 behandeln (aufgerufen, wenn keine Argumente). Dependent Properties werden beim Zugriff via get.X-Methoden berechnet. disp überschreibt die Anzeige. Statische Methoden nehmen kein obj.
% file: Point.m
classdef Point
properties
x = 0
y = 0
end
properties (Dependent)
r % computed on access
end
methods
function obj = Point(x, y)
if nargin > 0
obj.x = x;
obj.y = y;
end
end
function r = get.r(obj)
r = sqrt(obj.x^2 + obj.y^2);
end
function obj = move(obj, dx, dy)
obj.x = obj.x + dx;
obj.y = obj.y + dy;
end
function disp(obj)
fprintf('Point(%.2f, %.2f), r=%.2f\n', obj.x, obj.y, obj.r);
end
end
methods (Static)
function p = origin()
p = Point(0, 0);
end
end
endValue- vs handle-Klassen
Value-Klassen kopieren bei Zuweisung (wie int oder struct); handle-Klassen werden per Referenz übergeben (wie Java-Objekte). Für mutable Objekte (eine Datenbankverbindung, eine UI-Komponente) handle verwenden. Value-Klassen sind einfacher und sicherer für immutable Daten. handle-Klassen erben von handle und unterstützen Events/Listener und einen delete-Destruktor.
% Value class (default) — copied on assignment
classdef VPoint
properties; x; end
methods
function obj = VPoint(x); obj.x = x; end
function obj = setX(obj, x); obj.x = x; end
end
end
p = VPoint(1);
p2 = p; % copy
p2 = setX(p2, 5);
disp(p.x) % still 1 (unchanged)
% Handle class — passed by reference
classdef HPoint < handle
properties; x; end
methods
function obj = HPoint(x); obj.x = x; end
function setX(obj, x); obj.x = x; end % no return needed
end
end
h = HPoint(1);
h2 = h; % same object
h2.setX(5);
disp(h.x) % 5 (shared)
% handle class features:
% - events and listeners
% - destructor (delete method)
% - copy() methodVererbung und Polymorphismus
Subclass mit <. Superklassen-Konstruktor mit obj@SuperClass(args) aufrufen. Polymorphismus funktioniert natürlich – Methode auf dem Basistyp aufrufen, und die richtige Override läuft. MATLAB unterstützt Mehrfachvererbung (Superklassen mit & trennen), aber nur eine kann eine konkrete Klasse sein; der Rest müssen Interfaces sein.
% base class
classdef Animal
properties; name; end
methods
function obj = Animal(name); obj.name = name; end
function speak(obj)
error('Abstract: subclass must override');
end
function describe(obj)
fprintf('%s says: ', obj.name);
obj.speak();
fprintf('\n');
end
end
end
% subclass
classdef Dog < Animal
methods
function obj = Dog(name); obj = obj@Animal(name); end
function speak(obj); fprintf('Woof'); end
end
end
classdef Cat < Animal
methods
function obj = Cat(name); obj = obj@Animal(name); end
function speak(obj); fprintf('Meow'); end
end
end
% polymorphism
animals = {Dog('Rex'), Cat('Whiskers'), Dog('Buddy')};
for k = 1:length(animals)
animals{k}.describe();
end
% multiple inheritance
classdef FlyingDog < Dog & IFlyable
...
endEvents und Listener
Events erfordern eine handle-Klasse. Events in einem events-Block deklarieren. notify löst ein Event aus; addlistener abonniert. Listener können Funktionen oder anonyme Funktionen @(src, event) sein. Benutzerdefinierte Event-Daten erben von event.EventData. Listener werden gelöscht, wenn das Source-Objekt gelöscht wird (oder man kann sie explizit löschen).
classdef Thermometer < handle
properties
temperature = 20
end
events
temperatureChanged
overheat
end
methods
function set.temperature(obj, t)
obj.temperature = t;
notify(obj, 'temperatureChanged');
if t > 100
notify(obj, 'overheat');
end
end
function obj = Thermometer()
% add listener to own event
addlistener(obj, 'overheat', @(s,e) disp('WARNING: too hot!'));
end
end
end
% usage
t = Thermometer();
lh = addlistener(t, 'temperatureChanged', @(s,e) ...
fprintf('Now: %.1f\n', s.temperature));
lh2 = addlistener(t, 'overheat', @onOverheat);
t.temperature = 25; % triggers temperatureChanged
t.temperature = 105; % triggers both
% custom event data
classdef OverheatData < event.EventData
properties; temp; end
end
% notify(obj, 'overheat', OverheatData(t));Enumeration und Properties
Enumeration-Klassen definieren feste Instanzen – nützlich für Zustandsautomaten, Optionen und Typen. Jeder Enum-Wert kann Daten via Properties tragen. Property-Attribute steuern den Zugriff: SetAccess=private macht read-only von außen; Constant für Kompilierzeit-Konstanten; Hidden verbirgt vor der Anzeige; Access={?Class1, ?Class2} beschränkt auf spezifische Klassen.
% enumeration class
classdef Color
enumeration
Red [1 0 0]
Green [0 1 0]
Blue [0 0 1]
end
properties
rgb
end
methods
function obj = Color(rgb)
obj.rgb = rgb;
end
end
end
c = Color.Red;
disp(c.rgb) % [1 0 0]
% switch on enum
switch c
case Color.Red; disp('red');
case Color.Green; disp('green');
end
% property attributes
classdef Account
properties (SetAccess = private)
balance = 0 % readable outside, settable only inside
end
properties (Access = {?Account, ?Bank})
internal_id % only Account and Bank classes
end
properties (Constant)
PI = 3.14159 % compile-time constant
end
properties (Hidden)
cache % not shown by disp/struct
end
endVerwandte MATLAB-Snippets
Copy-paste ready code for common tasks.
Matrix-Erstellung und -Operationen
Matrizen in MATLAB erstellen und operieren.
2D-Plotting
Liniendiagramme mit Beschriftungen, Legenden und Stilisierung erstellen.
Funktionen und Skripte
Funktionen in separaten Dateien oder am Ende von Skripten definieren.
Cell Arrays und Structs
Heterogene Datencontainer in MATLAB.
Datei-E/A
.mat-, .csv- und Textdateien lesen und schreiben.
ODE-Löser
Gewöhnliche Differentialgleichungen mit ode45 lösen.
Signalverarbeitung (FFT)
FFT eines Signals berechnen und visualisieren.
Struct-Arrays und Tables
Mit Struct-Arrays und dem modernen table-Datentyp arbeiten.
Was this helpful?