Finding tensor indices - matlab

I am building a 5-d tensor which explores a function in a 5-D space. The tensor is just the values of the function in discrete points in the space.
But, whenever I get the value, I want to get the indices of tensor / coordinate of space for later visualization. I tried to construct linspace-s for particular dimensions, then do a "sort of tensor exterior product". When I call the indices, I get the coordinate. It didn't work.
I hope I can get the indices with the value of the tensor at those indices, so I can rescale the indices into my coordinate. Is there such a function?
For example -
A =
1 2 3
4 5 6
7 8 9
For visualization, I want to plot A(:,2), a slice at fixed column. The coordinates are (1,2),(2,2),(3,2).
I want to plot f = (2,5,8) with coordinate = (1,2,3)
But now I have to generalize it into 5 dimensions and extract data for 2D colour plot (fix the other 3 dimensions)

Related

how do you visualize a matrix whose elements are vectors in MATLAB?

I have generated a 3 x 2 x 25 matrix A in MATLAB.
A(1,2,1) = 5 means method 1, type 2, trial 1 has a count value of 5.
A(3,1,2) = 7 means method 3, type 1, trial 2 has a count value of 7.
Basically, there are 25 count values for each (method, type) pair.
In the past, I have used "histogram" MATLAB function to visualize a 2-D frequency plot and I know I can use it here like so:
histogram(A(3,1,:))
But if I use histogram I would have to plot all 6 like:
histogram(A(1,1,:))
histogram(A(1,2,:))
histogram(A(2,1,:))
histogram(A(2,2,:))
histogram(A(3,1,:))
histogram(A(3,2,:))
But I was wondering if there is a way to all 6 plots in a 3-dimensional histogram ?
You want 4 dimensions of information on a 3 dimensional plot. the only good way to get a 4th dimension of information would probably be color and that's going to be a mess with 6 plots. You're better off separating the plots into different graphs.
From what you're describing the second dimension only has 2 states. Would it make sense in your case to have 2 3d plots with this dimension being split across graphs/colors?

Is it possible to apply an arbitrary transformation matrix to an image in SPM?

I have a somewhat specific task I'd like to do in SPM.
Basically, I have some input NII file scan.nii and I would like to apply an arbitrary affine transformation to it, defined by x y z p r yw.
x,y,z,p,r,yw represent the translations and rotations in each degree of freedom (so say x=2mm, p=0.7deg and so on). I can get an appropriate matrix with M=spm_matrix([x y z p r yw]), but I do not know how I can actually go about applying this matrix to my scan.
Ideally I would want it to output with a new filename or simply as a Matlab variable so I can go and do this many times to the same image, but that is not explicitly necessary.
Thank you for your help.
An affine matrix works on image coordinates, not on the image itself. You need to multiply the affine matrix with the coordinates list of your image, then you will get new coordinates, corresponds to the original coordinates.
In addition, the translation is done by multiplying the 4th column of the affine matrix with additional 1's in the last row of your indices list (each match of these, at a single vector-multiplying from that matrix).
So, you need to produce a list of your 3D coordinates, as a 3xn matrix, then add a row of 1's at the bottom, and multiply the 4x4 affine matrix by the 4xn coordinates matrix.
An example, say your image is 4x4x4:
[X Y Z]=ndgrid(1:4);
ind=reshape(cat(3,X,Y,Z),[],3)'; % list of all of the indices in the image
ind=[ind; ones(1,size(ind,2))]; % add a row of `1`s
ind_aff=m*ind;
The bottom row of ind_aff is 1's, and you can ignore it. The first 3 rows are now the new coordinates, while each column is coordinates to the value that was coordinated by the same column number in the ind matrix.
For example, if
m=spm_matrix([3 1 10 0.5 0.9 0.3])
You will get this transformation:
% old coordinates (column-wise)
ind(1:3,1:3)=
1 2 3
1 1 1
1 1 1
% new coordinates (column-wise)
ind_aff(1:3,1:3)=
4.5609 5.1547 5.7486
1.4073 0.7892 0.1711
9.3693 8.8542 8.3392

Using MATLAB, is there a way to get a 2D visualisation of data points that are in 6D space?

