How to move larger values close to matrix diagonal in a correlation matrix

后端 未结 2 1296
广开言路
广开言路 2021-01-06 09:29

I have a correlation matrix X of five elements(C1,C2,C3,C4,C5)

      C1    C2    C3     C4   C5  

 C1    *     1     0     1     0
 C2    1     *     0              


        
2条回答
  •  梦毁少年i
    2021-01-06 10:00

    A = [1 0  0 1 0;
         0 1  0 0 1;
         0 0  1 0 1;
         1 1  0 1 0;
         0 1  0 0 1]; 
    N = length(A);
    switched = false;
    
    %%
    % Calculate initial Global Energy
    disp(A);
    global_energy = 0;
    for l = 1:N
        for m = 1:N
            if(A(l,m))
                global_energy = global_energy + (l-m)^2/2;
            end
        end
    end
    disp(global_energy); 
    
    counter = 0;
    counter_cutoff = 10000000000;
    while(true)
        switched = false;
        counter = counter + 1;
        for i = 1:N
            for j = i+1:N        
                current_metric = 0; % Calculate metric of row i and j with columns i and j
                permuted_metric = 0; % Calculate metric if they were permuted        
                % Row i
                for k = 1:N
                    if(k ~= i && k ~= j && A(i,k))
                        current_metric = current_metric + (i-k)^2/2;
                        permuted_metric = permuted_metric + (j-k)^2/2;
                    end
                end
                % Row j
                for k = 1:N
                    if(k ~= i && k ~= j && A(j,k))
                        current_metric = current_metric + (j-k)^2/2;
                        permuted_metric = permuted_metric + (i-k)^2/2;
                    end
                end
                % Col i
                for k = 1:N
                    if(k ~= i && k ~= j && A(k,i))
                        current_metric = current_metric + (i-k)^2/2;
                        permuted_metric = permuted_metric + (j-k)^2/2;
                    end
                end
                % Col j 
                for k = 1:N
                    if(k ~= i && k ~= j && A(k,j))
                        current_metric = current_metric + (j-k)^2/2;
                        permuted_metric = permuted_metric + (i-k)^2/2;
                    end
                end
    
                % If permuted metric is less, swap columns and rows - set switched to true 
                if(permuted_metric < current_metric)
                    switched = true; % there was at least one switch
                    % Now switch rows and columns
                    % Switch columns first
                    A(:,[i j]) = A(:,[j i]);
                    % Now switch rows
                    A([i j],:) = A([j i],:);
                end
            end
        end
        if(~switched || counter > counter_cutoff)
            % All permutations did not lead to a switching of rows and columns
            break;
        end
    end
    
    % Calculate final Global Energy
    disp(A);
    global_energy = 0;
    for l = 1:N
        for m = 1:N
            if(A(l,m))
                global_energy = global_energy + (l-m)^2/2;
            end
        end
    end
    disp(global_energy); 
    

    Terminal:

     1     0     0     1     0
     0     1     0     0     1
     0     0     1     0     1
     1     1     0     1     0
     0     1     0     0     1
    
    22
    
     1     1     0     0     0
     1     1     1     0     0
     0     0     1     1     0
     0     0     1     1     0
     0     0     0     1     1
    
     3
    

提交回复
热议问题