Equalizing sizes of matrices - matlab

Say we have the following two matrices in matlab:
>> x=[1 5;7 8;9 6]
>> y=[6 87]
I'm trying to make them have the same size. I did that by making the size of y to be the same as the size of x. But, when I call y again, I get the result as the original dimension.
I want them to have the same dimensions since for instance if I want to measure the distance between them they have to have the same dimensions.
So, the other cells can have zero values for instance.
How can I make that in matlab?
Thanks.

Try this :
y = padarray(y,size(x)-size(y),'post');
Be sure that size(x) > size(y).
For more information have a look to : padarray

Related

Surface plot with 3 vectors Matlab

I need to be able to do a surface plot using data from 3 vectors. I found similar information, but no method seems to work with my data. My X and Y columns are evenly spaced, but not in increasing order. I tried different methods, but none of them seem to give me what I want, which is a simple surface linking close points together. I tried the following:
[X Y]=meshgrid(x,y);
Z=griddata(x,y,z, X,Y);
surf(X,Y,Z);
This is not exactly what I want, because it creates a surface at z=0 and makes it look more like a volume plot than just a surface. It also runs very slowly on my computer (probably from creating all the gridpoints). If I could get something that doesn't require as much memory it would be ideal (my vectors have about 20k values each), but this is not a necessity.
***Edit: I also tried using the scatteredInterpolant method found here,but the function doesn't seem to be recognized by MATLAB and I get this error:
Undefined function 'scatteredInterpolant' for input arguments of type 'double'.
Also here is an image of my problem:
You can see that we can't see under the surface, there is some z=0 plane blocking it.
If you have anything for me, any help is appreciated.
Thanks in advance.
**Edit 2: I added sample vectors, they're my x,y and z values from left to right.
***Edit 3: Here's an image of the triangulation I get. As you can see some points are being ignored for some reason, which gives those long and weird looking blue triangles.
Mike
As conventional methods seem to fail, I would suggest you to do it manually.
Create a Z matrix full of NaN values. The size of the matrix should be dependant on your x and y values.
Loop over all occuring x,y, pairs and put their (average?) z value in the right position of your Z matrix.
Loop over all NaN values and interpolate their value. Perhaps using filter2.
Use surf to plot the resulting surface
If you have points which are described by vectors, and you want to plot them you could always use a Delauny triangulation. The function in matlab is called Tri=delauny(X,Y,Z). The data generated by this function can be shown with either trimesh(Tri,X,Y,Z) or trisurf(Tri,X,Y,Z). Keep in mind trisurf is only for 3D data. If you want to adjust the transparancy of plots in your graph use the alpha setting.
I hope this helps
To me it looks like you just need to sort your data before plotting.
Here is an example which I believe is similar to your case (since I could not download your data).
x = [2 1 4 3 -1 -3 -4 -2];
y = [1 2 3 4 -1 -2 -3 -4];
z = 32 - x.*x - y.*y;
[X1 Y1] = meshgrid(x,y);
Z1 = 32 - X1.*X1 -Y1.*Y1;
surf(X1,Y1,Z1)
aux = sort([x;y],2);
x = aux(1,:);
y = aux(2,:);
[X2 Y2] = meshgrid(x,y);
Z2 = 32 - X.*X - Y.*Y;
figure()
surf(X2,Y2,Z2)
The first figure results in a very problematic surface:
The second figure contains the desired surface:

Matlab: Creating 3D array from a vector

I don't think I know tricks to use repmat in Matlab yet. I tried a number of combination and I am not able to achieve what I need.
I have a vector A of size 1 x 20. I just want to stack A to create 3 x 5 x 20 size matrix. Can you please help ?
A = 1:20;
reshape(repmat(A, [15, 1]), [3,5,20])

Matlab's Quiver3 plots only 4 vectors

