Calcolatore Distanza tra Due Punti in MATLAB
Calcola la distanza euclidea, Manhattan e altre metriche tra due punti in coordinate cartesiane o polari, con visualizzazione grafica dei risultati.
-
Guida Completa: Come Calcolare la Distanza tra Due Punti in MATLAB
Il calcolo della distanza tra due punti è un’operazione fondamentale in matematica, ingegneria e scienze dei dati. MATLAB, con le sue potenti funzioni matematiche e capacità di visualizzazione, offre diversi metodi per calcolare varie metriche di distanza. Questa guida approfondita esplorerà:
- Le basi matematiche delle diverse metriche di distanza
- Come implementare questi calcoli in MATLAB
- Applicazioni pratiche in diversi campi
- Ottimizzazione delle prestazioni per grandi dataset
- Visualizzazione dei risultati
1. Fondamenti Matematici delle Metriche di Distanza
Esistono diverse metriche per calcolare la distanza tra due punti in uno spazio n-dimensionale. Le più comuni includono:
1.1 Distanza Euclidea
La distanza euclidea è la “distanza normale” che misuriamo nella vita quotidiana. Per due punti P = (x₁, y₁) e Q = (x₂, y₂) in uno spazio 2D, la formula è:
d = √((x₂ - x₁)² + (y₂ - y₁)²)
1.2 Distanza di Manhattan
Conosciuta anche come distanza L₁, è la somma delle differenze assolute delle coordinate:
d = |x₂ - x₁| + |y₂ - y₁|
1.3 Distanza di Chebyshev
Chiamata anche distanza del massimo, è definita come il massimo valore assoluto delle differenze tra le coordinate:
d = max(|x₂ - x₁|, |y₂ - y₁|)
1.4 Distanza di Minkowski
Una generalizzazione che include le distanze euclidea e Manhattan come casi speciali:
d = (|x₂ - x₁|ᵖ + |y₂ - y₁|ᵖ)^(1/ᵖ)
Dove p ≥ 1. Quando p = 2, otteniamo la distanza euclidea; quando p = 1, la distanza di Manhattan.
2. Implementazione in MATLAB
MATLAB offre diverse funzioni integrate e metodi per calcolare le distanze. Ecco le implementazioni pratiche:
2.1 Utilizzo della funzione pdist
La funzione pdist calcola le distanze tra coppie di osservazioni:
% Definizione dei punti P = [x1 y1]; Q = [x2 y2]; % Calcolo distanza euclidea distance = pdist([P; Q], 'euclidean'); % Per altre metriche: % distance = pdist([P; Q], 'cityblock'); % Manhattan % distance = pdist([P; Q], 'chebychev'); % Chebyshev % distance = pdist([P; Q], 'minkowski', p); % Minkowski
2.2 Implementazione Manuali delle Formule
Per un controllo maggiore, è possibile implementare direttamente le formule:
% Distanza Euclidea euclidean_dist = sqrt((x2 - x1)^2 + (y2 - y1)^2); % Distanza Manhattan manhattan_dist = abs(x2 - x1) + abs(y2 - y1); % Distanza Chebyshev chebyshev_dist = max(abs(x2 - x1), abs(y2 - y1)); % Distanza Minkowski (p=3) p = 3; minkowski_dist = (abs(x2 - x1)^p + abs(y2 - y1)^p)^(1/p);
2.3 Gestione di Dati Multidimensionali
Per punti in spazi con più di 2 dimensioni, le funzioni MATLAB si adattano automaticamente:
% Punti in 3D P = [x1 y1 z1]; Q = [x2 y2 z2]; % Distanza euclidea in 3D distance_3d = pdist([P; Q], 'euclidean'); % Implementazione manuale euclidean_3d = sqrt((x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2);
3. Visualizzazione dei Risultati
MATLAB eccelle nella visualizzazione dei dati. Ecco come rappresentare graficamente i punti e la distanza:
% Definizione dei punti
P = [x1 y1];
Q = [x2 y2];
% Creazione del grafico
figure;
hold on;
plot(P(1), P(2), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');
plot(Q(1), Q(2), 'bo', 'MarkerSize', 10, 'MarkerFaceColor', 'b');
plot([P(1) Q(1)], [P(2) Q(2)], 'k--', 'LineWidth', 1.5);
% Aggiunta di etichette
text(P(1), P(1), 'P(x₁,y₁)', 'VerticalAlignment', 'bottom', 'HorizontalAlignment', 'right');
text(Q(1), Q(1), 'Q(x₂,y₂)', 'VerticalAlignment', 'bottom', 'HorizontalAlignment', 'left');
% Formattazione
axis equal;
grid on;
title('Distanza tra due punti');
xlabel('Asse X');
ylabel('Asse Y');
legend('Punto P', 'Punto Q', 'Distanza', 'Location', 'best');
% Aggiunta della distanza come annotazione
mid_x = (P(1) + Q(1)) / 2;
mid_y = (P(2) + Q(2)) / 2;
distance = pdist([P; Q], 'euclidean');
text(mid_x, mid_y, sprintf('d = %.2f', distance), 'BackgroundColor', 'w', 'EdgeColor', 'k');
4. Applicazioni Pratiche
Il calcolo delle distanze ha numerose applicazioni in vari campi:
| Campo di Applicazione | Utilizzo delle Metriche di Distanza | Metrica Più Utilizzata |
|---|---|---|
| Robotica | Pianificazione del percorso, evitamento ostacoli | Euclidea, Manhattan |
| Machine Learning | Algoritmi k-NN, clustering (k-means) | Euclidea, Minkowski |
| Geografia/GIS | Calcolo distanze tra coordinate geografiche | Haversine (per coordinate sferiche) |
| Elaborazione Immagini | Confronti tra immagini, riconoscimento pattern | Euclidea, Chebyshev |
| Bioinformatica | Allineamento sequenze, analisi strutture proteiche | Euclidea, Manhattan |
4.1 Esempio in Machine Learning: k-Nearest Neighbors (k-NN)
Nel algoritmo k-NN, la scelta della metrica di distanza influisce significativamente sulle prestazioni:
% Dati di esempio X = rand(100, 2); % 100 punti in 2D y = randi([0 1], 100, 1); % Etichette binarie % Nuovo punto da classificare new_point = [0.5, 0.5]; % Calcolo distanze con diverse metriche dist_euclidean = pdist2(X, new_point, 'euclidean'); dist_manhattan = pdist2(X, new_point, 'cityblock'); dist_chebyshev = pdist2(X, new_point, 'chebychev'); % Classificazione con k=5 k = 5; [~, idx_euclid] = mink(dist_euclidean, k); [~, idx_manhat] = mink(dist_manhattan, k); [~, idx_cheby] = mink(dist_chebyshev, k); % Voto maggioritario pred_euclid = mode(y(idx_euclid)); pred_manhat = mode(y(idx_manhat)); pred_cheby = mode(y(idx_cheby));
5. Ottimizzazione delle Prestazioni
Per dataset di grandi dimensioni, il calcolo delle distanze può diventare computazionalmente intensivo. Ecco alcune strategie di ottimizzazione:
- Vettorizzazione: Utilizzare operazioni vettoriali invece di loop
for. - Funzioni ottimizzate: Preferire
pdist2per calcoli tra molti punti. - Parallelizzazione: Utilizzare
parforper calcoli paralleli. - Approssimazione: Per applicazioni dove la precisione non è critica, considerare metodi di approssimazione come Locality-Sensitive Hashing (LSH).
- Memorizzazione: Cache dei risultati per query ripetute.
% Esempio di vettorizzazione vs loop
n = 1e6;
X = rand(n, 2);
query = rand(1, 2);
% Metodo lento con loop
tic;
dist_loop = zeros(1, n);
for i = 1:n
dist_loop(i) = norm(X(i,:) - query);
end
time_loop = toc;
% Metodo vettorizzato (molto più veloce)
tic;
dist_vector = sqrt(sum((X - query).^2, 2));
time_vector = toc;
fprintf('Tempo con loop: %.4f s\nTempo vettorizzato: %.4f s\n', time_loop, time_vector);
fprintf('Speedup: %.1fx\n', time_loop/time_vector);
6. Confronto tra Metriche di Distanza
La scelta della metrica dipende dal contesto specifico. Ecco un confronto delle proprietà:
| Metrica | Formula | Invarianza alla Rotazione | Invarianza alla Traslazione | Sensibilità ai Valori Anomali | Complessità Computazionale |
|---|---|---|---|---|---|
| Euclidea | √(Σ(x_i – y_i)²) | Sì | Sì | Media | O(n) |
| Manhattan | Σ|x_i – y_i| | No | Sì | Bassa | O(n) |
| Chebyshev | max(|x_i – y_i|) | Sì | Sì | Alta | O(n) |
| Minkowski (p=3) | (Σ|x_i – y_i|³)^(1/3) | Sì | Sì | Alta | O(n) |
| Coseno | 1 – (x·y)/(|x||y|) | Sì | No | Bassa | O(n) |
7. Errori Comuni e Best Practices
Quando si lavorano con distanze in MATLAB, è importante evitare questi errori comuni:
- Dimenticare la normalizzazione: Quando si confrontano caratteristiche con scale diverse, è essenziale normalizzare i dati prima di calcolare le distanze.
- Scegliere la metrica sbagliata: Ad esempio, usare la distanza euclidea per dati testuali può dare risultati fuorvianti.
- Ignorare la dimensionalità: In spazi ad alta dimensionalità, molte metriche diventano meno significative (“malattia della dimensionalità”).
- Non gestire i valori mancanti: I NaN nei dati possono causare errori nei calcoli.
- Trascurare la precisione numerica: Per distanze molto piccole o molto grandi, considerare l’uso di
vpa(Variable Precision Arithmetic) dal Symbolic Math Toolbox.
Best Practices:
- Sempre visualizzare i dati per comprendere meglio le relazioni di distanza.
- Testare diverse metriche per determinare quale funziona meglio per il problema specifico.
- Per applicazioni critiche, validare i risultati con implementazioni alternative.
- Documentare sempre quale metrica di distanza è stata utilizzata per garantire riproducibilità.
8. Estensioni Avanzate
Per applicazioni più avanzate, MATLAB offre ulteriori possibilità:
8.1 Distanze tra Insiemi di Punti
Calcolare distanze tra tutti i punti in due set diversi:
A = rand(50, 2); % 50 punti in 2D B = rand(30, 2); % 30 punti in 2D % Matrice delle distanze (50x30) D = pdist2(A, B, 'euclidean'); % Distanza minima tra i due set min_distance = min(D(:)); % Punti più vicini [min_val, idx] = min(D(:)); [row, col] = ind2sub(size(D), idx); closest_A = A(row, :); closest_B = B(col, :);
8.2 Distanze in Spazi Non Euclidei
Per dati su superfici curve (come la Terra), è necessario utilizzare metriche specifiche:
% Coordinate geografiche (latitudine, longitudine) in gradi
lat1 = 41.9028; lon1 = 12.4964; % Roma
lat2 = 40.7128; lon2 = -74.0060; % New York
% Conversione in radianti
lat1 = deg2rad(lat1); lon1 = deg2rad(lon1);
lat2 = deg2rad(lat2); lon2 = deg2rad(lon2);
% Formula Haversine
R = 6371; % Raggio terrestre in km
a = sin((lat2-lat1)/2)^2 + cos(lat1) * cos(lat2) * sin((lon2-lon1)/2)^2;
c = 2 * atan2(sqrt(a), sqrt(1-a));
distance = R * c;
fprintf('Distanza tra Roma e New York: %.2f km\n', distance);
8.3 Distanze tra Distribuzioni di Probabilità
Per confrontare distribuzioni invece di punti singoli:
% Dati di esempio data1 = normrnd(0, 1, 1000, 1); data2 = normrnd(0.5, 1.2, 1000, 1); % Divergenza di Kullback-Leibler [counts1, edges1] = histcounts(data1, 'Normalization', 'pdf'); [counts2, edges2] = histcounts(data2, 'Normalization', 'pdf'); % Assicurarsi che gli edges siano allineati edges = linspace(min([data1; data2]), max([data1; data2]), 50); [counts1, ~] = histcounts(data1, edges, 'Normalization', 'pdf'); [counts2, ~] = histcounts(data2, edges, 'Normalization', 'pdf'); % Calcolo KL divergence kl_div = sum(counts1 .* log(counts1 ./ counts2)); % Distanza di Wasserstein (Earth Mover's Distance) [~, ~, emd] = emd_hat_gd_2(counts1', counts2', edges(2)-edges(1));
9. Integrazione con Altri Strumenti
MATLAB può essere integrato con altri linguaggi e strumenti per applicazioni più ampie:
9.1 Chiamare MATLAB da Python
Utilizzando l’API MATLAB Engine per Python:
# In Python
import matlab.engine
eng = matlab.engine.start_matlab()
x1, y1 = 1.0, 2.0
x2, y2 = 4.0, 6.0
# Chiamata a funzione MATLAB
distance = eng.eval("sqrt((4.0-1.0)^2 + (6.0-2.0)^2)")
print(f"Distanza calcolata da MATLAB: {distance}")
eng.quit()
9.2 Esportare Risultati per Visualizzazione Web
Convertire i risultati MATLAB in formati compatibili con librerie JavaScript come D3.js:
% In MATLAB
points = [1 2; 4 6; 7 3; 2 8];
dist_matrix = squareform(pdist(points));
% Esportazione in JSON
json_str = jsonencode(struct(...
'points', points, ...
'distances', dist_matrix, ...
'metric', 'euclidean'));
% Salvataggio su file
fid = fopen('distance_data.json', 'w');
fprintf(fid, '%s', json_str);
fclose(fid);
10. Risorse per Approfondire
Per ulteriori studi sulle metriche di distanza e loro applicazioni in MATLAB:
- Documentazione ufficiale MATLAB su metriche di distanza
- Corsi di matematica del MIT OpenCourseWare (in particolare “Introduction to Algorithms” per applicazioni computazionali)
- Progetti NIST su standard di misurazione
- Libro: “Data Clustering: Algorithms and Applications” di Charu C. Aggarwal e Chandan K. Reddy (capitoli sulle metriche di similarità)
- Libro: “MATLAB Guide” di Desmond J. Higham e Nicholas J. Higham (per ottimizzazione del codice MATLAB)
11. Esempi Pratici Completi
Ecco alcuni esempi completi che combinano diversi concetti:
11.1 Analisi di Cluster con Diverse Metriche
% Generazione dati
rng(1); % Per riproducibilità
X = [randn(100,2)*0.75+1; randn(100,2)*0.5-1];
% Calcolo distanze con diverse metriche
metrics = {'euclidean', 'cityblock', 'chebychev', 'minkowski'};
p = 3; % per Minkowski
figure;
for i = 1:length(metrics)
subplot(2, 2, i);
if strcmp(metrics{i}, 'minkowski')
D = pdist(X, metrics{i}, p);
else
D = pdist(X, metrics{i});
end
Z = linkage(D, 'ward');
dendrogram(Z, 0);
title(sprintf('Dendrogramma con metrica: %s', metrics{i}));
end
sgtitle('Confronto tra metriche di distanza per clustering gerarchico');
11.2 Ottimizzazione del Percorso con Distanze
% Problema del commesso viaggiatore semplificato
cities = 10;
locations = rand(cities, 2);
% Matrice delle distanze
D = squareform(pdist(locations, 'euclidean'));
% Soluzione con algoritmo del vicino più vicino (semplificato)
n = size(D, 1);
unvisited = true(1, n);
path = zeros(1, n);
path(1) = 1; % Partenza dalla prima città
unvisited(1) = false;
for i = 2:n
last = path(i-1);
[~, next] = min(D(last, unvisited));
next = find(unvisited, next);
path(i) = next;
unvisited(next) = false;
end
% Distanza totale del percorso
total_distance = 0;
for i = 2:length(path)
total_distance = total_distance + D(path(i-1), path(i));
end
total_distance = total_distance + D(path(end), path(1)); % Ritorno al punto di partenza
% Visualizzazione
figure;
plot(locations(path, 1), locations(path, 2), 'bo-', 'LineWidth', 1.5, 'MarkerFaceColor', 'b');
hold on;
plot([locations(path(end), 1) locations(path(1), 1)], ...
[locations(path(end), 2) locations(path(1), 2)], 'b--');
for i = 1:cities
text(locations(i,1), locations(i,2), sprintf(' C%d', i), 'FontSize', 12);
end
title(sprintf('Percorso ottimizzato (distanza totale: %.2f)', total_distance));
axis equal;
12. Conclusione
Il calcolo delle distanze tra punti è un’operazione fondamentale con applicazioni che spaziano dalla matematica pura all’ingegneria applicata. MATLAB offre strumenti potenti e flessibili per implementare diverse metriche di distanza, visualizzare i risultati e integrare questi calcoli in applicazioni più complesse.
Ricordate che:
- La scelta della metrica dipende dal contesto specifico del problema.
- La visualizzazione è cruciale per comprendere i risultati.
- Per dataset di grandi dimensioni, l’ottimizzazione del codice è essenziale.
- MATLAB offre funzioni integrate che spesso sono più efficienti delle implementazioni manuali.
- Sperimentare con diverse metriche può portare a nuove intuizioni nei vostri dati.
Con le conoscenze acquisite in questa guida, sarete in grado di affrontare con sicurezza qualsiasi problema che richieda il calcolo di distanze in MATLAB, dalle applicazioni più semplici a quelle più complesse e specializzate.