Matlab: Efficiently do SVD many times? (to triangulate a 3D point cloud) - matlab

The context: Performing triangulation on many point pairs, 2d to 3d. The equation I have is:
Mv = 0 with M = [P1 -x1 0] (6x6 matrix) v = [X, lambda1, lambda2]^T (6x1)
[P2 0 -x2]
where P1, P2 are 3x4 projection matrices, x1 and x2 are 2D projections of the 3D point X, and the lambdas are just parameters for representing the line-plane intersection (not important). All of this is done in homogeneous coordinates, so M is 6x6.
The problem: By doing a SVD on M, I can get a least squares triangulation of the two 2D points x1 and x2 to get a 3D point. If I repeat this on all point pairs I can obtain a point cloud. However, it is extremely inefficient to repeatedly compute SVD that many times in a for loop; mainly, I would have to construct each matrix by inserting the points first, then doing SVD. Is there a way I can vectorize the SVD computation on a list of point pairs?
Any suggestions would be greatly appreciated!

There is now a triangulate function in the Computer Vision System Toolbox.

Related

Get nearest point on a sphere in MATLAB

I want to get the point on a n-dimensional sphere, which is nearest to a given point p with the same dimension.
My sphere is created by the dot-product of a positive definite Matrix A.
All points on the sphere are characterized by:
x'*A*x = const
Mathematically, I am searching for the x where
(p-x)'*A*(p-x)
is minimal. (x is a point on the sphere)
I didn't find any MATLAB function for this problem, nor do I have an idea on how to solve this problem in n dimensions.

Finding the shortest distance between a 2D array of peaks

I'm trying to use MatLab to help in automated analysis of microscopy data from our lab. We have images that consist of 2D arrays of points that correspond to atom positions. We would first like to fit these positions to Gaussians, then find the shortest distance between the positions and draw vectors between them.
I've been using the Fast 2D Peak Finder to locate the peak positions and it works quite well. However, I'm having trouble identifying the shortest distances and plotting vectors between them. Does anyone have an idea for how this might work? Thanks for your help!
Assuming that you identify n peaks and store their coordinates in n-by-2 matrix X, you could calculate the pairwise distance between these peaks using D = pdist(X) (this function requires the statistics toolbox). By default, this will assume you are interested in finding the euclidean distance between each pair of point.
The returned vector, D, corresponds to a list of pairwise distances. The pdist() documentation describes the meaning of the ordering of these distances. I recommend following the D = pdist(X) with D = squareform(D) to convert the vector into a pairwise distance matrix.
Then you simply need to identify the shortest k distances you are interested in and plot these points.
I have provided an example way of doing this below.
X = rand(10,2); % Generate random 2D points
k = 3; % Number of closest pairs of points to choose
Y = [];
D = pdist(X); % Get vector of distances
B = sort(D,'ascend'); % Sort distances
D = tril(squareform(D)); % Convert distance vector to lower triangular matrix
% Find k pairs of rows of X corresponding to closest peaks
[Y(:,1),Y(:,2)] = find(ismember(D,B(1:k)));
% Plot results
figure; hold on;
plot(X(:,1),X(:,2),'b+'); % Plot "peaks"
for i = 1:k
plot(X([Y(i,1),Y(i,2)],1),X([Y(i,1),Y(i,2)],2),'r'); % Plot closest peaks
end

how to do clustering when the input is 3D matrix, MATLAB

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.

Sampling uniformly from many circles on the sphere efficiently in matlab

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.

Fast and efficient upper diagonal matrix inverse

I compute the multinomial Gaussian density for some huge number of times in a project where I update the covariance matrix by rank-1. Instead of computing the covariance from scratch, I used the cholupdate function to add a new sample to the covariance and remove a new sample to the covariance. By this way, the update is told to be in $O(n^2)$ as opposed to $O(n^3)$ Cholesky factorization of the covariance matrix.
persistent R
if (initialize) % or isempty(R)
% compute covariance V
R = chol(V);
else
R = cholupdate(R,xAdded);
detVar = prod(diag(R))^2;
Rt = R';
coeff = 1/sqrt((2*pi)^dimension*detVar);
y = Rt\x;
logp = log(coeff) - 1/2 * norm(y)^2;
Actually the code is quite complicated but I simplified it here. I wonder if there is a faster way to compute the inverse (the Rt\x part in the code) of an upper triangular matrix in MATLAB. Do you have any ideas to do it more efficiently in MATLAB.
Note that computing the determinant is also faster this way. So the new method will also not bad for the computation of the determinant.
The mldivide function is smart enough to check for triangular matrices, in which case it uses a forward/backward substitution method to efficiently solve the linear system:
AX=B <--> X=inv(A)*B <--> X=A\B
(compute x1, substitute it in second equation and compute x2, substitute in third ...)