Skip to content

MATLAB Hoja de referencia

Entorno de computación numérica para ingeniería y ciencia.

01

Matrices y operaciones básicas

Creación de matrices y vectores

MATLAB (MATrix LABoratory) trata todas las variables como matrices. Los vectores son matrices 1xN o Nx1. Use espacios o comas para separar elementos en una fila, punto y coma para nuevas filas. zeros, ones, eye, rand y magic crean matrices de prueba comunes. El operador dos puntos start:step:stop genera rangos (paso por defecto 1). linspace(a, b, n) crea n puntos espaciados uniformemente — ideal para ejes de gráficos.

matlab
% 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]

Indexación y segmentación de matrices

MATLAB usa indexación base 1 (no base 0). El dos puntos : significa 'todo' — A(:,2) es toda la segunda columna. A(1:3, :) selecciona las filas 1-3. 'end' se refiere al último índice en esa dimensión. La indexación lógica (A(A > 5)) es extremadamente potente — extrae o modifica elementos que cumplen una condición. find devuelve los índices de elementos distintos de cero/verdaderos, y con dos salidas da fila y columna por separado.

matlab
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 16

Aritmética de matrices

El punto antes de un operador (.*) lo hace elemento a elemento en lugar de operación matricial — esta es la fuente #1 de errores de principiantes. A*B es multiplicación matricial; A.*B multiplica elementos correspondientes. El operador barra invertida (\) resuelve sistemas lineales de manera eficiente y precisa (descomposición LU) — siempre prefiera x = A\b sobre inv(A)*b. El apóstrofo (') transpone; para matrices complejas use .' para transposición no conjugada.

matlab
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 slower

Manipulación de matrices

La concatenación con [A B] (espacios) une horizontalmente; [A; B] (punto y coma) une verticalmente — reflejando la sintaxis de creación de filas. reshape rellena por columnas (hacia abajo y luego a través). flipud/fliplr/rot90 reorientan matrices. repmat coloca una matriz en un patrón de cuadrícula. Establecer una fila o columna a [] la elimina. size devuelve las dimensiones, length devuelve la dimensión más grande, numel devuelve el recuento total de elementos.

matlab
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 1

Funciones elemento a elemento y vectorización

La fortaleza de MATLAB es la vectorización — aplicar operaciones a matrices completas a la vez, lo que se ejecuta en C/Fortran optimizado por debajo. sin, exp, sqrt etc. operan elemento a elemento automáticamente. sum/prod/max/min funcionan por columnas por defecto (dimensión 1); pase la dimensión 2 para operaciones por filas. A(:) aplana una matriz a un vector. Siempre prefiera operaciones vectorizadas sobre bucles for por rendimiento — pueden ser 10-100x más rápidas.

matlab
% 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, vectorized
02

Flujo de control y lógica

If / Elseif / Else

MATLAB usa if/elseif/else/end (nota: elseif es una sola palabra). Operadores lógicos: && (AND escalar), || (OR escalar), & (AND elemento a elemento), | (OR elemento a elemento), ~ (NOT, no !). Para comparación de cadenas use strcmp/strcmpi (insensible a mayúsculas) — el operador == solo funciona para matrices de caracteres de la misma longitud. Siempre termine los bloques con 'end'.

matlab
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');
end

Bucles For y While

for itera sobre cada columna de la expresión dada (para vectores, cada elemento). while se ejecuta mientras la condición sea verdadera. SIEMPRE preasigne matrices antes de los bucles (result = zeros(1,N)) — hacer crecer una matriz en un bucle fuerza reasignación en cada iteración y es extremadamente lento. El operador dos puntos 1:5 crea [1 2 3 4 5]. fprintf imprime salida formateada (como printf de C).

matlab
% 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;
end

Switch y Break/Continue

switch compara un valor con etiquetas case — no se necesita break (a diferencia de C/Java). case puede tomar un cell array para múltiples valores. otherwise es el valor por defecto. break sale del bucle más interno; continue salta a la siguiente iteración. try/catch maneja errores elegantemente; ME es un objeto MException con .message e .identifier. MATLAB no tiene operador ternario — use if/else o funciones inline.

matlab
% 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);
end

Operaciones lógicas e indexación

La indexación lógica es la característica estrella de MATLAB — A(condition) selecciona elementos donde la matriz lógica es verdadera. ~= es 'no igual' (no !=). & y | son elemento a elemento; && y || son de cortocircuito (solo escalares, preferidos en condiciones if). find devuelve índices lineales de valores verdaderos. any/all prueban si algún/todos los elementos son verdaderos, opcionalmente a lo largo de una dimensión. La familia is* prueba tipos y valores especiales (NaN, Inf).

matlab
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);

Cadenas y formato

MATLAB tiene dos tipos de cadena: matrices de caracteres ('text', heredado) y escalares de cadena ("text", R2017+). Los escalares de cadena son más flexibles para manipulación. sprintf devuelve una cadena formateada; fprintf imprime a consola o archivo. Especificadores de formato comunes: %s (cadena), %d (entero), %f (flotante), %.2f (2 decimales), %e (científico). strsplit/strjoin manejan listas delimitadas. num2str/mat2str convierten números a cadenas.

matlab
% 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'
03

Funciones y scripts

Definición de funciones

Las funciones deben estar en un archivo con el mismo nombre (add.m para la función add), o al final de un archivo de script. La primera línea es la declaración de función. Las funciones tienen su propio espacio de trabajo (separado del espacio de trabajo base). nargin/nargout le permiten manejar argumentos opcionales — nargin cuenta las entradas reales. Múltiples salidas se capturan con [a, b] = func(). Si llama con menos salidas, las adicionales se descartan.

matlab
% 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;
end

Funciones anónimas e inline

Las funciones anónimas (@(args) expr) son funciones rápidas de una línea definidas inline — perfectas para pasar a solvers (fzero, integral, ode45) sin crear archivos. Capturan variables del espacio de trabajo en el momento de creación. Los function handles (@sin) le permiten pasar funciones integradas o de usuario como argumentos. Esto es esencial para computación numérica: integral(@(x) f(x), a, b) integra cualquier función que defina.

matlab
% 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)             % 0

Scripts y Live Scripts

Los scripts son secuencias de comandos que se ejecutan en el espacio de trabajo base (a diferencia de las funciones, que tienen espacios de trabajo aislados). El marcador %% crea 'celdas' (secciones) que puede ejecutar independientemente con Ctrl+Enter — ideal para desarrollo incremental. Los Live Scripts (.mlx) son como cuadernos de Jupyter: combinan código, texto formateado, ecuaciones y gráficos inline en un documento interactivo. Prefiera funciones sobre scripts para código reutilizable.

matlab
% 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, equations

Funciones anidadas y locales

Los scripts pueden contener funciones locales al final del archivo (desde R2016b) — solo son visibles dentro de ese archivo. Las funciones anidadas (definidas dentro de otra función) comparten el espacio de trabajo del padre, por lo que pueden leer y modificar sus variables — útil para callbacks y acumuladores pero puede hacer el código más difícil de seguir. Las funciones locales en archivos de función son helpers visibles solo dentro de ese archivo. Use funciones locales para mantener los scripts organizados sin crear muchos archivos.

matlab
% 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);
end

Ámbito de variables y global

MATLAB pasa argumentos por valor (copiar al modificar), por lo que las funciones no pueden cambiar accidentalmente las variables del llamador — a diferencia de C/Python. Use global para estado verdaderamente compartido (declare en cada función que lo use), pero prefiera pasar argumentos. Las variables persistent retienen su valor entre llamadas a funciones (como static en C) — útil para contadores, cachés o memoización. Inicialice variables persistent con comprobación isempty en la primera llamada. Evite globales en favor de retornos de función o funciones anidadas.

matlab
% 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);
end
04

Estructuras de datos

Cell Arrays