Part of an assignment of mine is to provide a 2D visualisation (plots) of some of my data points that are stored in a matrix. I'm slightly confused because the data is actually in 6D space (i.e. each row has 6 columns like 0 1 0 8 8 2).
Is there something I'm missing or does this genuinely not make sense? Is this something MATLAB can do?
Edit: Is something like this possible?
Though I wouldn't consider it visualizing 6D data, you can get the linked plot with a simple call to plot:
A = rand(6);
x = 1:6;
plot(x,A'); % Transpose A to plot rows since it's square, see plot documentation
Which produces the following:
From the documentation:
If one of X or Y is a vector and the other is a matrix, then the
matrix must have dimensions such that one of its dimensions equals the
vector length. If the number of matrix rows equals the vector length,
then the plot function plots each matrix column versus the vector. If
the number of matrix columns equals the vector length, then the
function plots each matrix row versus the vector. If the matrix is
square, then the function plots each column versus the vector.
Simply use:
surf(2Dmatrix)
You can read more here: http://uk.mathworks.com/help/matlab/ref/surf.html
If your matrix is 2D image, simply use
figure; imshow(2Dmatrix, [])
If you leave the square bracket empty, the limit will be automatic. When the figure is displayed you can change it to different colormap by Edit > Colormap.

Randomly select Elements of 4D matrix in Matlab

I have a 4D matrix with dimensions 7x4x24x10 (Lets call it main_mat). I want to get a matrix of size 7x4x24 (rand_mat) so that each element of this (rand_mat) matrix is actually a uniformly random draw from the main matrix (main_mat). I am sorry if I have not put the question clearly, so I try to explain:
I have a stack of 24 sheets of 7x4 elements, and I have 10 such stacks. What I want is that I get a single stack of 24 sheets of 7x4 elements in such a way that every element out of resultant single stack is uniformly randomly drawn from exactly same sheet number from within 10 stacks. How can I do it without using loops?
If I am interpreting what you want correctly, for each unique 3D position in this matrix of 7 x 4 x 24, you want to be sure that we randomly sample from one out of the 10 stacks that share the same 3D spatial position.
What I would recommend you do is generate random integers that are from 1 to 10 that is of size 7 x 4 x 24 long, then use sub2ind along with ndgrid. You can certainly use randi as you have alluded to in the comments.
We'd use ndgrid to generate a grid of 3D coordinates, then use the random integers we generated to access the fourth dimension. Given the fact that your 4D matrix is stored in A, do something like this:
rnd = randi(size(A,4), size(A,1), size(A,2), size(A,3));
[R,C,D] = ndgrid(1:size(A,1), 1:size(A,2), 1:size(A,3));
ind = sub2ind(size(A), R, C, D, rnd);
B = A(ind);
Bear in mind that the above code will work for any 4D matrix. The first line of code generates a 7 x 4 x 24 matrix of random integers between [1,10]. Next, we generate a 3D grid of spatial coordinates and then use sub2ind to generate column-major indices where we can sample from the matrix A in such a way where each unique 3D spatial location of the matrix A only samples from one chunk and only one chunk. We then use these column-major indices to sample from A to produce our output matrix B.
This problem might not be solvable without the use of loops. One way that could work is:
mainMatrix = ... (7x4x24x10 matrix)
randMatrix = zeros(mainMatrix(:,1,1,1), mainMatrix(1,:,1,1), mainMatrix(1,1,:,1))
for x = 1:length(mainMatrix(:,1,1,1))
for y = 1:length(mainMatrix(1,:,1,1))
for z = 1:length(mainMatrix(1,2,:,1))
randMatrix(x,y,z) = mainMatrix(x,y,z,randi(10))
end
end
end

Matlab divergence of a randomly sampled 3d vector field

I am trying to use the divergence function in Matlab over a dataset which is not ordered. I have therefore the x, y, z positions of the origins of the vectors (3 columns) and the three components Fx, Fy, Fz of the vector field (3 columns), for a total of a 6 columns dataset, where the positions are random points in a 3d volume. How should I transform the data in order to be readable by divergence?
I guess I should use meshgrid and generate an ordered grid associated to my original random points, but how should I deal with the vector field F?
You are correct, use a meshgrid to generate the uniform datapoints, and then if your data is well behaved, you should be able to interpolate using interp3.
FinterpX = interp3(Xmeas,Ymeas,Zmeas,FmeasX,Xgrid, Ygrid, Zgrid);
FinterpY = interp3(Xmeas,Ymeas,Zmeas,FmeasY,Xgrid, Ygrid, Zgrid);
FinterpZ = interp3(Xmeas,Ymeas,Zmeas,FmeasZ,Xgrid, Ygrid, Zgrid);
However, your random datapoints may not work well with this approach, due to the constraints that interp3 puts on them.