Adding a dimension to a matrix in Matlab - matlab

I need to add a new matrix to a previously existant matrix, but on his dimension coordinate.
I know this is hard to understand, so let's see it on a example:
I've a matrix like this:
480x640x3
And I want to add the following one:
480x640x6
The result has be this: (6+3 = 9)
480x640x9
As you can see it adds but on the 3rd dimension.

For concatenating along higher dimensions, use the function CAT:
newMatrix = cat(3,matrix1,matrix2);

I would say that gnovice's answer is probably the best way to go, but you could do it this way too:
matrix1(:,:,4:9) = matrix2;

Related

matlab/numpy submatrix contour

I'm looking for a way to get the contour of a matlab/numpy submatrix.
For example, if I have :
A=
[x,x,x,x,x,x,x]
[x,x,x,x,x,x,x]
[x,1,2,3,4,x,x]
[x,5,x,x,6,x,x]
[x,7,8,9,10,x,x]
[x,x,x,x,x,x,x]
Is there a way to get [1,2,3,4,6,10,9,8,7,5] faster (ie more readable) than slicing every edge and then concatenating them ?
EDIT :
The problem is that slicing with numpy is bothersome.
For example, let's say I have i0,i1,j0,j1 to identify the submatrix :
I wanted to do :
np._r[A[i0,j0:j1+1],A[i0:i1+1,j1],A[i1,j1:j0-1:-1],A[i1:i0-1:-1,j0]]
But [j1:j0-1:-1] does not work if j0==0, as [j1:-1:-1] returns an empty slice...
EDIT 2 :
The following slice seems to work, I'm not sure it's really good, but I have not manage to do better.
np._r[A[i0,j0:j1+1],A[i0+1:i1+1,j1],(A[i1,j0+1:j1+1])[::-1],(A[i0+1:i1+1,j0])[::-1]]
Still thanks to all those who answered, if you found a better way, do not hesitate to post.
I think this is a good solution:
contour = [A(3,2:5) A(4,5) A(5,5:-1:2) A(4,2)];
here the value of contour will be your array [1,2,3,4,5,6,7,8,9,a]
rows = [2,2,2,2,3,4,4,4,4,3]
cols = [1,2,3,4,4,4,3,2,1,1]
A[rows, cols]
Should return [1,2,3,4,5,6,7,8,9,a] in your case.

Zero padding in Matlab

I have image, and I want to do up sampling. First of all I need to plug zeros between pixels such that [1,2,3] transforms to [1,0,2,0,3]. Can anyone tell me how to do it without using paddarray and without using for loops?
Thank you in advance!
Something like this?:
B=zeros(size(img)*2);
B(1:2:end,1:2:end)=img;
However there are ways of up-sampling in matlab without having the need of doing it by hand, for example interp2
You could also make use of MATLAB's way of dynamically allocating variables if you don't specify a number for an index into the array. By omitting indexing into certain locations in your array, MATLAB will fill in these values with zeroes by default. As such:
B(1:2:5) = 1:3
B =
1 0 2 0 3
V = [1,2,3];
padded(numel(V)*2) = 0;
padded(1:2:end) = V
And then just deal with the trailing zero if numel(V) was odd
There is a function upsample that does exactly this from Octave-Forge -- see docs on upsample.
Or you can look at the source of upsample to see what implements it. Are you opposed to using a package or a function?

Set vector equal to row of matrix matlab

I'm new to matlab and would like to create a new vector equal to a row of an nxn matrix that I already have. I know how to do it with loops but is there a command? Something like
vector1=matrix1(row5)
Thanks!
Yep this is easy, the syntax is:
row5Vector = matrix1(5,:);
Also to grab a column you could:
col5Vector = matrix1(:,5);

Referring to coordinates of a 3d matrix in Matlab

In Matlab I'm trying to find points in a 3d matrix whose coordinates are smaller than some function.
If these coordinates are equal to some functions than I can write:
A(some_function1,some_function2,some_function3)=2;
But what if I want to do something like:
A(<some_function1,<some_function2,<some_function3)=2;
This isn't working - so what is the other way of finding such points without using "for" loop? Unfortunately with "for" loop my code takes a lot of time to compute. Thank you for your help!
How about something along the lines of
A( ceil(min(some_function1,size(A,1))),...
ceil(min(some_function2,size(A,2))),...
ceil(min(some_function3,size(A,3))) );
This will cap the indicies to the end of each array dimension
You can just use regular indexing to achieve this:
A(1:floor(some_function1),1:floor(some_function2),1:floor(some_function3)) = 2;
assuming you check / ensure that floor(some_function*) is smaller than the dimensions of A
Try:
A(1:size(A,1)<some_function1, 1:size(A,2)<some_function2, 1:size(A,3)<some_function3) = 2
I hope I got your question correctly.

What's the best way to iterate through columns of a matrix?

I want to apply a function to all columns in a matrix with MATLAB. For example, I'd like to be able to call smooth on every column of a matrix, instead of having smooth treat the matrix as a vector (which is the default behaviour if you call smooth(matrix)).
I'm sure there must be a more idiomatic way to do this, but I can't find it, so I've defined a map_column function:
function result = map_column(m, func)
result = m;
for col = 1:size(m,2)
result(:,col) = func(m(:,col));
end
end
which I can call with:
smoothed = map_column(input, #(c) (smooth(c, 9)));
Is there anything wrong with this code? How could I improve it?
The MATLAB "for" statement actually loops over the columns of whatever's supplied - normally, this just results in a sequence of scalars since the vector passed into for (as in your example above) is a row vector. This means that you can rewrite the above code like this:
function result = map_column(m, func)
result = [];
for m_col = m
result = horzcat(result, func(m_col));
end
If func does not return a column vector, then you can add something like
f = func(m_col);
result = horzcat(result, f(:));
to force it into a column.
Your solution is fine.
Note that horizcat exacts a substantial performance penalty for large matrices. It makes the code be O(N^2) instead of O(N). For a 100x10,000 matrix, your implementation takes 2.6s on my machine, the horizcat one takes 64.5s. For a 100x5000 matrix, the horizcat implementation takes 15.7s.
If you wanted, you could generalize your function a little and make it be able to iterate over the final dimension or even over arbitrary dimensions (not just columns).
Maybe you could always transform the matrix with the ' operator and then transform the result back.
smoothed = smooth(input', 9)';
That at least works with the fft function.
A way to cause an implicit loop across the columns of a matrix is to use cellfun. That is, you must first convert the matrix to a cell array, each cell will hold one column. Then call cellfun. For example:
A = randn(10,5);
See that here I've computed the standard deviation for each column.
cellfun(#std,mat2cell(A,size(A,1),ones(1,size(A,2))))
ans =
0.78681 1.1473 0.89789 0.66635 1.3482
Of course, many functions in MATLAB are already set up to work on rows or columns of an array as the user indicates. This is true of std of course, but this is a convenient way to test that cellfun worked successfully.
std(A,[],1)
ans =
0.78681 1.1473 0.89789 0.66635 1.3482
Don't forget to preallocate the result matrix if you are dealing with large matrices. Otherwise your CPU will spend lots of cycles repeatedly re-allocating the matrix every time it adds a new row/column.
If this is a common use-case for your function, it would perhaps be a good idea to make the function iterate through the columns automatically if the input is not a vector.
This doesn't exactly solve your problem but it would simplify the functions' usage. In that case, the output should be a matrix, too.
You can also transform the matrix to one long column by using m(:,:) = m(:). However, it depends on your function if this would make sense.