Los cell arrays son el contenedor de MATLAB para datos de tipos mixtos (como las listas de Python). Use llaves {} para acceder al CONTENIDO de una celda, y paréntesis () para obtener una celda (útil para segmentación). Esta distinción es crucial: c{1} da la cadena; c(1) da una celda que contiene la cadena. Las celdas son esenciales para manejar cadenas de diferentes longitudes, matrices de tamaño variable y datos irregulares. num2cell/mat2cell convierten entre matrices numéricas y celdas.

matlab
% 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 y Tables

Los structs agrupan datos relacionados con campos con nombre — como objetos sin métodos. Las Tables (R2013+) son el equivalente de MATLAB a los dataframes: orientadas a columnas, con variables con nombre y nombres de fila. Las Tables son ideales para datos CSV/Excel. Acceda a columnas por nombre (T.ages) o índice. La indexación lógica funciona en filas: T(T.age > 25, :) filtra filas. summary() da estadísticas para cada columna. Las Tables se integran con readtable/writetable para E/S de datos.

matlab
% 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 y manejo de caracteres

El MATLAB moderno (R2017+) prefiere string arrays ("text") sobre matrices de caracteres ('text'). Los string arrays soportan operaciones vectorizadas: strlength, +, split, join, contains, matches, replace todas funcionan elemento a elemento. Las matrices de caracteres siguen siendo comunes en código antiguo y son necesarias para algunas funciones. Use string arrays para colecciones de texto; manejan diferentes longitudes naturalmente (a diferencia de las matrices de caracteres que necesitan relleno o celdas).

matlab
% 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 y conjuntos

containers.Map es el diccionario clave-valor de MATLAB (hash map) — útil para tablas de búsqueda y configuración. Las claves pueden ser cadenas o números. isKey comprueba existencia; keys/values recupera todos. Las operaciones de conjuntos (union, intersect, setdiff, setxor, ismember) funcionan en matrices numéricas y cell arrays de cadenas. ismember prueba pertenencia y devuelve una matriz lógica — ideal para filtrado. Estas complementan la indexación lógica para manipulación de datos.

matlab
% 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 y datetime

Los categorical arrays almacenan datos de texto eficientemente (como enteros con un mapa de etiquetas) y soportan ordenamiento — ideales para respuestas de encuestas, calificaciones o cualquier conjunto fijo de categorías. datetime/duration (R2014+) reemplazan las funciones heredadas datenum/datestr con un sistema de fechas moderno y consciente de zonas horarias. La aritmética de fechas es intuitiva: añada days(), hours(), minutes(). Estos tipos se integran con tables y gráficos para análisis de series temporales.

matlab
% 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 week
05

Gráficos y visualización

Gráficos 2D básicos

plot() es la función central de gráficos 2D. El tercer argumento especifica color y estilo ('b-' = azul sólido). hold on le permite superponer múltiples gráficos; hold off libera. Siempre etiquete los ejes y añada una leyenda. axis([xmin xmax ymin ymax]) establece límites. saveas/print exportan figuras — print con -r300 da 300 DPI. gcf obtiene el handle de la figura actual. La opción 'Location','best' coloca la leyenda automáticamente.

matlab
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');

Múltiples gráficos y subgráficos

subplot(r, c, n) divide la figura en una cuadrícula r por c y selecciona la celda n-ésima para graficar. tiledlayout (R2019+) es el reemplazo moderno — espaciado más limpio y un título compartido. nexttile avanza al siguiente subgráfico. yyaxis crea gráficos con dos ejes y (izquierdo y derecho) para datos con diferentes escalas. Siempre llame figure primero para abrir una nueva ventana, o sobrescribirá el gráfico actual.

matlab
% 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));

Gráficos especializados

MATLAB tiene docenas de gráficos especializados: bar/barh (gráficos de barras), histogram (reemplaza hist), scatter (con mapeo opcional de color/tamaño), pie, area, stem, stairs, compass, feather. scatter(x, y, size, color, 'filled') es especialmente potente — el 4º argumento colorea puntos por un valor, revelando una tercera dimensión. histogram con 'Normalization','pdf' normaliza a una densidad de probabilidad para comparación con distribuciones continuas.

matlab
% 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));

Gráficos 3D y superficies

plot3 dibuja líneas paramétricas 3D. Para superficies, primero cree una cuadrícula con meshgrid, luego compute Z = f(X, Y). surf dibuja una superficie rellena; mesh dibuja un wireframe; contour dibuja curvas de nivel 2D. colormap (jet, parula, hot, cool) controla el mapeo de color; colorbar añade una leyenda. shading interp elimina líneas de cuadrícula para gradientes suaves. view(az, el) establece el ángulo de cámara. 'EdgeColor','none' oculta líneas de malla para un aspecto limpio.

matlab
% 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;

Personalización de gráficos y exportación

Casi todos los aspectos visuales son personalizables vía pares nombre-valor o set(). Los colores son triples RGB [r g b] de 0-1. set(gca, ...) modifica los ejes actuales (fuente, escala, límites). MATLAB soporta LaTeX en títulos/etiquetas con 'Interpreter','latex'. exportgraphics (R2020+) es la función moderna de exportación con opciones vectoriales y de alta DPI. Use handles de figura (f1, f2) para gestionar múltiples ventanas. annotation() añade flechas, cuadros de texto y formas.

matlab
% 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 f1
06

Análisis de datos y estadística

Estadística descriptiva

MATLAB proporciona funciones estadísticas completas. mean/median/mode para tendencia central; std/var/range/iqr para dispersión. Por defecto operan a lo largo de la primera dimensión (columnas). Use 'omitnan' para omitir valores NaN (importante para datos del mundo real). quantile/prctile dan percentiles. El Statistics and Machine Learning Toolbox añade geomean, harmmean, zscore y funciones de distribución. Siempre compruebe si hay NaNs antes del análisis — se propagan a través de la mayoría de las operaciones.

matlab
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 equivalent

Ajuste de curvas y regresión

polyfit ajusta un polinomio de grado dado; polyval lo evalúa. Para regresión lineal, regress() da coeficientes más estadísticas (R², F-statistic, p-value). corrcoef devuelve la matriz de correlación completa. El Curve Fitting Toolbox proporciona fit() para ajuste interactivo y programático con modelos personalizados. lsqcurvefit (Optimization Toolbox) ajusta modelos no lineales arbitrarios. Siempre grafique el ajuste contra los datos para comprobar calidad — los polinomios de alto orden pueden sobreajustar.

matlab
% 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]

Interpolación y remuestreo

interp1 interpola datos 1D — 'linear' es rápido, 'spline' es suave (puede sobrepasar), 'pchip' preserva forma (sin sobrepasar). interp2 hace lo mismo para cuadrículas 2D. Para consultas repetidas, griddedInterpolant es más eficiente (construya una vez, consulte muchas veces). resample cambia la tasa de muestreo de una señal (requiere Signal Processing Toolbox). Siempre elija el método basado en sus datos: spline para funciones suaves, pchip para datos monótonos, nearest para categóricos.

matlab
% 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 y procesamiento de señales

fft computa la Transformada Rápida de Fourier — la base del análisis de frecuencias. La salida es compleja; tome abs() para la magnitud. Convierta a un espectro de un solo lado tomando la primera mitad y duplicando (excepto DC y Nyquist). Las frecuencias van de 0 a fs/2 (Nyquist). ifft invierte de vuelta al dominio del tiempo. El filtrado en el dominio de frecuencia (poniendo a cero frecuencias no deseadas) es simple pero puede causar ringing; use designfilt para filtros apropiados. spectrogram muestra el contenido de frecuencia a lo largo del tiempo.

matlab
% 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');

Optimización y búsqueda de raíces

