Cropping matrix - matlab

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.

Related

Store 3x3 matrix in a variable in a for loop

I have a 9x3 matrix that I subdivided into three (3) 3x3 matrix. Now I want to make a for loop function that will store each 3x3 matrix into a variable.
X=reshape(1:27,3,9)'; % sample 9x3 matrix
xx = mat2cell(X,[3,3,3],3); % subdivide X matrix into 3x3 cell matrix
for i:1:3
x(i) = xx{i,1}; %store the three cells into x1 x2 and x3 matrix
end
I know that this does not how it works in matlab but just to show the function I would like to attain.
You can use eval function.
X=reshape(1:27,3,9)'; % sample 9x3 matrix
xx = mat2cell(X,[3,3,3],3); % subdivide X matrix into 3x3 cell matrix
for i=1:3
eval(['x' num2str(i) ' = xx{' num2str(i) ',1};']);
end
But What you are asking for is not recommended at all. In fact i always avoid using eval because the code doesn't get checked by MATLAB editor.
It is also not a good idea to have multiple variables, instead use cells, structures, and so on for a better usage in the rest of your code.
Is this what you're looking for?
X=reshape(1:27,3,9)';
for i=1:3
block = X(3*i-2:3*i,:);
disp(block);
end
The preferred way to do this is to actually just store it in a 3D array and you can access each element along the third dimension. The reason for that is that MATLAB is optimized for computing using matrices, so if you keep all of your data in a matrix, operations can be performed in a vectorized fashion on all components.
Better yet you can remove the for loop needed to create it by using reshape and permute.
X = permute(reshape(X', [3 3 3]), [2 1 3]);
% And access each element
X(:,:,1)
X(:,:,2)
X(:,:,3)
This is going to be more performance than using cell arrays or eval.

create 3D (n:m:k) matrix in matlab using array 2D (i:3)

I need a 3D matrix in matlab, I have another 2D matrix (7570x3) too,
The 3D matrix should have zero number except of all dimensions in 2D matrix that should have 1 value. How can I do that.
i.e. 2D matrix (1,:) = 28,64,27 then 3d(27,64,27) should be 1
how can i do that?
Assuming a is your 2-d matrix, and b is the 3-d one, use sub2ind as follows:
b=false(max(a)); % preallocate memory for a logical zeros matrix b
b(sub2ind(size(b),a(:,1),a(:,2),a(:,3))) = 1;
Check to see what max(a) gives you to see if you can host a 3-d matrix of size(max(a) to begin with. Since you are interested in a logcial matrix (ones and zeros), the size of that matrix in memory is the same as the # of elements, n*m*l, so a 1000x1000x1000 will take 1 GB.
Note, it very well may be that b is very sparse, if that is the case you can refer to this thread to see how to deal with it. Know that at the moment, and to the best of my knowledge, matlab doesn't support 3d sparse matrices. So you may want to check this option from the FEX. When I think of it, you already have a sparse look-up table of the 3D matrix! it is just your 2D matrix you started with...
Thanks a lot #natan
for non-integer matrix also can use:
b=false(floor(max(a))); % preallocate memory for a logical zeros matrix b
b(sub2ind(size(b),floor(a(:,1)),floor(a(:,2)),floor(a(:,3)))) = 1;
or use round function:
b=false(round(max(a))); % preallocate memory for a logical zeros matrix b
b(sub2ind(size(b),round(a(:,1)),round(a(:,2)),round(a(:,3)))) = 1;

Matlab 3d-matrix

I have to create a very big 3D matrix (such as: 500000x60x60). Is there any way to do this in matlab?
When I try
omega = zeros(500000,60,60,'single');
I get an out-of-memory error.
The sparse function is no option since it is only meant for 2D matrices. So is there any alternative to that for higher dimensional matrices?
Matlab only has support for sparse matrices (2D). For 3D tensors/arrays, you'll have to use a workaround. I can think of two:
linear indexing
cell arrays
Linear indexing
You can create a sparse vector like so:
A = spalloc(500000*60*60, 1, 100);
where the last entry (100) refers to the amount of non-zeros eventually to be assigned to A. If you know this amount beforehand it makes memory usage for A more efficient. If you don't know it beforehand just use some number close to it, it'll still work, but A can consume more memory in the end than it strictly needs to.
Then you can refer to elements as if it is a 3D array like so:
A(sub2ind(size(A), i,j,k))
where i, j and k are the indices to the 1st, 2nd and 3rd dimension, respectively.
Cell arrays
Create each 2D page in the 3D tensor/array as a cell array:
a = cellfun(#(x) spalloc(500000, 60, 100), cell(60,1), 'UniformOutput', false);
The same story goes for this last entry into spalloc. Then concatenate in 3D like so:
A = cat(3, a{:});
then you can refer to individual elements like so:
A{i,j,k}
where i, j and k are the indices to the 1st, 2nd and 3rd dimension, respectively.
Since your matrix is sparse, try to use ndsparse (N-dimensional sparse arrays FEX)

Matlab Isolating 2D Array from 3D Matrix

I have a 3D matrix called M of size <100x100x100>, so basically coordinates.
I am trying to get the array of at specific values of y. However using M(:,1,:) I get a <100x1x100> matrix whereas finding I can use M(:,:,1) and get a <100x100> matrix.
Is there an easy way to turn the <100x1x100> into a <100x100> by either isolating it a different way or using a short translation?
Thanks,
Does squeeze do what you want?
a = ones(100, 1, 100);
b = squeeze(a);
size(b) % 100x100

Matlab: a smart way to create a sparse matrix

I have to create a matlab matrix that is much bigger that my phisical memory, and i want to take advantage of the sparsity.
This matrix is really really sparse [say N elements in an NxN matrix], and my ram is enought for this. I create the matrix in this way:
A=sparse(zeros(N));
but it goes out of memory.
Do you know the right way to create this matrix?
zeros(N) is creating an NxN matrix, which is not sparse, hence you are running out of memory. Your code is equivalent to
temp = zeros(N)
A = sparse(temp)
Just do sparse(N,N).
Creating an all zeros sparse matrix, and then modifying it is extremely inefficient in matlab.
Instead of doing something like:
A = sparse(N,N) % or even A = sparse([],[],[],N,N,N)
A(1:N,7) = 1:N
It is much more efficient to construct the matrix in triplet form. That is,
construct the column and row indices and the nonzero entries first, then
form the matrix. For example,
i = 1:N;
j = 7*ones(1,N);
x = 1:N;
A = sparse(i,j,x,N,N);
I'd actually recommend the full syntax of sparse([],[],[],N,N,N).
It's useful to preallocate if you know the maximum number of nonzero elements as otherwise you'll get reallocs when you insert new elements.