Diagonal sums with non-zero elements

1 次查看(过去 30 天)
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

采纳的回答

Riccardo Scorretti
编辑:Riccardo Scorretti 2022-5-2
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_'
ans = 24×1
0 0 0 0 0 0 0 0 0 1.6000
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
diag = 1×24
0 0 0 0 0 0 0 0 0 1.6000 1.6000 0 0 0 0 0 1.6000 1.6000 0 0 0 0 1.6000 1.6000
Of course, both versions give exactly the same result.

更多回答(1 个)

Davide Masiello
Davide Masiello 2022-5-2
编辑:Davide Masiello 2022-5-2
%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
dgnl = 1×6
1.6000 1.6000 1.6000 1.6000 1.6000 1.6000
Better not use diag as variable name, since it's already a MatLab in-built function.

类别

Help CenterFile Exchange 中查找有关 Operating on Diagonal Matrices 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by