Summation of matrices - matlab

I want to sum together each cell in the same position for each matrix. I have k amount of (i,j) matrices stored in MATLAB as (i,j,k) and I want to create one matrix which is the sum of all them - however the MATLAB command sums together every value in each column whereas I want to sum together each cell in the same position from each matrix.
1 3 4 3 4 0 2 4 4
0 3 1 2 7 8 0 3 1
9 0 2 0 1 2 1 2 3
I want to create a matrix that is:
1+3+2 3+4+4 4+0+4
0+2+1 3+7+3 1+8+1
9+0+1 0+1+2 2+2+3
=
6 11 8
3 13 10
10 3 7

Use a second input to sum specifying the dimension along which to sum (in your case, 3):
>> A(:,:,1) = [ 1 3 4
0 3 1
9 0 2 ];
>> A(:,:,2) = [ 3 4 0
2 7 8
0 1 2 ];
>> A(:,:,3) = [ 2 4 4
0 3 1
1 2 3 ];
>> sum(A,3)
ans =
6 11 8
2 13 10
10 3 7

Related

Find rows of a matrix whose certain columns all match a condition

Suppose I have a matrix with many rows and columns, for example a small subset would be:
1 2 3 4 5 6
1 1 5 6 0 0
1 2 2 3 2 1
1 2 0 3 4 5
1 9 5 7 3 0
I want to find the rows whose columns #4, #5 and #6 contain elements greater than zero, so I in this case would get a vector like this:
1
3
4
I have tried using the find() function this way:
idx = find(y(:, 4:6) > 0)
but I get this:
1
2
3
4
5
6
8
9
10
11
13
14
You can use a combination of find and all like this:
idx = find(all(y(:,4:6) > 0, 2))
This gives:
>> y = [1 2 3 4 5 6; 1 1 5 6 0 0; 1 2 2 3 2 1; 1 2 0 3 4 5; 1 9 5 7 3 0]
y =
1 2 3 4 5 6
1 1 5 6 0 0
1 2 2 3 2 1
1 2 0 3 4 5
1 9 5 7 3 0
>> idx = find(all(y(:,4:6) > 0, 2))
idx =
1
3
4
The idea is that we extract columns 4 to 6, check which values are greater than 0, operate along the 2nd dimension with an AND condition (all), and then extract which indices (rows) are 1/true in the resulting column vector.

Dividing a vector to form different matrices

