I'm wondering if it's possible for Neural Network to operate on matrices say I want to:
A(i)=matrix(10,10) -> B(i)=matrix(10,10)
input = vector of matrices, i = sample size
output = vector of matrices
Say I would like to guess an matrix operation transforming matrix into another matrix ie
f(A(i,j))=2*A(i,j)*b
Matlab does not take arrays with dimension >2 in NNtool
Any idea?
Thanks
You can simply convert the arrays into vectors before passing them to NNtool. It won't make a difference for the result of your calculation.
In other words, instead of passing A(:,:,i) to NNtool, you pass reshape(A(:,:,i),[],1). Then you reshape the output into a 10x10 array by using B = reshape(outputOfNNtool,10,10).
Related
I attempted to use the solution from this post: Multiply a 3D matrix with a 2D matrix, to vectorize the multiplication of a one dimensional with a three dimensional, but to no avail. Any help would be greatly appreciated!
for s = 1: s_length
for a = 1: a_length
for g = g_length
two_dim(s,a) = two_dim(s,a) + one_dim(g) * three_dim(s,a,g);
end
end
end
I think this does what you want.
two_dim = reshape(three_dim, [], size(three_dim,3))*one_dim(:);
two_dim = reshape(two_dim, size(three_dim,1), size(three_dim,2));
This works as follows:
First line reshapes your 3D array into a matrix, collapsing the first two dimensions into one. That way the operation you want is standard multiplication of the resulting matrix times a column vector.
Second line reshapes the result into matrix shape.
mtimes does not work with inputs with dimension larger than 2, so you have to find a way to do the multiplication by yourself. The solution of Luis Mendo is a nice solution; here is another one using bsxfun:
two_dim = two_dim + squeeze(sum(bsxfun(#times, three_dim, reshape(one_dim,[1 1 g_length])),3));
Here is how it works:
reshape makes the vector one_dim looking like a 3D array. This must be done because the multiplication between the vector and the 3D array is performed along the 3rd dimension, so Matlab need a hint on sizes.
bsxfun perfoms the element-wise multiplcation, so the result must be sumed up along the 3rd dimension (and squeezed to be compliant with a 2D matrix format)
In my current analysis, I am trying to multiply a matrix (flm), of dimension nxm, with the inverse of a matrix nxmxp, and then use this result to multiply it by the inverse of the matrix (flm).
I was trying using the following code:
flm = repmat(Data.fm.flm(chan,:),[1 1 morder]); %chan -> is a vector 1by3
A = (flm(:,:,:)/A_inv(:,:,:))/flm(:,:,:);
However. due to the problem of dimensions, I am getting the following error message:
Error using ==> mrdivide
Inputs must be 2-D, or at least one
input must be scalar.
To compute elementwise RDIVIDE, use
RDIVIDE (./) instead.
I have no idea on how to proceed without using a for loop, so anyone as any suggestion?
I think you are looking for a way to conveniently multiply matrices when one is of higher dimensionality than the other. In that case you can use bxsfun to automatically 'expand' the smaller matrix.
x = rand(3,4);
y = rand(3,4,5);
bsxfun(#times,x,y)
It is quite simple, and very efficient.
Make sure to check out doc bsxfun for more examples.
Is it possible to use pagefun to calculate the norm (and execute other built-in GPU functions - http://www.mathworks.co.uk/help/distcomp/run-built-in-functions-on-a-gpu.html) on multiple pages simultaneously?
For example, I need to calculate the norms of a 3D array.
N = 10000
Sig = gpuArray(2,2000,N) % This is just to get an idea of the dimensions. Its populated elsewhere
% This is what I am currently doing.
for k = 1:N
TNorm(k,:) = [norm(Sig(1,:,k),2) norm(Sig(2,:,k),2)];
end
Is there a way to execute it in one go rather than iterate through the 3rd dimension to calculate the norm each time? Can something like this be done?
pagefun(norm(Sig,2)) % This gives the error: Input data must be a double or single vector or 2D matrix.
Thanks in advance! :)
Say you have a 3D array, in your case lets call it E:
E = rand(3,3,4) % This is a 3D array with size 3x3x4
if you want to calculate the norm of page so from 1 to 4 in this case, you can use:
norm_E = arrayfun(#(idx) norm(E(:,:,idx)), 1:size(E,3))
The output will be:
norm_E = [(norm array 1),(norm array 2),(norm array 3),(norm array 4)]
You are also not limited to the 2-norm you can use any norm you please for example if you wanted to use the infinity norm you could put:
norm_E = arrayfun(#(idx) norm(E(:,:,idx),inf), 1:size(E,3))
Using arrayfun is faster than a for loop. I apologize if you are restricted to using pagefun I do not have that feature with my version of Matlab.
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)
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{:});