titulo - Matlab, genera y traza una nube de puntos distribuida dentro de un triángulo
suptitle matlab (4)
Intento generar una nube de puntos 2D (uniformemente) distribuidos dentro de un triángulo. Hasta ahora, he logrado lo siguiente:
El código que he usado es este:
N = 1000;
X = -10:0.1:10;
for i=1:N
j = ceil(rand() * length(X));
x_i = X(j);
y_i = (10 - abs(x_i)) * rand;
E(:, i) = [x_i y_i];
end
Sin embargo, los puntos no están distribuidos uniformemente, como se ve claramente en las esquinas izquierda y derecha. ¿Cómo puedo mejorar ese resultado? He estado tratando de buscar las diferentes formas también, sin suerte.
Esa concentración de puntos se esperaría de la forma en que estás construyendo los puntos. Tus puntos se distribuyen por igual a lo largo del eje X. En los extremos del triángulo hay aproximadamente la misma cantidad de puntos presentes en el centro del triángulo, pero se distribuyen a lo largo de una región mucho más pequeña.
El primer y mejor enfoque que puedo pensar: fuerza bruta . Distribuya los puntos por igual en una región más grande y luego elimine los que están fuera de la región en la que está interesado.
N = 1000;
points = zeros(N,2);
n = 0;
while (n < N)
n = n + 1;
x_i = 20*rand-10; % generate a number between -10 and 10
y_i = 10*rand; % generate a number between 0 and 10
if (y_i > 10 - abs(x_i)) % if the points are outside the triangle
n = n - 1; % decrease the counter to try to generate one more point
else % if the point is inside the triangle
points(n,:) = [x_i y_i]; % add it to a list of points
end
end
% plot the points generated
plot(points(:,1), points(:,2), ''.'');
title (''1000 points randomly distributed inside a triangle'');
El resultado del código que publiqué:
un importante descargo de responsabilidad : ¡distribuido aleatoriamente no significa distribuido "uniformemente"! Si genera datos aleatoriamente a partir de una distribución uniforme, eso no significa que estará "distribuido uniformemente" a lo largo del triángulo. Verá, de hecho, algunos conglomerados de puntos.
Puedes imaginar que el triángulo se divide verticalmente en dos mitades, y mueve una mitad para que, junto con el otro, forme un rectángulo. Ahora muestras uniformemente en el rectángulo, lo cual es fácil, y luego mueves el medio triángulo hacia atrás.
Además, es más fácil trabajar con longitudes de unidad (el rectángulo se convierte en un cuadrado) y luego estirar el triángulo a las dimensiones deseadas.
x = [-10 10]; % //triangle base
y = [0 10]; % //triangle height
N = 1000; %// number of points
points = rand(N,2); %// sample uniformly in unit square
ind = points(:,2)>points(:,1); %// points to be unfolded
points(ind,:) = [2-points(ind,2) points(ind,1)]; %// unfold them
points(:,1) = x(1) + (x(2)-x(1))/2*points(:,1); %// stretch x as needed
points(:,2) = y(1) + (y(2)-y(1))*points(:,2); %// stretch y as needed
plot(points(:,1),points(:,2),''.'')
Podemos generalizar este caso. Si desea muestrear puntos de un (simple) n-1-dimensional simple en el espacio euclidiano UNIFORMEMENTE (no necesariamente un triángulo, puede ser cualquier politopo convexo), simplemente muestree un vector de una distribución simétrica de Dirichlet n-dimensional con el parámetro 1 - estas son las coordenadas convexas (o baricéntricas) relativas a los vértices del politopo.
Primero debe preguntarse qué haría que los puntos dentro de un triángulo se distribuyeran uniformemente.
Para abreviar una historia larga, dados los tres vértices del triángulo, necesitas transformar dos valores aleatorios distribuidos uniformemente de la siguiente manera:
N = 1000; % # Number of points
V = [-10, 0; 0, 10; 10, 0]; % # Triangle vertices, pairs of (x, y)
t = sqrt(rand(N, 1));
s = rand(N, 1);
P = (1 - t) * V(1, :) + bsxfun(@times, ((1 - s) * V(2, :) + s * V(3, :)), t);
Esto producirá un conjunto de puntos que están uniformemente distribuidos dentro del triángulo especificado:
scatter(P(:, 1), P(:, 2), ''.'')
Tenga en cuenta que esta solución no implica la manipulación condicional repetida de números aleatorios, por lo que potencialmente no puede caer en un ciclo sin fin.
Para leer más, echa un vistazo a este artículo .