I have a two long vector. Vector one contains values of 0,1,2,3,4's, 0 represent no action, 1 represent action 1 and 2 represent the second action and so on. Each action is 720 sample point which means that you could find 720 consecutive twos then 720 consecutive 4s for example. Vector two contains raw data corresponding to each action. I need to create a matrix for each action ( 1, 2, 3 and 4) which contains the corresponding data of the second vector. For example matrix 1 should has all the data (vector 2 data) which occurred at the same indices of action 1. Any Help??
Example on small amount of data:
Vector 1: 0 0 1 1 1 0 0 2 2 2 0 0 1 1 1 0 0 2 2 2
Vector 2: 6 7 5 6 4 6 5 9 8 7 9 7 0 5 6 4 1 5 8 0
Result:
Matrix 1:
5 6 4
0 5 6
Matrix 2:
9 8 7
5 8 0
Here is one approach. I used a cell array to store the output matrices, hard-coding names for such variables isn't a good plan.
V1=[0 0 1 1 1 0 0 2 2 2 0 0 1 1 1 0 0 2 2 2]
V2=[6 7 5 6 4 6 5 9 8 7 9 7 0 5 6 4 1 5 8 0]
%// Find length of sequences of 1's/2's
len=find(diff(V1(find(diff(V1)~=0,1)+1:end))~=0,1)
I=unique(V1(V1>0)); %// This just finds how many matrices to make, 1 and 2 in this case
C=bsxfun(#eq,V1,I.'); %// The i-th row of C contains 1's where there are i's in V1
%// Now pick out the elements of V2 based on C, and store them in cell arrays
Matrix=arrayfun(#(m) reshape(V2(C(m,:)),len,[]).',I,'uni',0);
%// Note, the reshape converts from a vector to a matrix
%// Display results
Matrix{1}
Matrix{2}
Since, there is a regular pattern in the lengths of groups within Vector 1, that could be exploited to vectorize many things while proposing a solution. Here's one such implementation -
%// Form new vectors out of input vectors for non-zero elements in vec1
vec1n = vec1(vec1~=0)
vec2n = vec2(vec1~=0)
%// Find positions of group shifts and length of groups
df1 = diff(vec1n)~=0
grp_change = [true df1]
grplen = find(df1,1)
%// Reshape vec2n, so that we end up with N x grplen sized array
vec2nr = reshape(vec2n,grplen,[]).' %//'
%// ID/tag each group change based on their unique vector 2 values
[R,C] = sort(vec1n(grp_change))
%// Re-arrange rows of reshaped vector2, s.t. same ID rows are grouped succesively
vec2nrs = vec2nr(C,:)
%// Find extents of each group & use those extents to have final cell array output
grp_extent = diff(find([1 diff(R) 1]))
out = mat2cell(vec2nrs,grp_extent,grplen)
Sample run for the given inputs -
>> vec1
vec1 =
0 0 1 1 1 0 0 2 2 2 ...
0 0 1 1 1 0 0 2 2 2
>> vec2
vec2 =
6 7 5 6 4 6 5 9 8 7 ...
9 7 0 5 6 4 1 5 8 0
>> celldisp(out)
out{1} =
5 6 4
0 5 6
out{2} =
9 8 7
5 8 0
Here is another solution:
v1 = [0 0 1 1 1 0 0 2 2 2 0 0 1 1 1 0 0 2 2 2];
v2 = [6 7 5 6 4 6 5 9 8 7 9 7 0 5 6 4 1 5 8 0];
m1 = reshape(v2(v1 == 1), 3, [])'
m2 = reshape(v2(v1 == 2), 3, [])'
EDIT: David's solution is more flexible and probably more efficient.

How to subtract every nth column in Matlab

If I have an arbitrary n*m matrix called data and I would like to take differences of the matrix using gradually bigger steps.
The first case would have a first column equal to data(:,2)-data(:,1), the next column would be data(:,3)-data(:,2) and so on. This can be done with the following function.
data = diff(data,1,2)
Similarly I would also like to take differences based of every second column, so that the first entry would be data(:,3)-data(:,1) and the next data(:,5)-data(:,3) and so on.
This can't be done with diff, but is there any other function or method that can do it without resorting to looping?
I need to do the same thing for every n value up to 50.
Use column indexing to select the "right" columns and then use your favourite diff -
A = randi(9,4,9) %// Input array
stepsize = 2; %// Edit this for a different stepsize
out = diff(A(:,1:stepsize:end),1,2)
Output -
A =
8 9 9 8 3 2 6 8 7
2 5 5 7 5 3 9 6 3
2 7 7 2 4 1 2 4 1
6 2 1 5 4 9 9 3 7
out =
1 -6 3 1
3 0 4 -6
5 -3 -2 -1
-5 3 5 -2
I just wrote a simple wrapper function for the purpose.
function [ out ] = diffhigh( matrix, offset )
matrix_1 = matrix(:,(offset+1):size(matrix,1));
matrix_2 = matrix(:, 1:(size(matrix,1)-offset));
out = matrix_1 - matrix_2;
end
>> a
a =
3 5 1 2 4
1 2 3 4 5
1 4 5 3 2
1 2 4 3 5
2 1 5 3 4
>> diffhigh(a, 2)
ans =
-2 -3 3
2 2 2
4 -1 -3
3 1 1
3 2 -1
>> diffhigh(a, 3)
ans =
-1 -1
3 3
2 -2
2 3
1 3

Choose specific values in matrix in MATLAB

I would like to select some numbers in a MATLAB matrix which have values greater than 4 and set them equal to zero.
For example:
A=[5 6 1 3 4 9 2 8 3];
Now, replace all values greater than 4 with zeros and store as a new matrix A1:
A1=[0 0 1 3 4 0 2 0 3];
You might want to try something like this:
A(A>4)=0
Here it is:
>> A=[5 6 1 3 4 9 2 8 3]
A =
5 6 1 3 4 9 2 8 3
>> A(A>4)=0
A =
0 0 1 3 4 0 2 0 3

How to split 1xN vector into MxL vector and fill the rest with zeros?

I have a matrix
a = [1 2 3 4 5 6 7 8 9 10 11]
I need to split it into rows of 5 and fill the rest of the unset block with zeros like this:
transformed = [ 1 2 3 4 5 ;
6 7 8 9 10;
11 0 0 0 0 ]
You could first expand a to have the required number of elements like this;
a(15) = 0 % Matlab will automatically fill elements 12:14 with 0
then
transformed = reshape(a,[5,3])'
produces
ans =
1 2 3 4 5
6 7 8 9 10
11 0 0 0 0