Summing multiple matrices in matlab - matlab

I have a file containing 60 matrices. I would like get the mean of each value across those 60 matrices.
so the mean of the [1,1] mean of [1,2] across the matrices.
I am unable to use the mean command and am not sure what's the best way to do this.
Here's the file: https://dl.dropbox.com/u/22681355/file.mat

You can try this:
% concatenate the contents of your cell array to a 100x100x60 matrix
c = cat(3, results_foptions{:});
% take the mean
thisMean = mean(c, 3);
To round to the nearest integer, you can use
roundedMean = round(thisMean);

You should put all the matrices together in a 3 dimensional (matrix?), mat, as:
mat(:,:,1) = mat1;
mat(:,:,2) = mat2;
mat(:,:,3) = mat3;
etc...
then simply:
mean(mat, 3);
where the parameter '3' stipulates that you want the mean accros the 3rd dimension.

The mean of the matrix can be computed a few different ways.
First you can compute the mean of each column and then compute the mean of those means:
colMeans = mean( A );
matMean = mean(colMean);
Or you can convert the matrix to a column vector and compute the mean directly
matMean = mean( A(:) );

Related

In matlab how to sum rows of a matrix according to specified bins/subscripts in a non-iteration manner?

This question generalizes the previous one Any way for matlab to sum an array according to specified bins NOT by for iteration? Best if there is buildin function for this. I am not sure, but I tried and the answers in previous post seem not to work with matrices.
For example, if
A = [7,8,1,1,2,2,2]; % the bins or subscripts
B = [2,1; ...
1,1; ...
1,1; ...
2,0; ...
3,1; ...
0,2; ...
2,4]; % the matrix
then the desired function "binsum" has two outputs, one is the bins, and the other is the accumulated row vectors. It is adding rows in B according to subscripts in A. For example, for 2, the sum is [3,1] + [0,2] + [2,4] = [5,6], for 1 it is [1,1] + [2,0] = [3,1].
[bins, sums] = binsum(A,B);
bins = [1,2,7,8]
sums = [2,1;
1,1;
3,1;
5,6]
The first method accumarray says its "val" argument can only be a scalar or vector. The second method spare seems not to accept a vector as the value "v" for each tuple (i,j) neither. So I have to post for help again, and it is still not desired to use iterations to go over the columns of B to do this.
I am using 2017a. Many thanks again!
A way to do that is using matrix multiplication:
bins = unique(A);
sums = (A==bins.')*B;
The above is memory-expensive, as it builds an intermediate logical matrix of size M×N, where M is the the number of bins and N is the length of A. Alternatively, you can build that matrix as sparse logical to save memory:
[bins, ~, labels] = unique(A);
sums = sparse(labels, 1:numel(A), true)*B;
A method base on sort and cumsum:
[s,I]=sort(A);
c=cumsum(B(I,:));
k= [s(1:end-1)~=s(2:end) true];
sums = diff([zeros(1,size(B,2)); c(k,:)])
bins=s(k)

Large image matrix: save to small matrices

I'm new to MATLAB and its development. I have a image which is 1134 (rows) X 1134 (columns). I want that image to save 3 (columns) X 3 (rows). In order to do that I need 378 cells. For that I used following code, but it gives me an error.
image=imread('C:\Users\ven\Desktop\test\depth.png');
I=reshape(image,1,1134*1134);
chunk_size = [3 3]; % your desired size of the chunks image is broken into
sc = sz ./ chunk_size; % number of chunks in each dimension; must be integer
% split to chunk_size(1) by chunk_size(2) chunks
X = mat2cell(I, chunk_size(1) * ones(sc(1),1), chunk_size(2) *ones(sc(2),1));
Error:
Error using mat2cell (line 97)
Input arguments, D1 through D2, must sum to each dimension of the input matrix size, [1 1285956].'
Unfortunately your code does not work as you think it would.
The ./ operator performs point wise division of two matrices. Short example:
[12, 8] ./ [4, 2] == [12/4, 8/2] == [3, 4]
In order for it to work both matrices must have exactly the same size. In your case you try to perform such an operation on a 1134x1134 matrix (the image) and a 1x2 matrix (chunk_size).
In other words you can not use it to divide matrices into smaller ones.
However, a solution to your problem is to use the mat2cell function to pick out subsets of the matrix. A explanation of how it is done can be found here (including examples): http://se.mathworks.com/matlabcentral/answers/89757-how-to-divide-256x256-matrix-into-sixteen-16x16-blocks.
Hope it helps :)
Behind the C=A./B command is loop over all elements of A(ii,jj,...) and B(ii,jj,..) and each C(ii,jj,..)=A(ii,jj,...)/B(ii,jj,...).
Therefore martices A and B must be of same dimension.
If you want to split matrix into groups you can use
sc=cell(1134/3,1);
kk=0;ll=0;
for ii=2:3:1133
kk=kk+1;
for jj=2:3:1133
ll=ll+1;
sc{kk,ll}=image(ii-1:ii+1,jj-1:jj+1);
end
end
The code allocates cell array sc for resulting submatrices and arbitrary counters kk and ll. Then it loops over ii and jj with step of 3 representing centers of each submatrices.
Edit
Or you can use mat2cell command (type help mat2cell or doc mat2cell in matlab shell)
sc=mat2cell(image,3,3);
In both cases the result is cell array and its iith and jjth elements (matrices) are accessible by sc{ii,jj}. If you want call iith anr jjth number in kkth and llth matrix, do it via sc{kk,ll}(ii,jj).
In short, you divided a 1134 x 1134 by 2 x 1 matrix. That doesn't work.
The error "Matrix dimensions must agree**" is from the dividing a matrix with another matrix that doesn't have the right dimensions.
You used the scalar divide "./" which divided a matrix by another matrix.
You want something like:
n = 1134 / 3 % you should measure the length of the image
I1=image(1:n,1:n); % first row
I2=image(1:n,n:2n);
I3=image(1:n,2n:3n);
I4=image(n:2n,1:n); % second row
I5=image(n:2n,n:2n);
I6=image(n:2n,2n:3n);
I7=image(2n:3n,1:n); % third row
I8=image(2n:3n,n:2n);
I9=image(2n:3n,2n:3n);
from here:
http://au.mathworks.com/matlabcentral/answers/46699-how-to-segment-divide-an-image-into-4-equal-halves
There would be a nice loop you could do it in, but sometimes thinking is hard.

