How can i generate random-uniform points in the surface of a N-dimensional cube with edge E?
There is a code for generating for a N-dimensional sphere, but I can't figure it out how can I generate it for a cube.
The nice thing with the N-dimensional hypercube is that its faces are hypercubes of dimension (N-1). Therefore I would proceed in four steps steps.
Draw a random integer called d in the range 1..N to select the hypercube face direction. d=randi(N)
To select a specific face among the two possible ones, draw a random integer called s which can take either of the two values: 0 or 1. s =randi(2)-1
Draw a random uniformly distributed vector called v of length N in the range 0..1. v=rand(N,1)
replace s as the d-th coordinate in v and multiply the result by the edge length E. v(d)=s, v=E*v
Plotting 1000 points on the surface or the 3-d cube of edge-length 2 would we something like:
N=3;
E=2;
Nsamples=1000;
d=randi(N,1,Nsamples);
s =randi(2,1,Nsamples)-1;
v=rand(N,Nsamples);
for i=1:Nsamples
v(d(i),i)=s(i);
end
v = E*v;
plot3(v(1,:),v(2,:),v(3,:),'.');
This implementation is probably not the best in terms of pure efficiency, but you understand how it works.
Hope this helps.
Adrien.
Related
I am trying to randomly generate uniformly distributed vectors, which are of Euclidian length of 1. By uniformly distributed I mean that each entry (coordinate) of the vectors is uniformly distributed.
More specifically, I would like to create a set of, say, 1000 vectors (lets call them V_i, with i=1,…,1000), where each of these random vectors has unit Euclidian length and the same dimension V_i=(v_1i,…,v_ni)' (let’s say n = 5, but the algorithm should work with any dimension). If we then look on the distribution of e.g. v_1i, the first element of each V_i, then I would like that this is uniformly distributed.
In the attached MATLAB example you see that you cannot simply draw random vectors from a uniform distribution and then normalize the vectors to Euclidian length of 1, as the distribution of the elements across the vectors is then no longer uniform.
Is there a way to generate this set of vectors such, that the distribution of the single elements across the vector-set is uniform?
Thank you for any ideas.
PS: MATLAB is our Language of choice, but solutions in any languages are, of course, welcome.
clear all
rng('default')
nvar=5;
sample = 1000;
x = zeros(nvar,sample);
for ii = 1:sample
y=rand(nvar,1);
x(:,ii) = y./norm(y);
end
hist(x(1,:))
figure
hist(x(2,:))
figure
hist(x(3,:))
figure
hist(x(4,:))
figure
hist(x(5,:))
What you want cannot be accomplished.
Vectors with a length of 1 sit on a circle (or sphere or hypersphere depending on the number of dimensions). Let's focus on the 2D case, if it cannot be done there, it will be clear that it cannot be done with more dimensions either.
Because the points are on a circle, their x and y coordinates are dependent, the one can be computed based on the other. Thus, the distributions of x and y coordinates cannot be defined independently. We can define the distribution of the one, generate random values for it, but the other coordinate must be computed from the first.
Let's make points on a half circle with a uniform x coordinate (can be extended to a full circle by adding a random sign to the y coordinate):
N = 1000;
x = 2 * rand(N,1) - 1;
y = sqrt(1 - x.^2);
plot(x,y,'.')
axis equal
histogram(y)
The plot generates shows a clearly non-uniform distribution, with many more samples generated near y=1 than near y=0. If we add a random sign to the y-coordinate we'd have more samples near y=1 and y=-1 than near y=0.
i am having 3D matrix in which most of the values are zeros but there are some nonzeros values.
when I am plotting this 3D matrix in matlab I am getting plot like as below
here u can see there are two groups of points are nearer to each other(that's why the color became dark) and two individual group of points is far away....
so my objective is to cluster that two nearer group of points and make it as one cluster1 and other two will be called as cluster2 and cluster3 ....
I tried kmeans clustering, BIC clustering...but as kmeans clustering is basically build up for 2D data input, I faced hurdle there ...then I reshape 3D matrix into 2D matrix but still I am getting another error Subscripted assignment dimension mismatch
so could u plz come out with some fruitful idea to do this......
Based on your comment that you used vol3d I assume that your data has to interpreted this way. If your data-matrix is called M, try
[A,B,C] = ind2sub(size(M),find(M));
points = [A,B,C];
idx = kmeans(points,3);
Here, I assumed that M(i,j,k) = 1 means that you have measured a point with properties i,j and k, which in your case would be velocity, angle and range.
In matlab, how to fill up the Cartesian plane with randomly distributed points?
That is, for each coordinate x(i,j) in the graph, a point is placed or is not placed based on some random criteria (for example a point is placed there iff a random number is > 0).
Seems like this should be easy to implement, but I'm stumped.
just use rand as usual,
A=rand(N,M)
will create a matrix of size NxM of random numbers between 0 and 1 (rand(N) will create a NxN matrix) . You can then select A>0.9 to select only those point at which A>0.9...
For example:
A=rand(50)>0.9;
imshow(A);
I have a 3-by-N matrix X whose columns are vectors on the unit sphere (i.e., the Euclidean length of each vector is 1), and I have a 1-by-N vector Theta whose entries are all angles between 0 and pi. For each i, there is a circle on the sphere centered at X(:,i) defined as the set of all points that have the angle Theta(i) with X(:,i). I would like to get one uniform sample from the circle for each i, avoiding for loops because they can be slow in Matlab. I know that in vectorized Matlab code I can easily get one sample each from all circles with angles in Theta if I assume the center of all circles is [0,0,1], and then I know how to get a rotation matrix (using Rodrigues rotation formula) that rotates [0,0,1] to another desired vector x, so for each i, I can just apply this rotation matrix to the sample point I obtained assuming [0,0,1] was the center.
I would like to this for all i without for loops, i.e. using array/matrix/vector notation.
If you're using Rodrigues' rotation formula, you're trying to convert from axis-angle representation to rotation matrices. You're in luck. I happen to have written fast vectorized code to do exactly what I believe you're asking about. You can can find the code here: axang2rotmat.m. Use is pretty straightforward (read the help):
n = 1e3; % Number of axis-angles and rotation matrices
th = pi*rand(1,n); % Random rotation angles between 0 and pi
v = normc(rand(3,n)); % Random rotation vectors, normalized across columns
R = axang2rotmat(v,th); % Generate n rotation matrices, R is 3-by-3-n
Note, the above code is just to demonstrate the use of axang2rotmat and won't give you uniformly sampled rotation matrices (See Miles, Biometrika 1962 for details on why and workaround). I recommend that you calculate random rotation matrices directly, however. You can us another of my functions for that: randrotmat.m.
I also have code to convert back from rotation matrices to axis-angle and check if a particular matrix is a rotation matrix here.
I wanted to generate a set of coordinates distributed uniformly at random within a ball of radius R. Is there any way to do this in Matlab without for loops, in a matrix-like form?
Thanks
UPDATE:
I'm sorry for the confusion. I only need to generate n points uniformly at random over a circle of radius R, not a sphere.
the correct answer is here http://mathworld.wolfram.com/DiskPointPicking.html. The distribution is known as "Disk point picking"
I was about to mark this as a duplicate of a previous question on generating uniform distribution of points in a sphere, but I think you deserve the benefit of doubt here, as although there's a matlab script in the question, most of that thread is python.
This little function given in the question (and I'm pasting it directly from there), is what you need.
function X = randsphere(m,n,r)
% This function returns an m by n array, X, in which
% each of the m rows has the n Cartesian coordinates
% of a random point uniformly-distributed over the
% interior of an n-dimensional hypersphere with
% radius r and center at the origin. The function
% 'randn' is initially used to generate m sets of n
% random variables with independent multivariate
% normal distribution, with mean 0 and variance 1.
% Then the incomplete gamma function, 'gammainc',
% is used to map these points radially to fit in the
% hypersphere of finite radius r with a uniform % spatial distribution.
% Roger Stafford - 12/23/05
X = randn(m,n);
s2 = sum(X.^2,2);
X = X.*repmat(r*(gammainc(s2/2,n/2).^(1/n))./sqrt(s2),1,n);
To learn why you can't just use uniform random variable for all three co-ordinates as one might think is the correct way, give this article a read.
For the sake of completeness, here is some MATLAB code for a point-culling solution. It generates a set of random points within a unit cube, removes points that are outside a unit sphere, and scales the coordinate points up to fill a sphere of radius R:
XYZ = rand(1000,3)-0.5; %# 1000 random 3-D coordinates
index = (sum(XYZ.^2,2) <= 0.25); %# Find the points inside the unit sphere
XYZ = 2*R.*XYZ(index,:); %# Remove points and scale the coordinates
One key drawback to this point-culling method is that it makes it difficult to generate a specific number of points. For example, if you want to generate 1000 points within your sphere, how many do you have to create in the cube before culling them? If you scale up the number of points generated in the cube by a factor of 6/pi (i.e. the ratio of the volume of a unit cube to a unit sphere), then you can get close to the number of desired points in the sphere. However, since we're dealing with (pseudo)random numbers after all, we can never be absolutely certain we will generate enough points that fall in the sphere.
In short, if you want to generate a specific number of points, I'd try out one of the other solutions suggested. Otherwise, the point-culling solution is nice and simple.
Not sure if I understand your question correctly, but can't you just generate any random number inside a sphere by setting φ, θ and r, assigned to random numbers?