Randperm in symmetric matrix

If i have a symmetric matrix and i want to select a random entries from this matrix and let these random entries belong to a set omega.. I can do that by use a randperm function however since the matrix is symmetric, I want to select the same corresponding entries.. so for example if we have 4×4 matrix and in randperm select the indices 2 6 8 and set this as omega then i want to update omega to include also the symmetric position such that 5 6 14

 Accepted Answer

%Let y be the matrix
y=rand(4);
s=size(y);
%Indices
x=[2 6 8];
[r,c]=ind2sub(s,x);
%Interchanging row and column
z=sub2ind(s,c,r)
z = 1×3
5 6 14
%Include the indices
x=[x z]
x = 1×6
2 6 8 5 6 14

More Answers (2)

To select random entries from a symmetric matrix and ensure that the corresponding symmetric positions are also included in the selected set, you can do the following:
  1. Use the randperm function to generate a random set of indices omega in the lower triangle of the matrix.
  2. Generate the corresponding indices in the upper triangle by adding the number of columns to each index. For example, if omega = [2 6 8], then the corresponding upper triangle indices would be omega + 4 = [6 10 12].
  3. Concatenate the two sets of indices to obtain the complete set of indices omega, including both the lower and upper triangle.
Here's an example code snippet that implements these steps:
% Generate a random symmetric matrix
n = 4;
A = randn(n);
A = A + A.'; % make A symmetric
% Generate a random set of indices in the lower triangle
n_lower = n*(n-1)/2;
omega_lower = randperm(n_lower, 3);
% Generate the corresponding indices in the upper triangle
omega_upper = omega_lower + n;
% Concatenate the two sets of indices to obtain the complete set
omega = sort([omega_lower omega_upper]);
% Display the selected indices and their corresponding symmetric positions
fprintf('Selected indices:\n');
disp(omega(:));
fprintf('Corresponding symmetric positions:\n');
disp(omega(:) + n*(ceil(omega(:)/n) - 1) - (n*(n-1)/2)));
This code generates a random 4x4 symmetric matrix A and selects a random set of 3 indices in the lower triangle using randperm. It then computes the corresponding indices in the upper triangle and concatenates the two sets of indices to obtain the complete set omega. Finally, it displays the selected indices and their corresponding symmetric positions in the matrix.
Note that in the last line of the code, the symmetric positions are computed using a formula that maps each index to its corresponding row and column in the lower triangle of the matrix, and then maps that position to its corresponding index in the upper triangle. This formula assumes that the matrix is square (i.e., n is even) and that the indices in omega are sorted in ascending order. If your matrix has a different size or the indices are not sorted, you may need to adjust the formula accordingly.

5 Comments

Actually this way not work because when you calculate the indices of omega upper and calculate the A(omega upper) it not going to be the same as A(omega lower) , and it should be the same because for example if i have indice 2 in omega lower ad it will be in the position (2,1) , then I want to select also the symmetric position which is (1,2) in omega upper and they should be equal to the same value since A symmetric
You are correct that selecting the upper triangle and lower triangle of a symmetric matrix will result in different sets of indices and different matrices when indexed by those sets. However, since the matrix is symmetric, you can compute the values of the upper triangle based on the lower triangle (or vice versa) by transposing the matrix.
Here's an example of how you can implement this:
% generate a symmetric matrix A
n = 4;
A = randn(n);
A = A + A.'; % make A symmetric
% generate a set of random indices in the lower triangle of A
n_lower = n*(n-1)/2; % number of elements in lower triangle
omega_lower = randperm(n_lower, 3); % select 3 random elements in lower triangle
% create the corresponding set of indices in the upper triangle
[I,J] = meshgrid(1:n);
upper_mask = tril(false(n), -1);
upper_indices = find(upper_mask);
omega_upper = upper_indices(ismember(upper_indices, sub2ind([n,n], J(:), I(:))));
omega_upper = omega_upper(ismember(omega_upper, sub2ind([n,n], J(upper_mask), I(upper_mask)))); % only keep indices that correspond to lower triangle
% compute the values of A at the selected indices in the lower triangle
A_lower = A(omega_lower);
% compute the values of A at the corresponding indices in the upper triangle
A_upper = A.';
A_upper = A_upper(omega_upper);
% verify that the values are equal
isequal(A_lower, A_upper) % should return true
Is it works with you? Because it isn't with me
  • Generate the corresponding indices in the upper triangle by adding the number of columns to each index. For example, if omega = [2 6 8], then the corresponding upper triangle indices would be omega + 4 = [6 10 12].
No, in a 4 x 4 array, adding 4 to a linear index gets you the index of the same row in the next column.
[r, c] = ind2sub([4 4], LINEARINDICES);
SYMLINEARINDICES = sub2ind([4 4], c, r)
I think user Jack is a chat bot so probably that's why it doesn't work.

Sign in to comment.

You can build a mapping:
LINEARINDICES = randperm(16,3)
LINEARINDICES = 1×3
9 6 13
MAPPING = reshape(reshape(1:16,4,4).', 1, []);
SYMLINEARINDICES = MAPPING(LINEARINDICES)
SYMLINEARINDICES = 1×3
3 6 4
%verification
[r, c] = ind2sub([4 4], LINEARINDICES);
SYMLINEARINDICES2 = sub2ind([4 4], c, r)
SYMLINEARINDICES2 = 1×3
3 6 4

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!