フィルターのクリア

Diagonal sums with non-zero elements

2 ビュー (過去 30 日間)
Ingrid Wilson
Ingrid Wilson 2022 年 5 月 2 日
編集済み: Riccardo Scorretti 2022 年 5 月 2 日
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 日
編集済み: 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 Center および File ExchangeOperating on Diagonal Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by