I have matrix A and I. When I run
Z = median(A(:,:,I), 3)
It gives me this output but I do not know how.
Lets take a look at your code
Z = median(A(:,:,I), 3)
What this says is that you want to find the median of some 3D matrix along the 3rd dimension.
Note that I=[0 1 1] means that A(:,:,I) selects the 2nd and 3rd pages of matrix A. When we call median(A(:,:,I), 3) we are asking for the median then across only pages 2 and 3 which results in an average of pages 2 and 3 because the median of two items is equal to the mean.
Related
In something which made me spent several hours, I have found an inconsistency in how Matlab deals with dimensions. I somebody can explain to me OR indicate me how to report this to Matlab, please enlight me.
For size, ones,zeros,mean, std, and most every other old and common commands existing inside Matlab, the dimension arrangement is like the classical one and like the intended standard (as per the size of every dimension), the first dimension is along the column vector, the second dimension is along the row vector, and the following are the non graphical following indexes.
>x(:,:,1)=[1 2 3 4;5 6 7 8];
>x(:,:,2)=[9 10 11 12;13 14 15 16];
>m=mean(x,1)
m(:,:,1) = 3 4 5 6
m(:,:,2) = 11 12 13 14
m=mean(x,2)
m(:,:,1) =
2.5000
6.5000
m(:,:,2) =
10.5000
14.5000
m=mean(x,3)
m = 5 6 7 8
9 10 11 12
d=size(m)
d = 2 4 2
However, for graphical commands like stream3,streamline and others relying on the meshgrid output format, the dimensions 1 and 2 are swapped!: the first dimension is the row vector and the second dimension is the column vector, and the following (third) is the non graphical index.
> [x,y]=meshgrid(1:2,1:3)
x = 1 2
1 2
1 2
y = 1 1
2 2
3 3
Then, for stream3 to operate with classically arranged matrices, we should use permute(XXX,[2 1 3]) at every 3D argument:
xyz=stream3(permute(x,[2 1 3]),permute(y,[2 1 3]),permute(z,[2 1 3])...
,permute(u,[2 1 3]),permute(v,[2 1 3]),permute(w,[2 1 3])...
,xs,ys,zs);
If anybody can explain why this happens, and can indicate to me why this is not a bug, welcome.
This behavior is not a bug because it is clearly documented as the intended behavior: https://www.mathworks.com/help/matlab/ref/meshgrid.html. Specifically:
[X,Y,Z]= meshgrid(x,y,z) returns 3-D grid coordinates defined by the vectors x, y, and z. The grid represented by X, Y, and Z has size length(y)-by-length(x)-by-length(z).
Without speaking to the original authors, the exact motivation may be a bit obscure, but I suspect it has to do with the fact that the y-axis is generally associated with the rows of an image, while x is the columns.
Columns are either "j" or "x" in the documentation, rows are either "i" or "y".
Some functions deal with spatial coordinates. The documentation will refer to "x, y, z". These functions will thus take column values before row values as input arguments.
Some functions deal with array indices. The documentation will refer to "i, j" (or sometimes "i1, i2, i3, ..., in", or using specific names instead of "i" before the dimension number). These functions will thus take row values before column values as input arguments.
Yes, this can be confusing. But if you pay attention to the names of the variables in the documentation, you will quickly figure out the right order.
With meshgrid in particular, if the "x, y, ..." order of arguments is confusing, use ndgrid instead, which takes arguments in array indexing order.
There is a downloadable function called CARTPROD which gives the cartesian product of given vectors
(link to CARTPROD function)
For example
cartprod(1:3,1:3)
ans =
1 1
2 1
3 1
1 2
2 2
3 2
1 3
2 3
3 3
However, is there a way in which I can specify how many times a given vector should be read in the cartesian product. I want something like this:
%If user chooses the vector to be used 4 times
cartprod(1:3,1:3,1:3, 1:3)
%If user chooses the vector to be used 2 times
cartprod(1:3,1:3)
I have tried thinking about it, but I can't think of doing it any way besides manually. Thanks!
What you're looking for is comma separated lists. Haven't tested this, but try
myvec={1:3,1:3,1:3,1:3};
cartprod(myvec{:}); %get cartprod of all vectors in the cell-array.
or as #Sardar_Usama pointed out, you can replace myvec={1:3,1:3,1:3,1:3} with this:
n=4; %number of repeated vectors
myvec=repmat({1:3},1,n); %repeat cell-array {1:3} 4 times
The other answer points out how you can use the same cartprod function from the FEX. However, there is another function named combvec (from the Neural Network Toolbox) which does exactly the same.
n = 4; %Number of times to be repeated
myvec = repmat({1:3},1,n); %Repeating the cell array vector
result = combvec(myvec{:}).'; %Converting to comma-separated list and applying combvec
I have a 3D matrix that each page/slice is independent of other slices. Thus, I would like to use the find command to filter my data in each page. However, when applied, find will return the indices in a row vector that describe my data as a whole, where actually it is not. For example:
a=rand(1,10,5);
ind=find(a<0.3);
This would return ind something like:
ind=
1 2 5 9 10 11 20 24 25 ...
I expected something like:
ind(:,:,1)=
1 2 3
ind(:,:,2)=
1 5 6 10 %based on each slice, independent to other slices
I intended to do so (independently), so that I could apply the found indices to each slice of other matrix.
Can this be done without using loop? Thanks in advance!
Use ind2sub() to convert your indices to subscripts. Something like this should work for a 3d array:
[i,j,k] = ind2sub(size(a), ind)
That said, the outputs (i, j, k), will all be the same size, that is the same size as ind. In other words, it gives one set of subscripts (i,j,k) (coordinates) for each value of a<0.3.
It's not completely clear what output you want/expect from your question, but if you want separate subscripts for each page in a, you'll have to filter further (e.g. j(i==1),k(i==1) for the first page in i).
I have a 4x1 matrix,
A= [1;2;3;4]
I want to make B such that its size is 4x50. All the elements in the columns must contain the same elements of A. For example,
B= [1 1 1 1.... 1 1; 2 2 2 2.... 2 2; 3 3 3 3.... 3 3; 4 4 4 4.... 4 4]
In this case all the elements of A from column 1 is present in the same way in the first column of B, same for second column on B, and so on
Is there any way to form B like this from A? I was trying concatenating like below:
B= horzcat(A,A,...);
But in this case, I have to write A, 50 times. So is there any other way to get the same result?
Have you tried using repmat?
B = repmat(A, 1, 50);
repmat (which nicely stands for repeat matrix) takes a matrix and repeats itself for as many times horizontally and vertically that you want. Technically speaking, you can choose how many times you want to repeat for as many dimensions as possible as there are in your matrix. However, for our purposes here, this is a matrix which has two degrees of freedom / dimensions, so we're only considering horizontal and vertical here.
In your specific case, you want to repeat this column vector 50 times horizontally, hence the third parameter being set to 50, while you only want one copy vertically, hence the second parameter being set to 1.
Is the first dimension always the Y-dimension (vertical one) while the second dimension refers to the X-dimension (horizontal one)? Is there any exceptions?
There are no exceptions.
The only subtlety is that if you only specify 1 index (eg x(10)), that refers to the 10th element overall, not the 10th element in dimension 1. So you have a size(x)=[2 10], then x(10) == x(2,5).
There are two things you need to keep in mind:
MATLAB operates always along the first non-singleton dimension
In a matrix, the first dimension is along rows and the second is along columns
Within this principles falls array indexing.
Another example, if you have a vector (abusing notation):
sum(reshape(1:3,[1,1,3])) == sum(1:3) == sum((1:3)')
if you have a matrix:
sum([1 2; 3 4]) ~= sum([1 2; 3 4],2)
i.e. sum along rows (also called column-wise) is different from the sum along columns (also called row-wise).