方程组的系数矩阵里的数都很小,为了避免累计误差我在matlab里用高斯消元法,但仍然有不准确的数

在matlab里用高斯消元法解方程组(23*23),但只解出来一部分准确值,其他的值就不准确了,请问若想把剩余的值解出用什么办法?
matlab 高斯消元法程序:
function [ x ] = gauss(A,b)
n=length(A);

a=[A,b];

for k=1:n-1

maxa=max(abs(a(k:n,k)));

if maxa==0

return;

end

for i=k:n

if abs(a(i,k))==maxa

y=a(i,k:n+1);a(i,k:n+1)=a(k,k:n+1);a(k,k:n+1)=y;

break;

end

end

for i=k+1:n

l(i,k)=a(i,k)/a(k,k);

a(i,k+1:n+1)=a(i,k+1:n+1)-l(i,k).*a(k,k+1:n+1);

end

end

%回代

if a(n,n)==0

return

end

x(n)=a(n,n+1)/a(n,n);

for i=n-1:-1:1

x(i)=(a(i,n+1)-sum(a(i,i+1:n).*x(i+1:n)))/a(i,i);

end

end

A系数都是类似这样的数1.233249766723970E-04、3.420321248530940E-03
B值都是9588.42、2310.5这样的正常一些的数
请各位高手帮帮忙!!!
我用cond(a)看了一下20*20的条件数大约是220.281324231037e+015,它的解有9个可以用,要怎样才能做平衡化弥补呢?

我看了一下,这段代码虽然写得不怎么好但也没什么问题,没有特殊情况的话不至于引起数值上的不稳定,不过你的代码不会优于MATLAB本身的x=A\b。
我估计问题主要出在矩阵A本身。你可以先用cond(A)看一下条件数大约有多大,如果大到一定程度了就很难求得比较精确的解,这个是问题本身的扰动性态比较坏,而不是选的方法不好。

如果条件数太大,但没有更多的信息,那么可以考虑用SVD来解,
[U,S,V]=svd(A);
x=V*(S\(U'*b));
精度上会略好一点,但不要指望太多。

从你的叙述来看,仅仅是A的系数太小,b比较大,这些都不是问题。如果A的系数有大有小,或者b有同样的问题(这比较符合你所说的x有一些分量比较精确),这样才容易出现不稳定,此时可以先通过平衡化来做一些弥补。当然,不论何种情况都一定要根据原来的问题去寻找合适的算法,而不要认定某些成熟算法是稳定的,因为你自己掌握了更多的信息。追问

我用cond(a)看了一下20*20的条件数大约是220.281324231037e+015,它的解有9个可以用,要怎样才能做平衡化弥补呢?

追答

平衡化的原理就是找两个对角阵D1,D2使得D1AD2的元素大小“比较接近”,代码可以参考
http://www.netlib.org/lapack/double/dgeequ.f
除非平衡化产生的D1和D2很对角元差距很大,否则不会有太本质的改进,你的问题太病态,不提供多余的信息也就无法得到有用的建议。

温馨提示:答案为网友推荐,仅供参考
相似回答