fzero encuentra raíces de funciones 1D (necesita un intervalo de bracketing o una estimación). fminbnd minimiza una función 1D en un intervalo acotado; fminsearch usa Nelder-Mead para optimización multivariante sin restricciones. fmincon (Optimization Toolbox) maneja restricciones. linprog resuelve programas lineales. Siempre proporcione una buena estimación inicial (x0) para solvers iterativos. Compruebe la salida exitflag para confirmar convergencia. Para optimización global, use GlobalSearch o MultiStart.

matlab
% 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);
07

E/S de archivos e importación de datos

Archivos MAT y Save/Load

.mat es el formato binario nativo de MATLAB — rápido, compacto y preserva todos los tipos de variables. save/load son los comandos principales. Use -v7.3 para archivos de más de 2GB (basado en HDF5). -ascii exporta a texto legible por humanos (pierde información de tipo). Cargar en un struct (s = load(...)) evita contaminar el espacio de trabajo. clear elimina variables; clearvars -except mantiene las especificadas. Siempre guarde resultados intermedios en cómputos largos para permitir reanudar.

matlab
% 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 x

Lectura de archivos de texto y CSV

readtable es la forma moderna de leer CSV/Excel — devuelve una table con columnas con nombre y maneja encabezados automáticamente. readmatrix lee datos numéricos en una matriz. Para control total, use fopen/fgetl/fprintf/fclose (¡siempre cierre los archivos!). fscanf lee datos formateados como en C. Siempre compruebe fid por errores: si fid == -1, el archivo no pudo abrirse. readcell maneja datos de tipos mixtos que no caben en una matriz o table.

matlab
% 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 y E/S de hojas de cálculo

readtable/writetable son las funciones recomendadas para E/S de Excel. Manejan encabezados, tipos y hojas automáticamente. detectImportOptions le permite personalizar cómo se analizan las columnas (p. ej., forzar una columna a int32 o string). Use 'Range' para leer/escribir celdas específicas. 'WriteMode','append' añade filas a una hoja existente. Para archivos Excel grandes, considere CSV (más rápido) o .mat (nativo). El toolbox Spreadsheet Link conecta MATLAB directamente a Excel.

matlab
% 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);

Trabajo con rutas y directorios

dir() devuelve un struct array con .name, .date, .bytes, .isdir, .datenum para cada archivo. fullfile une rutas de forma portable (usa el separador correcto en cada SO). fileparts divide una ruta en directorio, nombre y extensión. exist('name', 'file') comprueba si existe un archivo. addpath añade directorios a la ruta de búsqueda de MATLAB para que las funciones en ellos sean accesibles; savepath lo persiste. Estos son esenciales para procesar archivos en lotes dentro de carpetas.

matlab
% 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 sessions

Imágenes y audio

imread/imshow/imwrite manejan imágenes (JPEG, PNG, TIFF, BMP). Las imágenes se almacenan como matrices uint8 (0-255) o doubles (0-1). rgb2gray convierte color a escala de grises. El Image Processing Toolbox añade imresize, imrotate, imfilter, detección de bordes y operaciones morfológicas. audioread/audiowrite/sound manejan archivos de audio. Las imágenes y el audio son solo matrices, por lo que todas las herramientas matemáticas y de gráficos de MATLAB se aplican directamente.

matlab
% 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);
08

Matemática simbólica y avanzada

Variables simbólicas y simplificación

El Symbolic Math Toolbox habilita computación exacta (no numérica). syms declara variables simbólicas. simplify, expand, factor, collect manipulan expresiones algebraicas. subs sustituye valores o variables. vpa (aritmética de precisión variable) computa con precisión arbitraria — útil cuando el redondeo de coma flotante importa. Los resultados simbólicos son exactos (p. ej., sqrt(2) permanece como sqrt(2), no 1.4142...). Convierta a numérico con double() cuando sea necesario.

matlab
% 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...

Cálculo: derivadas e integrales

diff deriva (pase un segundo argumento para derivadas de orden superior). int integra — sin límites devuelve la antiderivada; con límites computa la integral definida. limit computa límites (incluyendo unilaterales con 'left'/'right'). taylor expande una función como una serie de Taylor alrededor de un punto. Estos devuelven expresiones simbólicas; use double() o vpa() para resultados numéricos. El cálculo simbólico es exacto y evita el redondeo numérico.

matlab
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/120

Resolución de ecuaciones

solve encuentra soluciones exactas (simbólicas) a ecuaciones y sistemas algebraicos. Para ecuaciones sin soluciones de forma cerrada, use vpasolve (numérico). dsolve resuelve ecuaciones diferenciales ordinarias simbólicamente — proporcione condiciones iniciales/de frontera para una solución particular. Los resultados son simbólicos; convierta con double/vpa para graficar. Para EDOs complejas que no pueden resolverse simbólicamente, use ode45 (solver numérico) en su lugar. Siempre compruebe si solve devolvió vacío (no se encontró solución).

matlab
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]);

Transformadas de Laplace y Fourier

laplace/ilaplace computan el par de transformadas de Laplace — esenciales para resolver EDOs lineales y analizar sistemas de control. fourier/ifourier hacen lo mismo para la transformada de Fourier (frecuencia continua). ztrans/iztrans manejan señales discretas (filtros digitales). El flujo de trabajo para resolver EDOs vía Laplace: transformar la EDO a algebraica, resolver para Y(s), luego transformada inversa. Estas son operaciones simbólicas exactas; para transformadas numéricas use fft.

matlab
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 invert

Solvers numéricos de EDOs

ode45 es el solver de EDO por excelencia — un método Runge-Kutta (4,5) que es preciso y adaptativo. Para sistemas, el estado es un vector v, y la función devuelve un vector columna de derivadas. ode15s es para problemas stiff (donde la dinámica opera en escalas de tiempo muy diferentes). odeset configura tolerancias y eventos. Para pasar parámetros, use una función anónima que los capture. Siempre grafique la solución para verificar que parece razonable. Para problemas de valor de frontera, use bvp4c.

matlab
% 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);
09

Operaciones matriciales en profundidad

Ecuaciones lineales y descomposiciones

El operador barra invertida (\) es el solver lineal preferido de MATLAB — auto-selecciona LU, QR o Cholesky basado en la matriz. Nunca use inv(A)*b a menos que realmente necesite la inversa; es más lento y menos estable numéricamente. lu, qr y chol devuelven las factorizaciones matriciales estándar. eig computa autovalores/autovectores, y svd da la descomposición en valores singulares — fundamental para PCA, pseudo-inversas y aproximaciones de rango bajo.

matlab
% 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'

Matrices dispersas

Las matrices dispersas almacenan solo entradas distintas de cero — esenciales cuando se trabaja con matrices dimensionales de 100k+ que son mayormente ceros (común en métodos de elementos finitos, algoritmos de grafos y EDPs). sparse(i,j,v) construye desde forma de triplete; full convierte de vuelta. La aritmética entre matrices dispersas permanece dispersa. nnz cuenta no ceros y spy grafica el patrón de dispersión. Las resoluciones lineales dispersas (A\b) usan solvers especializados como UMFPACK automáticamente.

matlab
% 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 pattern

Funciones matriciales y reshape

reshape reorganiza elementos por columnas (primero por columnas hacia abajo) — una fuente común de errores al portar desde lenguajes row-major. flipud/fliplr/rot90 son útiles para revertir o transponer de formas no estándar. repmat coloca una matriz en mosaico; repelem duplica elementos individuales. La concatenación usa [A; B] (vertical) y [A B] (horizontal), o horzcat/vertcat para uso programático. arrayfun aplica una función elemento a elemento cuando la vectorización no es posible.

matlab
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 y vectorización

Desde R2016b, MATLAB automáticamente hace broadcasting (expande) dimensiones de tamaño 1 para coincidir con el otro operando — no se necesita bsxfun o repmat. La vectorización (operar en matrices completas en lugar de bucles elemento por elemento) es la mayor ganancia de rendimiento en MATLAB, porque las rutinas BLAS/LAPACK subyacentes están altamente optimizadas. Siempre preasigne matrices antes de rellenarlas en un bucle; hacer crecer matrices dinámicamente fuerza reasignación en cada iteración y es O(n^2).

