求解线性方程组: 高斯消元--LU分解--Jacobi迭代--高斯赛德尔--sor超松弛迭代
是一个最基本的计算模型,它在科学与工程计算中扮演着极其重要的角色。
求解线性方程组的直接法,就是通过有限步的运算手续,将所给方程组直接加工成某个三角方程组乃至对角方程组来求解。
求解线性方程组的直接法主要分为消去法与矩阵分解方法两大类。2.迭代法
for (int k = 0; k < 5; k++)
{
for (int i = k + 1; i < 6; i++)
{
temp = third.ele[i][k] / third.ele[k][k];
for (int j = k; j < 6; j++)
{
third.ele[i][j] -= temp*third.ele[k][j];
}
b3[i] -= temp*b3[k];
}
}
for (int i = 5; i >= 0; i--)
{
x[i] = b3[i];
for (int j = 5; j >= 0; j--)
{
if (i != j)
{
x[i] -= third.ele[i][j] * x[j];
}
}
x[i] /= third.ele[i][i];
}
2.LU分解(LU decomposition)
事实上,设将系数矩阵A分解成下三角矩阵L与上三角矩阵U的乘积
A=LU
则所给方程组Ax=b即
L(Ux)=b
可化为两个三角方程组
Ly=b,Ux=y
来求解,三角方程组有简单的回带公式,求解是方便的。
这里,下三角方程组Ly=b的回代过程是顺序计算y1→y2→…→yn的追的过程,而上三角方程组Ux=y的回代过程则是逆序求解xn→xn-1→…→x1的赶的过程,因此,上述矩阵分解方法可理解为广义的追赶法。
为了保证分解式A=LU的唯一性,实际的附加条件是,令其中一个分解阵L或U的对角线元素全为1.
令其左端保留对角成分,将其余成分挪到右端,而改写成如下“伪对角形式”:
相应的迭代公式为:
do
{
if ((++cnt) > cnt) break;
for (int i = 0; i < 6; i++) x1[i] = x[i];
for (int i = 0; i < 6; i++)
{
temp = 0;
for (int j = 0; j < 6; j++)
{
if (i != j)
{
temp += third.ele[i][j] * x1[j];
}
}
x[i] = (b3[i] - temp) / third.ele[i][i];
// cout << x[i] << endl;
}
// cout << endl;
ep = 0;
for (int i = 0; i < 6; i++)
{
if (ep < (abs(x[i] - x1[i])))
{
ep = abs(x[i] - x1[i]);
}
}
} while (ep > e);
do
{
if ((++cnt) > 100) break;
for (int i = 0; i < 6; i++) x1[i] = x[i];
for (int i = 0; i < 6; i++)
{
temp = 0;
for (int j = 0; j < 6; j++)
{
if (i != j)
{
if (j < i)
{
temp += third.ele[i][j] * x[j];
}
else temp += third.ele[i][j] * x1[j];
}
}
x[i] = (b3[i] - temp) / third.ele[i][i];
// cout << x[i] << endl;
}
// cout << endl;
ep = 0;
for (int i = 0; i < 6; i++)
{
if (ep < (abs(x[i] - x1[i])))
{
ep = abs(x[i] - x1[i]);
}
}
} while (ep > e);
要求取松弛因子 w>1 ,以尽量发挥新值的优势。
do
{
if ((++cnt) > 100) break;
for (int i = 0; i < 6; i++) x1[i] = x[i];
for (int i = 0; i < 6; i++)
{
temp = 0;
for (int j = 0; j < 6; j++)
{
if (i != j)
{
if (j < i)
{
temp += third.ele[i][j] * x[j];
}
else temp += third.ele[i][j] * x1[j];
}
}
x[i] = (1 - w)*x[i] + w*(b3[i] - temp) / third.ele[i][i];
// cout << x[i] << endl;
}
// cout << endl;
ep = 0;
for (int i = 0; i < 6; i++)
{
if (ep < (abs(x[i] - x1[i])))
{
ep = abs(x[i] - x1[i]);
}
}
} while (ep > e);