Matlab Dimensions Swapped in Meshgrid - matlab

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.

Related

Vector with specific number of equally spaced values

I am familiar with the command:
(-5:0.1:5)
which creates a vector of values, equally spaced by 0.1, from -5 to 5.
However, is there a way to produce a vector of values, equally spaced from -5 to 5 such that there are, say, 100 values in the vector.
(-5:0.1:5) gives a vector with 101 values, however, is there a way to get a vector of 100 values without manually calculating the step size?
Yes there is. Use function linspace. See documentation here
linspace(1,10,10)
ans =
1 2 3 4 5 6 7 8 9 10
also the question is a duplicate of this question

What to call (1 by n) plus (n by 1) operation?

I stumbled across an unexpected behavior of the addition operator.
a=[1 2 3];
b=[5; 7; 11];
a+b
Produces
ans =
6 7 8 % a(1)+b(1) a(1)+b(2) a(1)+b(3)
8 9 10 % a(2)+b(1) a(2)+b(2) a(2)+b(3)
12 13 14 % a(3)+b(1) a(3)+b(2) a(3)+b(3)
This behavior probably falls under the Add a Vector to a Matrix example in the documentation.
Create an array, A, and add a column vector to it. The vector is
treated as though it is a matrix of the same size as A, so that each
element in the vector is added to a row in A.
Although, b in my example cannot be treated as the same size as a. Both vectors must be duplicated.
What can I call this behavior when I am describing it to others? None of the definitions of Matrix Addition fit. Vector addition also has a different definition. The best I could come up with was the "sum of the elements in the cartesian product".
That's called binary singleton expansion. Starting with R2016b, MATLAB does it automatically with standard operators. See bsxfun for more details.

Average on contiguos segments of a vector

I'm sure this is a trivial question for a signals person. I need to find the function in Matlab that outputs averaging of contiguous segments of windowsize= l of a vector, e.g.
origSignal: [1 2 3 4 5 6 7 8 9];
windowSize = 3;
output = [2 5 8]; % i.e. [(1+2+3)/3 (4+5+6)/3 (7+8+9)/3]
EDIT: Neither one of the options presented in How can I (efficiently) compute a moving average of a vector? seems to work because I need that the window of size 3 slides, and doesnt include any of the previous elements... Maybe I'm missing it. Take a look at my example...
Thanks!
If the size of the original data is always a multiple of widowsize:
mean(reshape(origSignal,windowSize,[]));
Else, in one line:
mean(reshape(origSignal(1:end-mod(length(origSignal),windowSize)),windowSize,[]))
This is the same as before, but the signal is only taken to the end minus the extra values less than windowsize.

Matlab general matrix indexing for accesing several rows

Edit for clarity:
I have two matrices, p.valor 2x1000 and p.clase 1x1000. p.valor consists of random numbers spanning from -6 to 6. p.clase contains, in order, 200 1:s, 200 2:s and 600 3:s. What I wan´t to do is
Print p.valor using a diferent color/prompt for each clase determined in p.clase, as in following figure.
I first wrote this, in order to find out which locations in p.valor represented where the 1,2 respective 3 where in p.clase
%identify the locations of all 1,2 respective 3 in p.clase
f1=find(p.clase==1);
f2=find(p.clase==2);
f3=find(p.clase==3);
%define vectors in p.valor representing the locations of 1,2,3 in p.clase
x1=p.valor(f1);
x2=p.valor(f2);
x3=p.valor(f3);
There is 200 ones (1) in p.valor, thus, is x1=(1:200). The problem is that each number one(1) (and, respectively 2 and 3) represents TWO elements in p.valor, since p.valor has 2 rows. So even though p.clase and thus x1 now only have one row, I need to include the elements in the same colums as all locations in f1.
So the different alternatives I have tried have not yet been succesfull. Examples:
plot(x1(:,1), x1(:,2),'ro')
hold on
plot(x2(:,1),x2(:,2),'k.')
hold on
plot(x3(:,1),x3(:,2),'b+')
and
y1=p.valor(201:400);
y2=p.valor(601:800);
y3=p.valor(1401:2000);
scatter(x1,y1,'k+')
hold on
scatter(x2,y1,'b.')
hold on
scatter(x3,y1,'ro')
and
y1=p.valor(201:400);
y2=p.valor(601:800);
y3=p.valor(1401:2000);
plot(x1,y1,'k+')
hold on
plot(x2,y2,'b.')
hold on
plot(x3,y3,'ro')
My figures have the axisies right, but the plotted values does not match the correct figure provided (see top of the question).
Ergo, my question is: how do I include tha values on the second row in p.valor in my plotted figure?
I hope this is clearer!
Values from both rows simultaneously can be accessed using this syntax:
X=p.value(:,findX)
In this case, resulting X matrix will be a matrix having 2 rows and length(findX) columns.
M = magic(5)
M =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
M2 = M(1:2, :)
M2 =
17 24 1 8 15
23 5 7 14 16
Matlab uses column major indexing. So to get to the next row, you actually just have to add 1. Adding 2 to an index on M2 here gets you to the next column, or adding 5 to an index on M
e.g. M2(3) is 24. To get to the next row you just add one i.e. M2(4) returns 5.To get to the next column add the number of rows so M2(2 + 2) gets you 1. If you add the number of columns like you suggested you just get gibberish.
So your method is very wrong. Freude's method is 100% correct, it's much easier to use subscript indexing than linear indexing for this. But I just wanted to explain why what you were trying doesn't work in Matlab. (aside from the fact that X=p.value(findX findX+1000) gives you a syntax error, I assume you meant X=p.value([findX findX+1000]))

Questions about matlab median filter commands

This is a question about Matlab/Octave.
I am seeing some results of the medfilt1(1D Median filter command in matlab) computation by which I am confused.
EDIT:Sorry forgot to mention:I am using Octave for Windows 3.2.4. This is where i see this behavior.
Please see the questions below, and point if I am missing something.
1] I have a 1D data array b=[ 3 5 -8 6 0];
out=medfilt1(b,3);
I expected the output to be [3 3 5 0 0] but it is showing the output as [4 3 5 0 3]
How come? What is wrong here?
FYI-Help says it pads the data at boundaries by 0(zero).
2] How does medfilt2(2D median filter command in matlab) work.
Help says "Each output pixel contains the median value in the m-by-n neighborhood around the corresponding pixel in the input image".
For m=3,n=3, So does it calculate a 3x3 matrix MAT for each of input pixels placed at its center and do median(median(MAT)) to compute its median value in the m-by-n neighbourhood?
Any pointers will help.
thank you. -AD
I was not able to replicate your error with Matlab 7.11.0, but from the information in your question it seems like your version of medfilt1 does not differentiate between an odd or even n.
When finding the median in a vector of even length, one usually take the mean of the two median values,
median([1 3 4 5]) = (3+4)/2 = 3.5
This seems to be what happens in your case. Instead of treating n as odd, and setting the value to be 3, n is treated as even and your first out value is calculated to be
median([0 3 5]) = (3+5)/2 = 4
and so on.. EDIT: This only seems to happen in the endpoints, which suggest that the padding with zeros is not properly working in your Octave code.
For your second question, you are almost right, it calculates a 3x3 matrix in each center, but it does not do median(median(MAT)), but median(MAT(:)). There is a difference!
A = [1 2 3
14 5 33
11 7 13];
median(median(A)) = 11
median(A(:)) = 7