How to crop matrix of any number of dimensions in Matlab?

Suppose I have 4D matrix:
>> A=1:(3*4*5*6);
>> A=reshape(A,3,4,5,6);
And now I want to cut given number of rows and columns (or any given chunks at known dimensions).
If I would know it's 4D I would write:
>> A1=A(1:2,1:3,:,:);
But how to write universally for any given number of dimensions?
The following gives something different:
>> A2=A(1:2,1:3,:);
And the following gives an error:
>> A2=A;
>> A2(3:3,4:4)=[];
It is possible to generate a code with general number of dimension of A using the second form of indexing you used and reshape function.
Here there is an example:
Asize = [3,4,2,6,4]; %Initialization of A, not seen by the rest of the code
A = rand(Asize);
%% This part of the code can operate for any matrix A
I = 1:2;
J = 3:4;
A1 = A(I,J,:);
NewSize = size(A);
NewSize(1) = length(I);
NewSize(2) = length(J);
A2 = reshape(A1,NewSize);
A2 will be your cropped matrix. It works for any Asize you choose.
I recommend the solution Luis Mendo suggested for the general case, but there is also a very simple solution when you know a upper limit for your dimensions. Let's assume you have at most 6 dimensions. Use 6 dimensional indexing for all matrices:
A1=A(1:2,1:3,:,:,:,:);
Matlab will implicit assume singleton dimensions for all remaining dimension, returning the intended result also for matrices with less dimensions.
It sounds like you just want to use ndims.
num_dimensions = ndims(A)
if (num_dimensions == 3)
A1 = A(1:2, 1:3, :);
elseif (num_dimensions == 4)
A1 = A(1:2, 1:3, :, :);
end
If the range of possible matrix dimensions is small this kind of if-else block keeps it simple. It seems like you want some way to create an indexing tuple (e.g. (1:2,:,:,:) ) on the fly, which I don't know if there is a way to do. You must match the correct number of dimensions with your indexing...if you index in fewer dimensions than the matrix has, matlab returns a value with the unindexed dimensions collapsed into a single array (similar to what you get with
A1 = A(:);