matlab
% 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);

Aplicaciones de álgebra lineal numérica

El operador barra invertida resuelve problemas de mínimos cuadrados automáticamente cuando A es rectangular (más filas que columnas). polyfit/polyval ajustan y evalúan polinomios. PCA se computa más establermente vía SVD de la matriz de datos centrada — las columnas de V son direcciones principales y diag(S) da las desviaciones estándar. cond(A) mide la sensibilidad numérica; valores por encima de 1e12 significan que la matriz es esencialmente singular para aritmética de doble precisión.

matlab
% 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-conditioned
10

Gráficos 2D y 3D en profundidad

Gráficos de líneas y personalización

plot es la función caballo de batalla de gráficos 2D. Las cadenas de especificación de línea como 'r--' (rojo discontinuo) combinan color, marcador y estilo. hold on le permite superponer múltiples gráficos. subplot(m,n,k) crea una cuadrícula m por n y selecciona la celda k-ésima (row-major). set(gca, ...) modifica los ejes actuales; gcf es la figura actual. print con -dpng y -r300 exporta un PNG de 300 DPI — mucha mayor calidad que saveas.

matlab
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');

Superficies 3D, mallas y gráficos de contorno

meshgrid crea las cuadrículas de coordenadas X, Y necesarias para gráficos de superficie. surf dibuja una superficie rellena, mesh dibuja un wireframe, y contour proyecta a curvas de nivel 2D. colormap cambia el mapeo de color (jet, parula, hot, cool, gray); parula es el valor por defecto moderno. shading interp suaviza transiciones de color. plot3 dibuja curvas paramétricas 3D. view(az, el) establece el ángulo de cámara; axis equal previene distorsión.

matlab
[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;

Gráficos estadísticos y especializados

histogram (R2014b+) reemplaza hist con más características como 'Normalization' para PDFs. boxplot compara distribuciones entre grupos. scatterhist muestra un gráfico de dispersión con histogramas marginales — ideal para visualizar correlaciones. bar soporta diseños agrupados y apilados. errorbar añade visualización de incertidumbre. Estos gráficos especializados son esenciales para presentación de datos científicos y análisis exploratorio.

matlab
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-');

Animaciones y gráficos interactivos

Las animaciones actualizan datos de gráfico dentro de un bucle y llaman drawnow para refrescar. Para rendimiento suave, cree el gráfico una vez y actualice XData/YData en lugar de volver a graficar. getframe captura la figura actual; movie reproduce una secuencia. VideoWriter exporta a MP4 o AVI — útil para compartir resultados. Siempre establezca límites de eje fuera del bucle para prevenir jitter de auto-escalado.

matlab
% 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);

Objetos gráficos y personalización de handles

Los gráficos de MATLAB se construyen sobre un árbol de objetos handle (figure → axes → lines, text, patches). set/get modifican propiedades; findobj localiza objetos por propiedad. La opción 'Interpreter' habilita renderizado TeX o LaTeX completo para notación matemática. exportgraphics (R2020a+) produce PDFs vectoriales de calidad de publicación con bounding boxes ajustadas — mucho mejor que el antiguo print para incrustar en artículos.

matlab
% 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');
12

GUI y App Designer

Fundamentos de App Designer

App Designer (lanzado con appdesigner) es la herramienta visual moderna para construir GUIs de MATLAB, guardando archivos .mlapp que empaquetan diseño y código. Para UIs programáticas, uifigure (R2014b+) crea ventanas de figura modernas con uibutton, uilabel, uieditfield, uislider, uidropdown y uiaxes. Los callbacks son function handles asignados a propiedades como ButtonPushedFcn. El antiguo GUIDE está deprecado; el código nuevo debería usar componentes basados en uifigure o App Designer.

matlab
% 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)];
end

Gestores de diseño y contenedores

uigridlayout (R2018b+) es el gestor de diseño responsivo moderno — las filas y columnas pueden ser fijas, proporcionales ('1x') o fit-content. uitabgroup/uitab crean interfaces con pestañas. uipanel agrupa componentes relacionados visualmente. uiscrollbox añade desplazamiento para contenido que excede la ventana. Las funciones de diálogo (uigetfile, inputdlg, msgbox, questdlg) manejan selección de archivos estándar, entrada y notificaciones. Estas herramientas de diseño son esenciales para construir aplicaciones MATLAB profesionales y redimensionables.

matlab
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 y manejo de eventos

El MATLAB moderno usa callbacks de function handle con dos argumentos (src, event) donde event lleva datos estructurados como event.Value o event.Key. ValueChangingFcn se dispara continuamente durante la interacción; ValueChangedFcn se dispara una vez al final. addlistener crea listeners persistentes en cualquier propiedad. Los objetos timer ejecutan callbacks en un horario — útiles para UIs de adquisición de datos en vivo. Siempre limpie listeners y timers (delete) para evitar fugas de memoria.

matlab
% 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);

Empaquetado de apps para distribución

matlab.apputil.package empaqueta una app de App Designer en un archivo .mlappinstall que los usuarios instalan vía la pestaña Apps. El Application Compiler (deploytool) produce ejecutables standalone (.exe) que se ejecutan con el MATLAB Runtime gratuito — no se necesita licencia de MATLAB en el destino. Las Web Apps (R2020a+) se despliegan en un MATLAB Web App Server y se ejecutan en cualquier navegador. Este pipeline de distribución le permite compartir aplicaciones MATLAB con usuarios no MATLAB.

matlab
% 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 App

Patrones de UI comunes

drawnow limitrate actualiza gráficos sin bloquear — crítico para pantallas de datos en vivo. uitable muestra datos tabulares con columnas ordenables. uiprogressdlg muestra una barra de progreso modal para operaciones largas. uicontextmenu añade menús de clic derecho a cualquier componente. Estos patrones cubren las necesidades de UI más comunes: actualizaciones en vivo, tablas de datos, retroalimentación de progreso y acciones contextuales. Para gráficos en vivo de alto rendimiento, considere animatedline que está optimizado para datos de streaming.

matlab
% 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;
13

Image Processing Toolbox

Lectura, escritura y visualización de imágenes

imread soporta PNG, JPEG, TIFF, BMP y muchos formatos científicos. Los tipos de datos de imagen importan: uint8 (0-255) es común para archivos, double (0-1) para procesamiento. Siempre use im2double/im2uint8 (que reescalan) en lugar de double()/uint8() (que truncan). im2gray (R2020b+) reemplaza rgb2gray. imwrite soporta opciones específicas de formato como calidad JPEG. imfinfo lee metadatos sin cargar datos de píxeles.

matlab
% 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});

Filtrado y mejora

imgaussfilt es el desenfoque gaussiano moderno (reemplaza fspecial('gaussian') + imfilter). medfilt2 elimina ruido de sal y pimienta sin difuminar bordes. fspecial crea kernels predefinidos (sobel, prewitt, laplacian, gaussian). imsharpen mejora bordes vía unsharp masking. histeq realiza ecualización de histograma global; adapthisteq (CLAHE) lo hace localmente para mejor contraste en imágenes no uniformes. imadjust mapea rangos de intensidad para corrección de brillo/contraste.

matlab
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], []);

Operaciones morfológicas y segmentación

Las operaciones morfológicas (erode, dilate, open, close) procesan imágenes binarias usando elementos estructurantes (strel). Opening elimina objetos pequeños; closing rellena pequeños agujeros. bwconncomp encuentra regiones conectadas; regionprops extrae medidas (área, centroide, bounding box) para cada una. watershed segmenta objetos que se tocan. edge detecta bordes (Canny es el más robusto). graythresh computa el umbral global de Otsu; multithresh hace multi-nivel. Estas herramientas forman el núcleo del preprocesamiento de visión por computador.

