I have 10 bins, and each bin contains a specific number of observations, e.g.:
a = [0,0,1,0,0,2,0,0,0,2]
I'd like to subsequently tally how many times any given pair of (non-zero) bins co-occur - based on the number of observations.
Given the above example, bin#3 = 1, bin#6 = 2 and bin#10 = 2.
This means that bin 3 and 6 co-occurred once, bin 3 and 10 co-occurred once, and bin 6 and 10 co-occurred twice (the minimum value of the pair is taken).
My desired output is a full matrix, listing every possible bin combination (columns 1-2) and the tally of what was observed (column 3):
1 2 0
1 3 0
1 4 0
1 5 0
1 6 0
1 7 0
1 8 0
1 9 0
1 10 0
2 3 0
2 4 0
2 5 0
2 6 0
2 7 0
2 8 0
2 9 0
2 10 0
3 4 0
3 5 0
3 6 1
3 7 0
3 8 0
3 9 0
3 10 1
4 5 0
4 6 0
4 7 0
4 8 0
4 9 0
4 10 0
5 6 0
5 7 0
5 8 0
5 9 0
5 10 0
6 7 0
6 8 0
6 9 0
6 10 2
7 8 0
7 9 0
7 10 0
8 9 0
8 10 0
9 10 0
Is there a short and/or fast way of doing this?
You can get all combinations of the bin numbers in many ways. I'll use combvec for ease.
Then it's relatively simple to vectorise this using min...
a = [0,0,1,0,0,2,0,0,0,2];
n = 1:numel(a);
% Use unique and sort to get rid of duplicate pairs when order doesn't matter
M = unique( sort( combvec( n, n ).', 2 ), 'rows' );
% Get rid of rows where columns 1 and 2 are equal
M( M(:,1) == M(:,2), : ) = [];
% Get the overlap count for bins
M( :, 3 ) = min( a(M), [], 2 );
Try this.
bin_output = [....];
bin_matrix = [0,0,1,0,0,2,0,0,0,2];
bin_nonzero = find(bin_matrix);
for j = 1:length(bin_nonzero);
if isequal(j,length(bin_nonzero))
break;
end
for k = (j+1):(length(bin_nonzero))
for m = 1:length(bin_output)
if isequal(bin_output(m,1),j) && isequal(bin_output(m,2),k)
bin_output(m,3) = bin_output(m,3) + min([bin_matrix(1,bin_nonzero(1,j)),bin_matrix(1,bin_nonzero(1,k))]);
end
end
end
end
It was hard to phrase the question, but here's an example of what I'm looking for:
1 2 3 4
2 1 1 1
2 2 3 1
0 0 0 0
and in column one, I add all the value of all of the first three rows and save it to the third and so on, so that it becomes:
1 2 3 4
2 1 1 1
2 2 3 1
5 5 7 6
I think you can use sum:
octave:23> m = [1 2 3 4; 2 1 1 1; 2 2 3 1; 0 0 0 0]
m =
1 2 3 4
2 1 1 1
2 2 3 1
0 0 0 0
octave:24> m(length(m), :) = sum(m)
m =
1 2 3 4
2 1 1 1
2 2 3 1
5 5 7 6
I have 2 matrices:
T3(:,:,1) =
0 0 0 0 1 0 0 0 0
0 0 0 0 2 0 0 0 0
0 0 0 0 3 0 0 0 0
0 1 0 1 4 2 0 4 0
0 3 0 2 6 3 0 5 0
2 4 2 5 7 5 4 6 5
4 5 5 7 8 8 5 7 6
5 6 6 8 9 9 8 9 8
T3(:,:,2) =
2 1 1 1 1 1 1 1 1
3 3 2 2 2 2 2 2 2
4 4 4 3 3 3 3 3 3
5 5 5 5 4 4 4 4 4
6 6 6 6 6 5 5 5 5
7 7 7 7 7 7 6 6 6
8 8 8 8 8 8 8 7 7
9 9 9 9 9 9 9 9 8
How do I make values present in T3(:,:,1) turn to zero in T3(:,:,2)?
e.g. in the first column of T3(:,:,1) the values are 2,4,5. I'd like the first column of T3(:,:,2) to have the the values 2,4,5 as zero.
T3(:,:,2) =
0 0 1 0 0 1 1 1 1
3 0 0 0 0 0 2 2 2
0 0 4 3 0 0 3 3 3
0 0 0 0 0 4 0 0 4
6 0 0 6 0 0 0 0 0
7 7 7 0 0 7 6 0 0
8 8 8 0 0 0 0 0 7
9 9 9 9 0 0 9 0 0
I wonder if there is a way to do this using setdiff or unique.
for y=1:H-1
for z=1:H-1
for h=1:H
for d=1:D-1
if T3(y,h,d+1) == T3(z,h,d)
T3(y,h,d+1)=0;
end
end
end
end
end
I can do it as a loop where H=number of columns (9) and D= number of dimensions (2). There must be a better way :)?
Many thanks guys.
I have matrix (a) with (1:10),<10 x 1> double. I would like to copy the values and rearrange them column wise into another matrix var. (b). See example below. Also, what method would be most efficient at this task?
matrix a matrix b
1 1
2 2 2
3 3 3 3
4 4 4 4 4
5 5 5 5 5 5
6 6 6 6 6 6 6
7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9
10 10 10 10 10 10 10 10 10 10 10
update:
Hi once again Amro. How about if I wanted to define which values to copy. See below example:
matrix a matrix b
column: 1 2 3 4 5 6 7
1 1
2 2 2
3 3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10 10
Try:
>> a = (1:10)'
a =
1
2
3
4
5
6
7
8
9
10
>> b = tril(repmat(a,1,10))
b =
1 0 0 0 0 0 0 0 0 0
2 2 0 0 0 0 0 0 0 0
3 3 3 0 0 0 0 0 0 0
4 4 4 4 0 0 0 0 0 0
5 5 5 5 5 0 0 0 0 0
6 6 6 6 6 6 0 0 0 0
7 7 7 7 7 7 7 0 0 0
8 8 8 8 8 8 8 8 0 0
9 9 9 9 9 9 9 9 9 0
10 10 10 10 10 10 10 10 10 10
I think in the second matrix you specified you made an error. I'm assuming you wanted to do something like this:
b =
1 0 0 0 0 0
2 2 0 0 0 0
0 3 3 0 0 0
0 0 4 4 0 0
0 0 0 5 5 0
0 0 0 0 6 6
this is simple to do:
%define vector of arbitrary length
a=1:6;
%generate b with shifted diagonal matrices
b=diag(a)+diag(a(2:end),-1);
the second argument of diag just shifts the resulting diagonal.
I want to replace duplicate elements from a vector with 0, and keep only the first occurrence.
If I have a vector like
[ 1 1 2 2 2 3 3 3 4 4 4 4 5 5 5 5 6 6 6 ]
how could I transform it into
[ 1 0 2 0 0 3 0 0 4 0 0 0 5 0 0 0 6 0 0 ] ?
Thanks.
a = [ 1 1 2 2 2 3 3 3 4 4 4 4 5 5 5 5 6 6 6 ];
[c, ia] = unique(a, 'first');
t = a;
t(ia) = 0;
filtered_vect = a - t;
edit: That in a more concise way, destroying the original vector:
a = [ 1 1 2 2 2 3 3 3 4 4 4 4 5 5 5 5 6 6 6 ];
[c, ia] = unique(a, 'first');
a(~ismember(1:length(a),ia)) = 0;