dynamic output for ndgrid in Matlab - matlab

I'd like to generate indices for an n-dimensional array with ndgrid. Since the dimension may change, is there a way to wrap ndgrid so that the number of outputs for ndgrid is dynamic? Say for example, I want the output for a 2 dimension array to be:
[output{1} output{2}]=ndgrid(1:5)
and the output for a 3 dimension array to be:
[output{1} output{2} output{3}]=ndgrid(1:5)
so on and so forth...

If you want different sizes for the different dimensions, you might want to consider something like:
creating adjacency matrix.
The relevant part is:
ndim = numel(sz);
I=cell(ndim,1);
% construct the neighborhood
for di=1:ndim
I{di}=1:sz(di);
end
[I{1:ndim}]=ndgrid(I{:});

Related

mathematical operation (Sum) on array elements

I want to sum elements of array which every element is a matrix.
I wrote below but not working:
AA={[1 2;3 4],[5 6;7 8]}
i=1:2;
sum(AA{i})
If you are wanting to perform operations across a set of 2-D matrices, all of which are the same size (and not too huge), it's easiest to store them as a 3-D matrix instead. See here for discussion/examples.
If you already have your matrices in a cell array, as in your example, you can concatenate them into a 3-D matrix using cat and sum across the third dimension without a for loop using sum:
mat = sum(cat(3, AA{:}), 3);

Submatrix based on size vector

It seems like this problem should be common, but I haven't found a good duplicate...
I'm implementing a level 2 S-function with a variable-sized multidimensional output. The state has to be in fixed-size Dwork vectors, so I zero-pad the input matrix to the maximum size allowed for the input and then reshape it to a vector.
When I reshape it back to a matrix for output, I need to trim it back down to the correct size.
The function needs to be general enough to support an arbitrary number of dimensions. The size of the output is stored in a size array.
For example, I may have a 500x500 matrix N, and a size array S = [40 25]. I need a MATLAB expression that would give me N(1:S(1), 1:S(2)), but it needs to work for any number of dimensions so I can't simply hardcode it like that.
Here is a solution in m-code:
%your input
M=rand(10,10,10);
S=[2,3,4]
%generate indices:
Index=arrayfun(#(x)(1:x),S,'uni',0)
%use comma separated list to index:
smallM=M(Index{:})

Putting vectors of different size in a matrix

I am trying to add a number of vectors in a Matrix where each row represents a vector, but it gives me "Subscripted assignment dimension mismatch." error. The main problem is that each vector has a different size. I tried to add zeros at the end of the short vectors but I couldn't do it. Any Help.
Example:
%signal is a vector of data.
[x(1,:),y(1,:)] = findpeaks(signal1);
[x(2,:),y(2,:)] = findpeaks(signal2); %error as the peaks count in signal 2 is not the same as in signal 1.
OK, given two vectors of unequal length,
A=rand(1,10)
B=rand(1,5)
the proper way to deal with this is to use a cell array
D={A;B}
And then you can get whatever elements you want like this, for example:
D{1}(1:3) %// A(1:3)
If you don't want to use cells, you can add rows using this little function that adds row vector M to matrix F
addRow=#(F,M) [F NaN(size(F,1),size(M,2)-size(F,2));M NaN(1,size(F,2)-size(M,2))]
you would use it like this:
F=A
F=addRow(F,B)

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)

Histogram on elements of a 2D matrix in Matlab

I am wondering if there is any build in function or an easy way to plot a histogram of elements of a 2d array.
For example, if A=rand(100,1), then A is an 1D array, and hist(A) can do the histogram.
However, what if A=rand(100,100), and I would like to make a histogram on elements of A, just like treating each element in A as an element on a 1D array. Is there a easy way to do so?
You just have to reshape A into a vector, then you can use hist as usual:
hist(A(:))
This command will do what you want:
hist(reshape(A, prod(size(A)), 1))
What it does is create a vector out of the matrix A by reshaping it into a matrix with one column and a number of rows equal to the number of elements of A:
prod(size(A)) = number_of_columns(A) * number_of_rows(A)
Or the short way:
hist(A(:))
This takes every element of A in sequence and thus also generates a vector.