matlab
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);

Detección de características y transformadas

La detección de características encuentra puntos distintivos para emparejamiento y seguimiento. Las esquinas de Harris son rápidas pero no invariantes a escala; SURF y ORB son invariantes a escala/rotación para emparejamiento robusto entre vistas. extractFeatures computa descriptores en puntos detectados. La transformada de Hough detecta líneas (y círculos) vía votación en espacio de parámetros — útil para corrección de inclinación de documentos y detección de carriles. imregtform realiza registro de imagen basado en intensidad, computando la transformación geométrica que alinea dos imágenes.

matlab
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);

Procesamiento por lotes e imágenes grandes

Para procesamiento por lotes, parfor paraleliza entre imágenes. blockproc procesa imágenes grandes en mosaicos — esencial cuando la imagen completa no cabe en memoria; la opción 'Destination' transmite salida a disco. imageDatastore gestiona colecciones demasiado grandes para enumerar manualmente y se integra con tall arrays y el framework MapReduce para computación fuera de núcleo. El soporte bigTIFF maneja microscopía de gigapíxeles e imágenes de teledetección.

matlab
% 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);
14

Optimization Toolbox

Optimización sin y con restricciones

fminunc resuelve problemas suaves sin restricciones; fmincon maneja cotas, y restricciones lineales y no lineales. linprog y quadprog están especializados para objetivos lineales y cuadráticos con restricciones lineales — mucho más rápidos que los solvers generales. optimoptions configura el comportamiento del solver (algoritmo, tolerancias, visualización). El algoritmo 'interior-point' es robusto para problemas grandes; 'sqp' es bueno para restricciones no lineales. Siempre proporcione gradientes analíticos cuando estén disponibles para velocidad y precisión.

matlab
% 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);

Optimización global y multiobjetivo

Los solvers locales (fminunc, fmincon) pueden quedarse atascados en mínimos locales. GlobalSearch y MultiStart ejecutan un solver local desde muchos puntos de inicio. ga (algoritmo genético), particleswarm y simulannealbnd son métodos globales sin derivadas — más lentos pero funcionan en objetivos discontinuos o ruidosos. gamultiobj encuentra el frente de Pareto para problemas multiobjetivo, devolviendo un conjunto de soluciones no dominadas. Elija basándose en suavidad del problema, dimensionalidad y si necesita garantías de optimalidad global.

matlab
% 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');

Ajuste de curvas y estimación de parámetros

fittype define modelos paramétricos personalizados; fit realiza la regresión con heurísticas automáticas de punto de inicio. lsqcurvefit es el solver de mínimos cuadrados no lineales de bajo nivel — útil cuando necesita control fino o Jacobianos personalizados. confint y predint devuelven intervalos de confianza y predicción para cuantificación de incertidumbre. La app Curve Fitter (cftool) proporciona una interfaz interactiva para explorar ajustes. Siempre compruebe los residuos por estructura sistemática que sugiera mala especificación del modelo.

matlab
% 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');

Optimización entera y combinatoria

intlinprog resuelve programas lineales de enteros mixtos — el caballo de batalla para problemas de programación, enrutamiento y asignación. matchpairs resuelve el problema de asignación óptimamente en O(n^3). El problema del viajante requiere eliminación iterativa de subtours ya que el conjunto de restricciones es exponencial. surrogateopt es para funciones costosas de caja negra (p. ej., simulaciones que toman minutos por evaluación) — construye un modelo sustituto y muestrea inteligentemente. Para problemas combinatorios demasiado grandes para métodos exactos, considere ga o heurísticas personalizadas.

matlab
% 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);

Flujo de trabajo de optimización y mejores prácticas

Elegir el solver correcto es la decisión más importante — usar fmincon en un programa lineal desperdicia órdenes de magnitud en rendimiento. Proporcionar gradientes analíticos (via el framework basado en problemas u optimoptions) mejora dramáticamente la velocidad y fiabilidad. Escalar variables a orden 1 mejora el condicionamiento. Compruebe exitflag y firstorderopt para verificar convergencia. El framework basado en problemas (optimproblem, optimvar) es más legible y deja a MATLAB auto-seleccionar el solver — preferido para código nuevo.

matlab
% 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);
15

Computación paralela

Bucles parfor y pools paralelos

parfor es el camino más fácil al paralelismo — distribuye iteraciones de bucle entre workers. Las iteraciones deben ser independientes (ninguna iteración k depende de k-1). Las variables se clasifican: variables de bucle (k), sliced (indexadas por k solo en primera/última dim), broadcast (solo lectura) y reduction (combinadas con op asociativo como + o *). La sobrecarga de comunicación significa que parfor solo ayuda cuando cada iteración hace trabajo sustancial. Inicie el pool una vez; reutilícelo entre bucles parfor para evitar coste de inicio.

matlab
% 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 workers

spmd y arrays distribuidas

spmd ejecuta el mismo código en todos los workers con labidx identificando cada uno — útil para algoritmos data-parallel donde cada worker procesa un chunk. Las variables Composite (A{1}, A{2}) contienen resultados por worker. Las arrays distribuidas esparcen una única array lógica entre workers; localpart da el chunk local. labSendrecv y gcat/gplus habilitan comunicación entre workers. Use spmd para paralelismo de grano fino que parfor no puede expresar (p. ej., algoritmos iterativos que necesitan comunicación).

matlab
% 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);

Computación en GPU

gpuArray transfiere datos a la GPU; las operaciones posteriores se ejecutan allí y permanecen en la GPU hasta que gather() trae los resultados de vuelta. La mayoría de las funciones elemento a elemento y de álgebra lineal están habilitadas para GPU. arrayfun ejecuta funciones personalizadas elemento a elemento en la GPU (pero solo con operaciones escalares). Para sistemas multi-GPU, asigne a cada worker parfor una GPU diferente via gpuDevice(k). La computación en GPU sobresale en álgebra lineal densa grande y operaciones elemento a elemento; la sobrecarga de transferencia de datos la hace ineficiente para arrays pequeñas.

matlab
% 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
end

batch y planificación de trabajos

batch ejecuta una función asincrónicamente en segundo plano — útil para cómputos largos que no quiere bloquear la sesión. batch con opción 'Pool' ejecuta una función que ella misma usa parfor. La API de job/task de bajo nivel da control fino sobre la planificación. parcluster selecciona un perfil de cluster; MATLAB se integra con SLURM, PBS y LSF vía la interfaz de planificador genérico del Parallel Computing Toolbox. Para HPC, guarde datos en archivos y envíe scripts en lugar de depender de memoria compartida.

matlab
% 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;

Rendimiento y profiling de código paralelo

Haga profiling de código paralelo con profile on -parallel para ver líneas de tiempo por worker. La aceleración está limitada por la ley de Amdahl: si el 10% del código es serial, la aceleración máxima es 10x independientemente del número de workers. Errores comunes: iteraciones demasiado pequeñas (la sobrecarga excede el trabajo), variables broadcast grandes (coste de transferencia) y operaciones de reducción excesivas. parallel.pool.DataQueue habilita actualizaciones de progreso en vivo desde workers sin bloqueo — útil para monitorizar trabajos paralelos largos. Siempre mida antes y después para verificar que el paralelismo realmente ayuda.

matlab
% 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);
end
16

Programación orientada a objetos

Clases y propiedades

Las clases de MATLAB viven en archivos llamados ClassName.m. El bloque classdef contiene propiedades y métodos. Los atributos de propiedad controlan el acceso: SetAccess=protected significa que solo los métodos de clase pueden escribir; Constant define constantes a nivel de clase. El constructor es un método con el nombre de la clase. MATLAB usa semántica de valor por defecto (los objetos se copian al asignar) — use clases handle para semántica de referencia. Los métodos sobrecargados como disp personalizan el comportamiento por defecto.