Treat each row of a matrix as a vector in a MATLAB function

Say I have a nxm matrix and want to treat each row as vectors in a function. So, if I have a function that adds vectors, finds the Cartesian product of vectors or for some reason takes the input of several vectors, I want that function to treat each row in a matrix as a vector.
This sounds like a very operation in Matlab. You can access the ith row of a matrix A using A(i, :). For example, to add rows i and j, you would do A(i, :) + A(j, :).
Given an nxm matrix A:
If you want to edit a single column/row you could use the following syntax: A(:, i) for the ith-column and A(i, :) for ith-row.
If you want to edit from a column/row i to a column/row j, you could use that syntax: A(:, i:j) or A(i:j, :)
If you want to edit (i.e.) from the penultimate column/row to the last one, you could you: A(:, end-1:end) or A(end-1:end, :)
EDIT:
I can't add a comment above because I don't have 50 points, but you should post the function setprod. I think you should be able to do what you want to do, by iterating the matrix you're passing as an argument, with a for-next statement.
I think you're going to have to loop:
Input
M = [1 2;
3 4;
5 6];
Step 1: Generate a list of all possible row pairs (row index numbers)
n = size(M,1);
row_ind = nchoosek(1:n,2)
Step 2: Loop through these indices and generate the product set:
S{n,n} = []; //% Preallocation of cell matrix
for pair = 1:size(row_ind,1)
p1 = row_ind(pair,1);
p2 = row_ind(pair,2);
S{p1,p2} = setprod(M(p1,:), M(p2,:))
end
Transform the matrix into a list of row vectors using these two steps:
Convert the matrix into a cell array of the matrix rows, using mat2cell.
Generate a comma-separated list from the cell array, using linear indexing of the cell contents.
Example: let
v1 = [1 2];
v2 = [10 20];
v3 = [11 12];
M = [v1; v2; v3];
and let fun be a function that accepts an arbitrary number of vectors as its input. Then
C = mat2cell(M, ones(1,size(M,1)));
result = fun(C{:});
is the same as result = fun(v1, v2, v3).

z score with nan values in matlab (vectorized)

I am trying to calculate the zscore for a vector of 5000 rows which has many nan values. I have to calculate this many times so I dont want to use a loop, I was hoping to find a vectorized solution.
the loop solution:
for i = 1:end
vec(i,1) = (val(i,1) - nanmean(:,1))/nanstd(:,1)
end
a partial vectorized solution:
zscore(vec(find(isnan(vec(1:end) == 0))))
but this returns a vector the length of the original vector minus the nan values. Thus it isn't the same as the original size.
I want to calculated the zscore for the vector and then interpolate missing data after words. I have to do this 100s of times thus I am looking for a fast vectorized approach.
This is a vectorized solution:
% generate some example data with NaNs.
val = reshape(magic(4), 16, 1);
val(10) = NaN;
val(17) = NaN;
Here's the code:
valWithoutNaNs = val(~isnan(val));
valMean = mean(valWithoutNaNs);
valSD = std(valWithoutNaNs);
valZscore = (val-valMean)/valSD;
Then column vector valZscore contains deviations (Z scores), and has NaN values for NaN values in val, the original measurement data.
Sorry this answer is 6 months late, but for anyone else who comes across this thread:
The accepted answer isn't fully vectorised in that it doesn't do what the real zscore does so beautifully: That is, do zscores along a particular dimension of a matrix.
If you want to calculate zscores of a large number of vectors at once, as the OP says he is doing, the best solution is this:
Z = bsxfun(#divide, bsxfun(#minus, X, nanmean(X)) ,
nanstd(X) );
To do it on an arbitrary dimension, just put the dimension inside the nanmean and nanstd, and bsxfun takes care of the rest.
nanzscore = #(X,DIM) bsxfun(#divide, bsxfun(#minus, X, nanmean(X,DIM)), ...
nanstd(X,DIM));
anonymous function:
nanZ = #(xIn)(xIn-nanmean(xIn))/nanstd(xIn);
nanZ(vectorWithNans)
vectorized version of below anonymous function (assumes observations are in rows, variables in columns):
nanZ = #(xIn)(xIn-repmat(nanmean(xIn),size(xIn,1),1))./repmat(nanstd(xIn),size(xIn,1),1);
nanZ(matrixWithNans)