I want to use the command quiver3(X,Y,Z,M,N,O)
in order to get a vector field, where all matrices are 10x10x10 arrays with real entries. Now I wanted to plot it and got only 4 vectors instead of my expected 1000. Does anybody here know, what I could possibly have done wrong?
If you need further information, I am available for your comments.
Assuming the problem occurs when attempting to display the data (rather than with attempting to display unallowed numerical values such as Inf or NaN), I think the problem is the range of norms of the vectors, such that only 4 show up.
The importance of the norm of the vectors relative to the range of the coordinate system is important, as illustrated by the following example:
Here all 10 random vectors show up:
Na = 10;
[X Y Z M N O] = deal(rand(Na,1),rand(Na,1),rand(Na,1),rand(Na,1),rand(Na,1),rand(Na,1));
quiver3(X,Y,Z,M,N,O)
But if some of the vectors are made 100 x bigger, only the smaller ones show up:
mul = 1e+3;
[X Y Z M N O] = deal(rand(Na,1),rand(Na,1),rand(Na,1),...
[mul*rand(Na/2,1);rand(Na/2,1)],...
[mul*rand(Na/2,1);rand(Na/2,1)],...
[mul*rand(Na/2,1);rand(Na/2,1)]);
quiver3(X,Y,Z,M,N,O)
Similarly if some of the vectors are made too small they don't show up:
mul = 1e-3;
[X Y Z M N O] = deal(rand(Na,1),rand(Na,1),rand(Na,1),...
[mul*rand(Na/2,1);rand(Na/2,1)],...
[mul*rand(Na/2,1);rand(Na/2,1)],...
[mul*rand(Na/2,1);rand(Na/2,1)]);
quiver3(X,Y,Z,M,N,O)
Vectors too large or too small relative to the axis are not displayed at all.
If it is a problem with scaling you may want to inspect your function and see how to narrow the range of x,y,z so that the vectors have a narrower range of values, or change the scale (logarithm?) so that all the data can be displayed in one figure.
edit
As an alternative to the question of how to display your data, you may want to consider using isosurfaces. Here's an example, with each red sphere representing a different isosurface in a spherical potential:

Cropping matrix

for examples, I have a 6x6 matrix, then I want to take out the small matrix which is located in the center of that matrix, say 2x2. Is there any smart way to do it ? Or I have to loop through the old matrix and then copying values to new one?
Thank you very much.
Of course you can. try for instance
A = rand(6,6); % // big matrix, an example
B = A(3:4,3:4); % // central sub matrix obtained using indices
which (in this case) is also equivalent to
B = A([3 4],[3 4]);
In general you can extract subvectors from a vector selecting the indices you are interested to.

Replace matrix values with mean values extracted from smaller matrix in MATLAB

Let's say I have a 10 x 10 matrix. What I do then is iterate through the whole matrix with an 3 x 3 matrix (except from the edges to make it easier), and from this 3 x 3 matrix I get the mean/average value of this 3 x 3 space. What I then want to do is to replace the original matrix values, with those new mean/average values.
Can someone please explain to me how I can do that? Some code examples would be appreciated.
What you're trying to do is called convolution. In MATLAB, you can do the following (read up more on convolution and how it's done in MATLAB).
conv2( myMatrix , ones(3)/9 , 'same' );
A little deciphering is in order. myMatrix is the matrix you're working on (the 10x10 one you mentioned). The ones(3)/9 command creates a so-called mask of filter kernel, which is
1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9
When you take this mask and move it around, multiplying value-by-value the mask's entries with 3x3 entries of the image and then add the results (dot product, essentially), the you get the average of the 9 values that ended up underneath this mask. So once you've placed this mask over every 3x3 segment of you matrix (image, I imagine) and replaced the value in the middle by the average, you get the result of that command. You're welcome to experiment with it further. The 'same' flag simply means that the matrix you're getting back is the same size as you original one. This is important because, as you've yourself realized, there are multiple ways of dealing with the edges.
To do this, you need to keep the original intact until you have got all the means. This means that if you implement this using a loop, you have to store the averages in different matrix. To get the borders too, the easiest way is to copy the original matrix to the new matrix, although only the borders are needed to be copied.
This average3x3 function copies the input Matrix to AveragedMatrix and then goes through all the elements that are not on any border, calculates the mean of 3x3 space and stores it in the corresponding element of AveragedMatrix.
function [AveragedMatrix] = average3x3(Matrix)
AveragedMatrix = Matrix;
if ((size(Matrix, 1) < 3) || (size(Matrix, 2) < 3))
fprintf('Matrix is too small, minimum matrix size is 3x3.\n');
return
end
for RowIndex = 2:(size(Matrix, 1)-1)
Rows = RowIndex-1:RowIndex+1;
for ColIndex = 2:(size(Matrix, 2)-1)
Columns = ColIndex-1:ColIndex+1;
AveragedMatrix(RowIndex,ColIndex) = mean(mean(Matrix(Rows,Columns)));
end
end
return
To use this function, you can try:
A = randi(10,10);
AveragedA = average3x3(A);