matlab
% 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)

Clases handle vs value

La elección entre clases value y handle es fundamental. Las clases value (por defecto) se copian al asignar y en llamadas a métodos — más seguras para datos inmutables. Las clases handle (subclase handle) son referencias: las asignaciones y copias apuntan al mismo objeto, como los objetos Java/Python. Las clases handle son necesarias para cosas como componentes GUI, handles de archivo y estado mutable compartido entre llamadores. Use clases value para objetos matemáticos (vectores, matrices) donde la inmutabilidad es deseable.

matlab
% 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)

Herencia y polimorfismo

La herencia usa < en la línea classdef; obj@SuperClass(args) llama al constructor de la superclase. MATLAB soporta herencia múltiple pero es rara y puede llevar a problemas de diamante. Los métodos abstractos (declarados en methods (Abstract)) deben ser implementados por subclases; la clase base no puede instanciarse. El polimorfismo funciona naturalmente: llame al método en cualquier objeto y MATLAB despacha a la implementación correcta. Use isa(obj, 'ClassName') e isprop/ismethod para comprobaciones de tipo en tiempo de ejecución.

matlab
% 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());
end

Eventos y listeners

El modelo de eventos implementa el patrón observer: las clases declaran eventos, los listeners registran callbacks y notify dispara eventos. Esto desacopla productores de consumidores — esencial para GUIs, simulaciones y sistemas reactivos. Los métodos set de propiedad (set.PropertyName) interceptan asignaciones y pueden disparar eventos. Los listeners pueden ser temporales (addlistener, ligados al tiempo de vida del objeto) o persistentes (objeto listener mantenido en una variable). Siempre elimine los listeners cuando termine para prevenir fugas de memoria.

matlab
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 + warning

Sobrecarga de operadores e indexación

La sobrecarga de operadores permite que las clases de usuario funcionen con +, *, [], etc. Cada operador mapea a una función (plus, mtimes, minus, mrdivide, horzcat, vertcat). subsref y subsasgn personalizan la indexación (obj(i), obj.field, obj{i}). El MATLAB moderno prefiere notación de punto para acceso a propiedades, pero subsref/subsasgn siguen siendo necesarios para patrones de falsa indexación (p. ej., una librería de tensores donde T(1,2,3) extrae un elemento). Sobrecargue disp para salida legible y end/numel para semántica de indexación personalizada.

matlab
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 abs
17

Depuración y ajuste de rendimiento

Depurador y breakpoints

dbstop establece breakpoints — la herramienta de depuración más potente. Los breakpoints condicionales (dbstop ... if condition) pausan solo cuando un predicado se cumple, esencial para encontrar errores en bucles grandes. dbstop if error convierte cualquier excepción no capturada en una pausa de depuración, dejándole inspeccionar el espacio de trabajo en el punto de fallo. El objeto ME (MException) en bloques catch lleva .message, .identifier y .stack para manejo de errores rico. Use dbstack para navegar la pila de llamadas y dbup/dbdown para inspeccionar espacios de trabajo de llamadores.

matlab
% 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
end

Profiling y detección de hotspots

El profiler (profile on/off + profile viewer) muestra dónde se gasta el tiempo, línea por línea — la herramienta más importante para optimización. Siempre haga profiling antes de optimizar; la intuición sobre cuellos de botella suele ser errónea. timeit es más preciso que tic/toc para microbenchmarks porque ejecuta la función múltiples veces y tiene en cuenta la sobrecarga. La opción -memory rastrea asignaciones, útil para encontrar fugas de memoria o copia excesiva. Centre el esfuerzo de optimización en las pocas líneas calientes superiores para máximo impacto.

matlab
% 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 those

Vectorización y preasignación

Las tres mayores ganancias de rendimiento en MATLAB: (1) preasignar matrices antes de rellenarlas en bucles (zeros, NaN, cell), (2) vectorizar operaciones para aprovechar BLAS/LAPACK, y (3) usar patrones amigables al JIT (los bucles simples ahora son rápidos, pero hacer crecer arrays sigue siendo O(n^2)). La indexación lógica reemplaza bucles if/else con una única asignación vectorizada. Evite arrayfun a menos que necesite su soporte GPU — los bucles preasignados simples a menudo son más rápidos. Mida con tic/toc o timeit para verificar mejoras.

matlab
% 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)

Archivos MEX e integración con C

Los archivos MEX le permiten llamar C/C++/Fortran desde MATLAB — esenciales cuando un bucle crítico no puede vectorizarse o al envolver librerías existentes. mex compila un archivo C en un binario .mexw64 (Windows) o .mexa64 (Linux). La moderna C++ MATLAB Data API (R2018a+) es type-safe y más limpia que la antigua API mxGetPr/mxCreate. Para llamar MATLAB desde aplicaciones externas, use la MATLAB Engine API o MATLAB Compiler SDK. loadlibrary envuelve librerías compartidas genéricas sin compilación. Haga profiling primero — solo MEX-ifique el cuello de botella real.

matlab
% 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');

Gestión de memoria y datos grandes

La memoria es a menudo el cuello de botella para cómputos grandes. Use single en lugar de double para halving memoria y duplicar throughput. Las matrices dispersas almacenan solo no ceros. memmapfile mapea un archivo binario en memoria sin cargarlo — perfecto para datasets enormes accedidos secuencialmente. Las tall arrays (con datastore) procesan datos en chunks que no caben en RAM, usando MapReduce por debajo. Desde R2018b, MATLAB puede hacer algunas operaciones in-place (A = A + 1) sin copiar, pero explícito A(:) = ... lo garantiza. Siempre limpie variables grandes cuando termine.

matlab
% 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 place
18

Gráficos avanzados

Subplots y tiledlayout

tiledlayout (R2019b+) es el reemplazo moderno de subplot — mejor espaciado, spanning más fácil y títulos compartidos via title(..., 'tiledtitle'). nexttile([1 2]) se extiende a través de múltiples tiles. subplot(n, m, k) todavía funciona para código heredado pero es menos flexible.

matlab
% 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);

Personalización de ejes

La mayoría de las propiedades de eje son accesibles vía el handle de ejes (gca). xlim/ylim establecen límites; xticks/xticklabels controlan posiciones y etiquetas de ticks. El marcado TeX como \pi renderiza letras griegas. set(gca, ...) es la sintaxis heredada; ax.Property = value es el equivalente moderno (R2014b+).

matlab
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');

Múltiples gráficos y leyenda

hold on le permite superponer múltiples gráficos en los mismos ejes — siempre termine con hold off para evitar sorpresas. 'Location', 'best' elige la esquina con menos solapamiento. La opción 'Interpreter', 'latex' habilita matemáticas LaTeX completas. Pase handles de línea específicos a legend para incluir solo algunos gráficos.

matlab
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');

Gráficos 3D

surf dibuja una superficie coloreada; mesh dibuja un wireframe. contour y contourf muestran proyecciones 2D; clabel añade etiquetas. plot3 grafica curvas paramétricas 3D. view(az, el) establece el ángulo de cámara (azimut, elevación en grados). shading interp suaviza transiciones de color.

matlab
[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, elevation

Animaciones y películas

Las animaciones actualizan datos de gráfico dentro de un bucle con drawnow para refrescar. Para vídeo suave, use VideoWriter (reemplaza el deprecado avifile). getframe captura la figura actual como imagen. Establezca FrameRate antes de abrir el vídeo. Siempre close(v) cuando termine para vaciar el archivo.

matlab
% 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 cdata
19

Operaciones matriciales en profundidad

Esenciales de álgebra lineal

Siempre use A\b (barra invertida) para resolver sistemas lineales — despacha a la factorización correcta (LU, Cholesky, QR) basada en la matriz. inv(A)*b es más lento y numéricamente peor. eig devuelve autovectores como columnas de V y autovalores en la diagonal de D. expm es la matriz exponencial (diferente de exp elemento a elemento).

matlab
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)

