Combining Matches of Numbers in Matrix Columns - MATLAB

I have a matrix (A) in the form (much more in reality):

205 204 201 202 208 202 

How can I calculate the coincidence of numbers in a column after a column, and then output this into a matrix?

I would like the final matrix to be executed with min (A): max (A) (or be able to specify a specific range) above and below, and for it matches the numbers in each column to match. Using the above example:

  200 201 202 203 204 205 206 207 208 200 0 0 0 0 0 0 0 0 0 201 0 0 1 0 0 0 0 0 0 202 0 0 0 0 0 1 0 0 0 203 0 0 0 0 0 0 0 0 0 204 0 0 0 0 0 0 0 0 1 205 0 0 0 0 0 0 0 0 0 206 0 0 0 0 0 0 0 0 0 207 0 0 0 0 0 0 0 0 0 208 0 0 0 0 0 0 0 0 0 

(Matrix marks are not required)

Two important points: the count should be non-duplicate and occur digitally. For example, a column containing:

 205 202 

Denotes this as 202, which has a value of 205 (as shown in the above matrix), but NOT 205 with 202 - the duplicate is the opposite. When deciding which number to use as a reference, it should be the smallest.

EDIT:

enter image description here

+5
source share
3 answers

sparse to the rescue!

Let your data and the desired range be defined as

 A = [ 205 204 201 202 208 202 ]; %// data. Two-row matrix limits = [200 208]; %// desired range. It needn't include all values of A 

Then

 lim1 = limits(1)-1; s = limits(2)-lim1; cols = all((A>=limits(1)) & (A<=limits(2)), 1); B = sort(A(:,cols), 1, 'descend')-lim1; R = full(sparse(B(2,:), B(1,:), 1, s, s)); 

gives

 R = 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

Alternatively, you can opt out of sort and use the addition of a matrix followed by triu to get the same result (possibly faster):

 lim1 = limits(1)-1; s = limits(2)-lim1; cols = all( (A>=limits(1)) & (A<=limits(2)) , 1); R = full(sparse(A(2,cols)-lim1, A(1,cols)-lim1, 1, s, s)); R = triu(R + R.'); 

Both approaches handle repeating columns (up to sorting), correctly increasing their number. For instance,

 A = [205 204 201 201 208 205] 

gives

 R = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+4
source

See what it was for you -

 range1 = 200:208 %// Set the range A = A(:,all(A>=min(range1)) & all(A<=max(range1))) %// select A with columns %// that fall within range1 A_off = A-range1(1)+1 %// Get the offsetted indices from A A_off_sort = sort(A_off,1) %// sort offset indices to satisfy "smallest" criteria out = zeros(numel(range1)); %// storage for output matrix idx = sub2ind(size(out),A_off_sort(1,:),A_off_sort(2,:)) %// get the indices to be set unqidx = unique(idx) out(unqidx) = histc(idx,unqidx) %// set coincidences 

FROM

 A = [205 204 201 201 208 205] 

it gets -

 out = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

Here you can use several performance-oriented tricks -

I. Replace

 out = zeros(numel(range1)); 

from

 out(numel(range1),numel(range1)) = 0; 

II. Replace

 idx = sub2ind(size(out),A_off_sort(1,:),A_off_sort(2,:)) 

from

 idx = (A_off_sort(2,:)-1)*numel(range1)+A_off_sort(1,:) 
+3
source

How about a solution using accumarray ? First I have to sort each column myself, and then use the first row as the first dimension in the final accumulation matrix, and then the second row as the second dimension in the final accumulation matrix. Sort of:

 limits = 200:208; A = A(:,all(A>=min(limits)) & all(A<=max(limits))); %// Borrowed from Divakar %// Sort the columns individually and bring down to 1-indexing B = sort(A, 1) - limits(1) + 1; %// Create co-occurrence matrix C = accumarray(B.', 1, [numel(limits) numel(limits)]); 

FROM

 A = [205 204 201 202 208 202] 

This is the conclusion:

 C = 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

With duplicates (borrowed from Luis Mendo):

 A = [205 204 201 201 208 205] 

Conclusion:

 C = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+3
source

Source: https://habr.com/ru/post/1205945/


All Articles