Question:
Design/implement a method to transform a matrix into strict diagonal dominance, if possible.
Solution:
First, we should clearly know what strictly diagonal dominant matrix is.
a matrix is said to be diagonally dominant if for every row of the matrix, the magnitude of the diagonal entry in a row is larger than or equal to the sum of the magnitudes of all the other (non-diagonal) entries in that row. More precisely, the matrix A is diagonally dominant if
where aij denotes the entry in the ith row and jth column.
Then, we come to the question. There is some questions we should answer:
(1) Whether the input matrix is an SDDM.
(2) If it’s not, whether we can transform it to one.
(3) And how?
First question first. We can judge the input matrix A easily by the definition. We just ensure every single row’s largest magnitude is in the position (i,i) in matrix A.
And then, if the matrix is not an SDDM. How can we ensure we can transform it? The answer is that we have to try. It means we have to row-interchange the matrix and make the rows in a way that fits the definition. Here I design an algorithm (pseudo code):
for i = 1:n
while(row(i) is not ok)
j = find_row_to_interchange(i)
if(i == j, which means no need to interchange)
row(i) is okay
else if(row(j) hasn’t been interchanged)
row_interchange(i,j);
else
the matrix can’t be transformed.
end if
end while
end for
So now, the whole process is just like the chart below:
Now we should consider the implement on MATLAB.
(1)Define two bool value to record status of row-interchange
The first one is about the whole process. The second one is just a n-size array to record the interchanging of every row.
(2)The implement of the
The whole matlab source code:
% Author: Jason Ye
% Time: 2015/04/29
% To judge a matrix whether a strictly diagonally dominant matrix(SDDM)
% If yes, print it. Else whether it can transform to one.
% input:
% a: a matrix
% output:
% A: return the SDDM A if okay.
function A = sddm(a)
len = length(a); % the size n of matrix a
sum_of_row = sum(abs(a')); % The sum of every entry's absolute value in a row.
row_interchange = false; % if there's row interchange in the process, it's true,
% else it's false;
row_status = zeros(1,len); % true for this row has been interchanged, false for not.
% To ensure each row is strictly diagnoally dominant.
for i = 1:len
row_ok = false;
% interchange the row until it's suitable for current row
while(1)
for j = 1:len
% find the entry that is biggest absolute value
% than the sum of the rest entry in absolute value.
if(2*abs(a(i,j)) > sum_of_row(i))
row_ok = true;
end
% break when we find
if(row_ok == true)
break;
end
end
% to judge the row whether it need row-interchanging
if(row_ok == true)
% no need
if(i == j)
break;
% need if the j row has not row-interchanged ever.
elseif(row_status(j) == 0)
row_status(j) = 1;
a([i,j],:) = a([j,i],:);
sum_of_row([i,j])=sum_of_row([j,i]);
row_ok = false;
row_interchange = true;
continue;
% j row has already been row-interchanged
else
row_ok=false;
break;
end
else
break;
end
end
if(~row_ok)
break;
end
end
if(~row_interchange)
fprintf('This is a SDDM!\n');
A = a;
else
fprintf('This origin matrix is not a SDDM!\n');
if(~row_ok)
error('And it can not transform into a SDDM.\n');
else
fprintf('But it can transform into a SDDM.\n');
A = a;
end
end