Operaciones elemento a elemento vs matriciales

El prefijo punto (.*) significa elemento a elemento; sin él, las operaciones son matriciales. El error de MATLAB más común: x*x donde x es un vector fila — use x*x' para producto escalar o x.*x para cuadrado elemento a elemento. ' es transpuesta conjugada (cambia el signo de partes imaginarias); .' es transpuesta simple.

matlab
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)

Reshape e indexación

MATLAB almacena matrices por columnas, por lo que A(5) en una 4x4 es A(1, 2). La indexación lógica (A(mask)) es potente y rápida — extrae o modifica elementos que cumplen una condición sin bucles. reshape requiere que el recuento total de elementos coincida. permute generaliza la transposición a arrays N-D.

matlab
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 2x3

Matrices dispersas

Las matrices dispersas almacenan solo elementos distintos de cero — esenciales para matrices grandes que son mayormente cero (p. ej., de discretizaciones de EDPs). Las operaciones preservan la dispersión cuando es posible. La barra invertida S\b usa un solver directo disperso (UMFPACK) — mucho más rápido y eficiente en memoria que full()\b para sistemas dispersos grandes. spy visualiza el patrón de dispersión.

matlab
% 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 sparsity

Broadcasting (expansión implícita)

Desde R2016b, MATLAB hace broadcasting automáticamente (como NumPy) — las dimensiones de tamaño 1 se expanden para coincidir. Antes de eso, necesitaba bsxfun. El broadcasting hace el código más limpio: M - mean(M, 2) centra cada fila sin repmat. Las dimensiones deben ser compatibles (iguales o una de ellas es 1).

matlab
% 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 + b
20

Cell Arrays y Structs

Cell arrays

Los cell arrays contienen tipos mixtos. Use {} para acceder a contenidos (elimina el wrapper de celda) y () para obtener una sub-celda. cellfun aplica una función a cada celda — pase 'UniformOutput', false si los resultados son heterogéneos. Los cell arrays son la forma estándar de contener cadenas de diferentes longitudes (pre-string array).

matlab
% 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 blocks

Struct arrays

Los structs agrupan campos con nombre de cualquier tipo. Los struct arrays contienen múltiples registros — {arr.field} reúne un campo a través de todos los elementos en una celda, [arr.field] en una array regular (si compatible). Los campos anidados usan encadenamiento de puntos. fieldnames lista campos; rmfield devuelve una copia sin el campo.

matlab
% 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 fields

Tables (datos tabulares)

Las Tables (R2013b+) son la forma moderna de contener datos tabulares — como un DataFrame en pandas. Acceda a columnas por nombre (T.Age) o índice (T.(2)). sortrows ordena por una o más columnas. readtable/writetable manejan CSV, Excel, etc. summary da estadísticas por columna. Prefiera tables sobre matrices en bruto para datos heterogéneos.

matlab
% 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

Las Timetables (R2016b+) son tables con timestamps de fila. retime remuestrea/agrega (p. ej., 'hourly', 'daily', o TimeStep personalizado). synchronize alinea múltiples timetables a un vector de tiempo común. lag/lead desplazan columnas. Mucho más limpio que gestionar manualmente índices de tiempo en matrices.

matlab
% 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 (diccionarios)

containers.Map es el hash map heredado — funciona en todas las versiones de MATLAB pero es más lento y sin tipar. dictionary (R2022b+) es el reemplazo moderno: tipado, más rápido y soporta búsqueda vectorizada. Use maps cuando necesite búsqueda O(1) por clave en lugar de buscar en un struct array o cell.

matlab
% 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)
21

Optimización

Optimización con restricciones fmincon

fmincon es el caballo de batalla para minimización no lineal con restricciones. La función nonlcon debe devolver [c, ceq] donde c <= 0 (desigualdad) y ceq = 0 (igualdad). deal es una forma limpia de devolver múltiples salidas desde una función anónima. Establezca Algorithm basado en el tipo de problema: 'interior-point' (general), 'sqp' (pequeño/mediano, a menudo más rápido).

matlab
% 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 sin restricciones

fminunc minimiza funciones no lineales sin restricciones. Proporcionar el gradiente (via SpecifyObjectiveGradient) mejora dramáticamente la velocidad y precisión. La aproximación BFGS Hessian por defecto funciona bien para problemas suaves; para grandes, 'lbfgs' limita la memoria. Compruebe exitflag (>0 = convergió) y firstorderopt (debería ser diminuto).

matlab
% 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 problems

Programación lineal linprog

linprog resuelve programas lineales. Para variables enteras/binarias, use intlinprog (reemplaza el deprecado bintprog). intcon lista qué variables están restringidas a enteros. Establezca lb=0, ub=1 para binarias. El algoritmo dual-simplex es el valor por defecto y más rápido para la mayoría de problemas.

matlab
% 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 y ajuste de curvas

lsqcurvefit ajusta modelos paramétricos a datos vía mínimos cuadrados. polyfit es la elección fácil para polinomios. Para R² (coeficiente de determinación), computelo manualmente: 1 - SSE/SST. El algoritmo Levenberg-Marquardt es bueno para problemas sin restricciones; trust-region-reflective maneja cotas.

matlab
% 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;

Optimización global

Las herramientas de optimización global (en el Global Optimization Toolbox) ayudan con problemas no convexos donde los solvers locales se atascan. MultiStart ejecuta un solver local desde muchos inicios aleatorios. GlobalSearch es más inteligente — filtra inicios prometedores. ga (algoritmo genético) y simulannealbnd son sin derivadas. patternsearch es bueno para problemas no suaves.

matlab
% 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]);
22

Procesamiento de imágenes

Lectura y visualización de imágenes

imread devuelve arrays uint8 para la mayoría de formatos de imagen. rgb2gray convierte RGB a escala de grises. im2double escala a [0, 1] — use esto (no double()) antes de procesamiento de coma flotante. imshow auto-escala imágenes double: [0, 1] es el rango esperado. imwrite soporta opciones de calidad/compresión.

matlab
% 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)

Filtrado y convolución

imgaussfilt es el desenfoque gaussiano moderno (reemplaza fspecial('gaussian') + imfilter). medfilt2 es la elección correcta para ruido de sal y pimienta (el filtro de media solo lo emborrona). fspecial crea kernels comunes (sobel, prewitt, laplacian, gaussian, disk, motion). imfilter hace correlación por defecto — pase 'conv' para verdadera convolución.

matlab
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);

Operaciones morfológicas

Las operaciones morfológicas funcionan en imágenes binarias. Erode encoge objetos; dilate los hace crecer. Open (erode luego dilate) elimina ruido pequeño; close (dilate luego erode) rellena pequeños huecos. strel crea elementos estructurantes — disk/square/line/octagon. bwareaopen elimina objetos pequeños; imfill rellena huecos; bwperim extrae bordes.

matlab
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);

Detección de bordes y segmentación

edge con 'canny' es el detector de bordes más robusto (especifique umbrales [low high] y sigma). imbinarize con 'adaptive' maneja iluminación desigual. bwconncomp encuentra componentes conectados; regionprops extrae medidas (Area, Centroid, BoundingBox, etc.). watershed separa objetos que se tocan — compute sobre el gradiente para encontrar bordes.

matlab
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, []);

Color y transformadas

rgb2hsv, rgb2lab convierten espacios de color — HSV es intuitivo para selección de color; L*a*b* separa luminancia del color (bueno para diferencia de color). fft2 + fftshift centran el espectro para filtrado. imresize/imrotate/imcrop son operaciones geométricas — 'bilinear' (por defecto) suele ser mejor; 'nearest' es más rápido pero bloqueado.

matlab
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]
23

GUI/App Designer

Fundamentos de App Designer

