我正在尝试创建一个以正方形(n-by-n)矩阵作为输入的程序,如果它是可逆的,LU将使用高斯消除来分解矩阵。
这是我的问题:在课堂上我们了解到最好更改行,以便您的数据轴始终是其列中的最大数字(绝对值)。例如,如果矩阵为A = [1,2;3,4]
,则切换行为[3,4;1,2]
,然后我们可以继续进行高斯消除。
我的代码适用于不需要行更改的矩阵,但对于那些不需要行更改的矩阵,它可以正常工作。这是我的代码:
function newgauss(A)
[rows,columns]=size(A);
P=eye(rows,columns); %P is permutation matrix
if(det(A)==0) %% determinante is 0 means no single solution
disp('No solutions or infinite number of solutions')
return;
end
U=A;
L=eye(rows,columns);
pivot=1;
while(pivot<rows)
max=abs(U(pivot,pivot));
maxi=0;%%find maximum abs value in column pivot
for i=pivot+1:rows
if(abs(U(i,pivot))>max)
max=abs(U(i,pivot));
maxi=i;
end
end %%if needed then switch
if(maxi~=0)
temp=U(pivot,:);
U(pivot,:)=U(maxi,:);
U(maxi,:)=temp;
temp=P(pivot,:);
P(pivot,:)=P(maxi,:);
P(maxi,:)=temp;
end %%Grade the column pivot using gauss elimination
for i=pivot+1:rows
num=U(i,pivot)/U(pivot,pivot);
U(i,:)=U(i,:)-num*U(pivot,:);
L(i,pivot)=num;
end
pivot=pivot+1;
end
disp('PA is:');
disp(P*A);
disp('LU is:');
disp(L*U);
end
澄清:由于我们正在切换行,因此我们希望将P
(置换矩阵)时间A
分解,而不是我们输入的原始A
。
代码说明:
答案 0 :(得分:3)
您的代码似乎可以正常工作,至少对于基本示例A=[1,2;3,4]
或A=[3,4;1,2]
。将您的函数定义更改为:
function [L,U,P] = newgauss(A)
因此您可以输出您的计算值(比使用disp
好得多,但这也显示了正确的结果)。然后你会看到P*A = L*U
。也许你期望L*U
直接等于A
?您还可以通过Matlab的lu
函数确认您的信息是正确的:
[L,U,P] = lu(A);
L*U
P*A
Permutation matrices是正交矩阵,因此P -1 = P T 。如果您想在代码中找回A
,可以执行以下操作:
P'*L*U
同样,使用Matlab的lu
和置换矩阵输出,你可以这样做:
[L,U,P] = lu(A);
P'*L*U
答案 1 :(得分:1)
请注意det
函数是使用LU分解本身实现的,以计算行列式...递归任何人:)
除此之外,还会提醒页面末尾,建议使用cond
代替det
来测试矩阵奇点:
使用
abs(det(X)) <= tolerance
测试奇点不是 建议因为很难选择正确的公差。该 函数cond(X)
可以检查单数和近似单数 矩阵。
COND使用奇异值分解(参见其实现:edit cond.m
)
答案 2 :(得分:0)
对于将来发现这一点且需要有效解决方案的人:
OP的代码不包含在创建置换矩阵L
时在P
中切换元素的逻辑。与Matlab的lu(A)
函数提供相同输出的调整后代码为:
function [L,U,P] = newgauss(A)
[rows,columns]=size(A);
P=eye(rows,columns); %P is permutation matrix
tol = 1E-16; % I believe this is what matlab uses as a warning level
if( rcond(A) <= tol) %% bad condition number
error('Matrix is nearly singular')
end
U=A;
L=eye(rows,columns);
pivot=1;
while(pivot<rows)
max=abs(U(pivot,pivot));
maxi=0;%%find maximum abs value in column pivot
for i=pivot+1:rows
if(abs(U(i,pivot))>max)
max=abs(U(i,pivot));
maxi=i;
end
end %%if needed then switch
if(maxi~=0)
temp=U(pivot,:);
U(pivot,:)=U(maxi,:);
U(maxi,:)=temp;
temp=P(pivot,:);
P(pivot,:)=P(maxi,:);
P(maxi,:)=temp;
% change elements in L-----
if pivot >= 2
temp=L(pivot,1:pivot-1);
L(pivot,1:pivot-1)=L(maxi,1:pivot-1);
L(maxi,1:pivot-1)=temp;
end
end %%Grade the column pivot using gauss elimination
for i=pivot+1:rows
num=U(i,pivot)/U(pivot,pivot);
U(i,:)=U(i,:)-num*U(pivot,:);
L(i,pivot)=num;
end
pivot=pivot+1;
end
end
希望这有助于将来绊倒这个人。