user758077
user758077

Reputation:

cell arrays manipulations in MATLAB --- creating a relation matrix

I have two cell arrays, named as countryname and export.

There is only one column in countryname, which is the code of the names of countries:

USA  
CHN  
ABW

There are two columns in export:

USA ABW  
USA CHN  
CHN USA  
ABW USA  

Each pair (X,Y) in a row of export means "country X has relation with country Y". The size of countryname has been simplified to 3. How can I achieve the following in MATLAB?

Create a square 3 by 3 (in general n by n, where n is the size of countryname) matrix M such that

M(i,j)=1 if country i has relation with country j
M(i,j)=0 otherwise.

The country names are relabeled as positive integers in countryname.

Upvotes: 1

Views: 102

Answers (2)

PagMax
PagMax

Reputation: 8568

This is using basic MATLAB functionalities only. Solution posted above by @rayryeng is surely much more advanced and may be faster to code as well. However, this should also help you in understanding at fundamental level

clear
country={'USA','CHN','ABW'};

export={'USA' 'ABW'; 'USA' 'CHN'; 'CHN' 'USA' ; 'ABW' 'USA'};

M=zeros(length(country));

for i=1:length(country)
  c=country(i);
  ind_state=strfind(export(:,1),char(c));  % this gives state of every which is 1 or blank.
  ind_match=find(not(cellfun('isempty', ind_state))); % extracting only indices which are 1.

  exp_match=export(ind_match,2); % find corresponding export rel countries from second column

 % useful only when your first ind_match matrix has more than 1 element. 
 % Like 'USA' appears twice in first column  of export countries.

  for j=1:length(exp_match)  
    c=exp_match(j);
    ind_state=strfind(country,char(c));
    ind_match=find(not(cellfun('isempty', ind_state)));

    M(i,ind_match)=1; % Selective make elements of M 1 when there is match.
  end

end

M

Upvotes: 1

rayryeng
rayryeng

Reputation: 104504

The first thing you need to do is establish a mapping from the country name to an integer value from 1 to 3. You can do that with a containers.Map where the input is a string and the output is an integer. Therefore, we will assign 'USA' to 1, 'CHN' to 2 and 'ABW' to 3. Assuming that you've initialized the cell arrays like you've mentioned above:

countryname = {'USA', 'CHN', 'ABW'};
export = {'USA', 'ABW'; 'USA', 'CHN'; 'CHN', 'USA'; 'ABW', 'USA'};

... you would create a containers.Map like so:

map = containers.Map(countryname, 1:numel(countryname));

Once you have this, you simply map the country names to integers and you can use the values function to help you do this. However, what will be returned is a cell array of individual elements. We need to unpack the cell array, so you can use cell2mat for that. As such, we can now create a 4 x 2 index matrix where each cell element is converted to a numerical value:

ind = cell2mat(values(map, export));

We thus get:

>> ind

ind =

     1     3
     1     2
     2     1
     3     1

Now that we have this, you can use sparse to create the final matrix for you where the first column serves as the row locations and the second column serves as the column locations. These locations will tell you where it will be non-zero in your final matrix. However, this will be a sparse matrix and so you'll need to convert the matrix to full to finally get a numerical matrix.

M = full(sparse(ind(:,1), ind(:,2), 1));

We get:

>> M

M =

     0     1     1
     1     0     0
     1     0     0

As a more convenient representation, you can create a table to display the final matrix. Convert the matrix M to a table using array2table and we can add the row and column names to be the country names themselves:

>> T = array2table(M, 'RowNames', countryname, 'VariableNames', countryname)

T = 

           USA    CHN    ABW
           ___    ___    ___

    USA    0      1      1  
    CHN    1      0      0  
    ABW    1      0      0 

Take note that the above code to create the table only works for MATLAB R2013b and above. If that isn't what you require, just stick with the original numerical matrix M.

Upvotes: 5

Related Questions