App Designer (R2016a+) es la herramienta GUI moderna, reemplazando GUIDE. Los componentes se acceden via app.<Name>. Los callbacks reciben (app, event). Las propiedades personalizadas (en la Code View) comparten estado entre callbacks. Guarde como .mlapp (binario) o exporte a .m. Ejecute escribiendo el nombre de la app en la ventana de comandos.

matlab
% 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.

UI programática con uifigure

uifigure (R2016b+) es el framework UI programático moderno — soporta widgets modernos (gauge, knob, switch, tree) que figure no. Establezca callbacks via las propiedades *Fcn usando funciones anónimas @(src, event) .... uiwait bloquea hasta que la figura se cierra; uiresume la libera.

matlab
% 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);

Componentes UI comunes

Componentes UI modernos: uieditfield (texto o numérico), uibuttongroup (gestiona radio buttons), uicheckbox, uitable (vincula a una tabla), uitabgroup/uitab (pestañas). Todos toman un parent como primer argumento y usan pares Name-Value para propiedades. Los callbacks se disparan en la interacción del usuario; acceda a los nuevos valores via el argumento source.

matlab
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);

Diálogos y prompts

inputdlg recopila entrada de texto; questdlg para sí/no/cancelar; listdlg para selección; uigetfile/uiputfile para selectores de archivos; msgbox/errordlg/warndlg para notificaciones. fullfile une rutas de forma portable (mejor que concatenación de cadenas). Siempre compruebe que el usuario no canceló (retorno vacío u ok == false).

matlab
% 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');

Compartir y desplegar

Para compartir: los archivos .mlapp requieren MATLAB; las apps standalone (via MATLAB Compiler) se ejecutan sin MATLAB pero necesitan el MATLAB Runtime gratuito; las web apps se ejecutan en un navegador via MATLAB Web App Server. Exportar a .m le da código fuente legible. Empaquételo como toolbox para distribución via Add-Ons.

matlab
% 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 deploying
24

E/S de archivos avanzada

E/S de archivos de bajo nivel

fopen devuelve -1 en caso de fallo — siempre compruebe. fgetl lee una línea sin el newline; fgets lo mantiene. fscanf lee datos formateados; fread lee binario. fseek/ftell navegan. Siempre fclose cuando termine (use onCleanup por seguridad: c = onCleanup(@() fclose(fid));).

matlab
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 close

textscan para datos mixtos

textscan es más flexible que fscanf — maneja tipos mixtos, delimitadores personalizados y devuelve un cell array de columnas. 'TreatAsEmpty' convierte placeholders a NaN. 'CollectOutput' agrupa columnas del mismo tipo en una array. fileread slurps todo el archivo como cadena — conveniente para archivos pequeños o procesamiento regex.

matlab
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 matrix

Archivos MAT y save/load

save/load con archivos .mat preservan tipos y estructura de variables. -v7.3 soporta archivos > 2GB (y es el valor por defecto en MATLAB moderno). -append añade variables sin reescribir. Para archivos enormes, cargue solo lo que necesite por nombre. Para exportación de texto, use -ascii (limitado) o writematrix/writetable para más control.

matlab
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 y formatos científicos

HDF5 es el estándar para datasets numéricos grandes — soporta chunking, compresión y dimensiones extensibles. h5read con start/count le permite leer slices sin cargar todo el archivo. NetCDF es común en ciencia climática/oceánica; FITS en astronomía. MATLAB también soporta TIFF, DICOM, audio y formatos de vídeo nativamente.

matlab
% 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 y XML

jsonencode/jsondecode (R2016b+) manejan JSON nativamente. Los Structs se convierten en objetos JSON; los cell arrays en arrays. Para XML, xmlread devuelve un objeto Java DOM — use métodos Java para recorrerlo. xmlwrite serializa un DOM de vuelta a un archivo. Para XML complejo, considere xml2struct de terceros o la API DOM directamente.

matlab
% 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);
25

Computación paralela

Bucles parfor

parfor ejecuta iteraciones de bucle en paralelo entre workers. Las iteraciones deben ser independientes. Las variables se clasifican: sliced (cada iteración toca un índice único), broadcast (solo lectura), reduction (combinadas con op asociativo como + o *) y temp (creadas dentro). La clasificación determina qué está permitido.

matlab
% 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, :));
end

spmd y arrays distribuidas

spmd ejecuta el mismo código en todos los workers, con labindex identificando cada uno. Use para algoritmos data-parallel donde los workers se comunican (p. ej., estilo MPI). Las arrays distribuidas esparcen una matriz grande entre workers — las operaciones sobre ellas permanecen distribuidas; gather() trae el resultado de vuelta al cliente. Composite almacena valores por worker.

matlab
% 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 value

gpuArray

gpuArray mueve datos a la GPU; las operaciones sobre gpuArrays se ejecutan en la GPU automáticamente. gather() trae los datos de vuelta. Las operaciones elemento a elemento y de multiplicación matricial ven la mayor aceleración; el código escalar o con ramificación no. arrayfun sobre gpuArrays le permite ejecutar funciones personalizadas elemento a elemento en la GPU sin escribir CUDA.

matlab
% 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 y job

batch ejecuta una función o script en segundo plano — útil para trabajos largos que no quiere bloquear la sesión de MATLAB. wait(job) bloquea hasta que termine; fetchOutputs recupera resultados. Siempre delete(job) para liberar recursos. 'Pool', N usa N workers adicionales para parfor dentro de la función batch.

matlab
% 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 pool

Consejos de rendimiento

Preasigne arrays (zeros/ones) — hacer crecer arrays en bucles es el asesino de rendimiento #1 de MATLAB. Vectorice (sin(x) en lugar de bucle) — más claro y a menudo más rápido. El JIT hace los bucles simples rápidos, pero la vectorización sigue ganando para matemáticas. profile viewer encuentra cuellos de botella. Use precisión simple para datos enormes; escriba archivos MEX para verdaderos hotspots.

matlab
% 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.c
26

Orientación a objetos

Definición de clase

Guarde classdef en un archivo llamado <ClassName>.m. Las propiedades contienen datos; los métodos definen comportamiento. El constructor debe llamarse como la clase y manejar nargin==0 (llamado cuando no hay args). Las propiedades dependent se computan al acceder via métodos get.X. disp sobrescribe la visualización. Los métodos static no toman obj.

matlab
% 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
end

Clases value vs handle

Las clases value se copian al asignar (como int o struct); las clases handle pasan por referencia (como objetos Java). Para objetos mutables (una conexión a base de datos, un componente UI), use handle. Las clases value son más simples y seguras para datos inmutables. Las clases handle heredan de handle y soportan events/listeners y un destructor delete.

matlab
% 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() method

Herencia y polimorfismo

Subclase con <. Llame al constructor de superclase con obj@SuperClass(args). El polimorfismo funciona naturalmente — llame al método en el tipo base y se ejecuta el override correcto. MATLAB soporta herencia múltiple (separe superclases con &), pero solo una puede ser clase concreta; el resto deben ser interfaces.

matlab
% 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
  ...
end

Eventos y listeners

Los eventos requieren una clase handle. Declare eventos en un bloque events. notify dispara un evento; addlistener se suscribe. Los listeners pueden ser funciones o funciones anónimas @(src, event). Los datos de evento personalizados heredan de event.EventData. Los listeners se eliminan cuando el objeto source se elimina (o puede eliminarlos explícitamente).

matlab
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));

Enumeración y propiedades

Las clases de enumeración definen instancias fijas — útiles para máquinas de estados, opciones y tipos. Cada valor enum puede llevar datos via propiedades. Los atributos de propiedad controlan el acceso: SetAccess=private hace solo lectura desde fuera; Constant para constantes en tiempo de compilación; Hidden oculta de la visualización; Access={?Class1, ?Class2} restringe a clases específicas.

matlab
% 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
end

Was this helpful?