Diagonal sums with non-zero elements
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Ingrid Wilson
le 2 Mai 2022
Modifié(e) : Riccardo Scorretti
le 2 Mai 2022
Hello,
I have a matrix A, and have computed all possible (n factorial) permutations of this matrix. Next, I want to compute the sum of the diagonals of the permuted matrices containing non-zero elements. I've written a nested for loop to check for non-zero elements, and then, if there are no zero-elements, I want to save the diagonal sum in "diag". But it saves diagonal sums that still contain zero-elements.
All permutations of matrix A, with non-zeros on the diagonal, have constant diagonal sum 1.6. This means that if the code works, it should only find diagonals with sum 1.6
%define A
A = [0 0.4 0.3 0.3; 0 0 0.5 0.5; 0.5 0.3 0 0.2; 0.5 0.3 0.2 0];
[n,n] = size(A);
%find all permutations of A
B = reshape(A(:,flipud(perms(1:4)).'),n,n,factorial(n));
%compute diagonal sums with non-zero elements
diag = zeros(1, factorial(n));
for i = 1:factorial(n)
for j=1:n
if B(j,j,i) == 0
break
end
diag(1,i) = trace(B(:,:,i));
end
end
diag
0 commentaires
Réponse acceptée
Riccardo Scorretti
le 2 Mai 2022
Modifié(e) : Riccardo Scorretti
le 2 Mai 2022
Hi Ingrid,
I guess you mean you want to compute te sum of the diagonals of the permuted matrices containing all non-zero elements. In this case I would program like that:
%define A
A = [0 0.4 0.3 0.3; 0 0 0.5 0.5; 0.5 0.3 0 0.2; 0.5 0.3 0.2 0];
You wrote: [n,n] = size(A). This is weird (for me), I would rather program like that:
[n, m] = size(A); % ***
assert(n == m, 'The matrix A must be square!') % ***
%find all permutations of A
B = reshape(A(:,flipud(perms(1:4)).'),n,n,factorial(n));
I need to use the built-in function diag, so I had to rename diag to diag_
%compute diagonal sums with non-zero elements
diag_ = zeros(1, factorial(n)); % diag "shades" a function with the same name
for i = 1:factorial(n)
if any(diag(B(:,:,i)) == 0) , continue ; end
diag_(1,i) = trace(B(:,:,i));
end
diag_'
The error in your program was here:
%define A
A = [0 0.4 0.3 0.3; 0 0 0.5 0.5; 0.5 0.3 0 0.2; 0.5 0.3 0.2 0];
[n,n] = size(A);
%find all permutations of A
B = reshape(A(:,flipud(perms(1:4)).'),n,n,factorial(n));
%compute diagonal sums with non-zero elements
diag = zeros(1, factorial(n));
for i = 1:factorial(n)
for j=1:n
if B(j,j,i) == 0
Consider the case: B(:,:,j) = [1 0 0 0 ; 0 2 0 0 ; 0 0 0 0 ; 0 0 0 0]. In the first two iterations B(j,j,i) ~= 0, so you assign to diag(1,i) the trace of B(:,:,i). But at the third iteration, B(3,3,i) = 0: if you break the loop, it is mandatory to reset the value of diag(1,j) to 0 otherwise it will store the wrong result.
By the way, in this algorithm the computation of the trace is uselessly repeated many times.
diag(1,i) = 0; % THIS WAS MISSING
break
end
diag(1,i) = trace(B(:,:,i));
end
end
diag
Of course, both versions give exactly the same result.
0 commentaires
Plus de réponses (1)
Davide Masiello
le 2 Mai 2022
Modifié(e) : Davide Masiello
le 2 Mai 2022
%define A
A = [0 0.4 0.3 0.3; 0 0 0.5 0.5; 0.5 0.3 0 0.2; 0.5 0.3 0.2 0];
[n,n] = size(A);
%find all permutations of A
B = reshape(A(:,flipud(perms(1:4)).'),n,n,factorial(n));
%compute diagonal sums with non-zero elements
dgnl = [];
for i = 1:factorial(n)
if all(diag(B(:,:,i))~=0)
dgnl = [dgnl,sum(diag(B(:,:,i)))];
end
end
dgnl
Better not use diag as variable name, since it's already a MatLab in-built function.
0 commentaires
Voir également
Catégories
En savoir plus sur Operating on Diagonal Matrices dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!