#include "stdafx.h"
#include
// 解线性方程组的直接法
void
PS(
double
A[],
int
n,
char
*name);
void
GaussXiaoQu()
{
printf
(
"高斯直接消元法:\n"
);
double
a[3][3] = {{2,4,-2},{1,-1,5},{4,1,-2}};
double
b[3] = {6,0,2};
double
x[3];
int
n = 3;
int
k,i,j;
double
l;
// 消元
for
(k = 0; k < n-1; k++)
{
for
(i = k+1; i < n; i++)
{
l = a[i][k]/a[k][k];
b[i] = b[i] - l*b[k];
for
(j = k; j < n; j++)
{
a[i][j] = a[i][j] - l*a[k][j];
}
}
}
// 消元结果
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,a[i][j]);
printf
(
"%f"
,b[i]);
printf
(
"\n"
);
}
// 回代
for
(i = n-1; i >= 0; i--)
{
x[i] = b[i];
for
(j = n-1; j > i; j--)
x[i] = x[i] - a[i][j]*x[j];
x[i] = x[i] / a[i][i];
}
printf
(
"x= "
);
for
(i = 0; i < n; i++)
printf
(
"%f\t"
,x[i]);
printf
(
"\n"
);
}
void
GaussLieZhuYuan()
{
printf
(
"高斯列主元法:\n"
);
double
a[3][3] = {{1,2,3},{5,4,10},{3,-0.1,1}};
double
b[3] = {1,0,2};
double
x[3];
int
n = 3;
// 系数矩阵维数
int
k,i,j;
double
l;
double
tmp;
int
r;
// 消元
for
(k = 0; k < n-1; k++)
{
// 找到该列最大元
for
(r=k,j=k+1; j < n; j++) {
if
(
abs
(a[j][k]) >
abs
(a[r][k]))
{
r = j;
}
}
// 行交换
if
(r != k)
{
for
(j = k; j < n; j++) {
tmp = a[k][j];
a[k][j] = a[r][j];
a[r][j] = tmp;
}
tmp = b[k];
b[k] = b[r];
b[r] = tmp;
}
// 消元
for
(i = k+1; i < n; i++)
{
l = a[i][k]/a[k][k];
b[i] = b[i] - l*b[k];
for
(j = k; j < n; j++)
{
a[i][j] = a[i][j] - l*a[k][j];
}
}
}
// 消元结果
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,a[i][j]);
printf
(
"%f"
,b[i]);
printf
(
"\n"
);
}
// 回代
for
(i = n-1; i >= 0; i--)
{
x[i] = b[i];
for
(j = n-1; j > i; j--)
x[i] = x[i] - a[i][j]*x[j];
x[i] = x[i] / a[i][i];
}
printf
(
"x= "
);
for
(i = 0; i < n; i++) {
printf
(
"%f\t"
,x[i]);
}
printf
(
"\n"
);
}
void
GaussQuanZhuYuan()
{
printf
(
"高斯全主元法:\n"
);
double
a[3][3] = {{1,2,3},{5,4,10},{3,-0.1,1}};
double
b[3] = {1,0,2};
double
x[3];
double
y[3];
int
n = 3;
// 系数矩阵维数
int
k,i,j;
double
l;
double
tmp;
int
r,c;
int
p[3] = {0,1,2},q;
// 消元
for
(k = 0; k < n-1; k++)
{
// 找到子矩阵内最大元
r = c = k;
for
(i = k; i < n; i++) {
for
(j = k; j < n; j++) {
if
(
abs
(a[i][j]) >
abs
(a[r][c]))
{
r = i;
c = j;
}
}
}
// 行交换 k~r
if
(r != k)
{
for
(j = k; j < n; j++) {
tmp = a[k][j];
a[k][j] = a[r][j];
a[r][j] = tmp;
}
tmp = b[k];
b[k] = b[r];
b[r] = tmp;
}
// 交换列 k~c
if
(c != k)
{
for
(i = 0; i < n; i++) {
tmp = a[i][k];
a[i][k] = a[i][c];
a[i][c] = tmp;
}
q = p[k];
p[k] = p[c];
p[c] = q;
}
// 消元
for
(i = k+1; i < n; i++)
{
l = a[i][k]/a[k][k];
b[i] = b[i] - l*b[k];
for
(j = k; j < n; j++)
{
a[i][j] = a[i][j] - l*a[k][j];
}
}
}
// 消元结果
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,a[i][j]);
printf
(
"%f"
,b[i]);
printf
(
"\n"
);
}
// 回代
for
(i = n-1; i >= 0; i--)
{
x[i] = b[i];
for
(j = n-1; j > i; j--)
x[i] = x[i] - a[i][j]*x[j];
x[i] = x[i] / a[i][i];
}
printf
(
"x= "
);
for
(i = 0; i < n; i++) {
for
(j = 0; j < n; j++)
{
if
(i == p[j])
{
y[i] = x[j];
}
}
printf
(
"%f\t"
,y[i]);
}
printf
(
"\n"
);
}
void
GaussYueDangMethod()
{
printf
(
"高斯约当消去法(列主元):\n"
);
double
a[3][3] = {{1,-1,0},{2,2,3},{-1,2,1}};
double
b[3] = {1,0,0};
double
x[3];
int
n = 3;
// 系数矩阵维数
int
k,i,j;
double
l;
double
tmp;
int
r;
// 消元
for
(k = 0; k < n; k++)
{
// 找到该列最大元
for
(r=k,j=k+1; j < n; j++) {
if
(
abs
(a[j][k]) >
abs
(a[r][k]))
{
r = j;
}
}
// 行交换
if
(r != k)
{
for
(j = k; j < n; j++) {
tmp = a[k][j];
a[k][j] = a[r][j];
a[r][j] = tmp;
}
tmp = b[k];
b[k] = b[r];
b[r] = tmp;
}
// 消元
for
(i = 0; i < n; i++) {
if
(i == k)
continue
;
else
{
l = a[i][k]/a[k][k];
b[i] = b[i] - l*b[k];
for
(j = k; j < n; j++)
{
a[i][j] = a[i][j] - l*a[k][j];
}
}
}
// 消去本行
l = a[k][k];
for
(j = k; j < n; j++)
a[k][j] = a[k][j] / l;
b[k] = b[k] / l;
// 消元结果
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,a[i][j]);
printf
(
"%f"
,b[i]);
printf
(
"\n"
);
}
printf
(
"\n"
);
}
/* // 消元结果
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%f\t",a[i][j]);
printf("%f",b[i]);
printf("\n");
}
*/
// 回代
for
(i = n-1; i >= 0; i--)
{
x[i] = b[i];
}
printf
(
"x= "
);
for
(i = 0; i < n; i++) {
printf
(
"%f\t"
,x[i]);
}
printf
(
"\n"
);
}
void
ZhuiGanMethod_I()
{
printf
(
"三对角方程追赶法I:\n"
);
double
p[3];
double
q[2];
double
a[3][3] = {{6,1,0},{1,4,1},{6,1,14}};
double
d[3] = {6,24,322};
double
x[3];
int
k;
int
n = 3;
double
l;
p[0] = d[0]/a[0][0];
q[0] = a[0][1]/a[0][0];
for
(k = 1; k < n; k++) {
l = a[k][k] - a[k][k-1]*q[k-1];
p[k] = (d[k]-a[k][k-1]*p[k-1])/l;
if
(k
}
// p,q结果
for
(k = 0; k < n; k++)
printf
(
"p[%d]=%f\t"
,k,p[k]);
printf
(
"\n"
);
for
(k = 0; k < n-1; k++)
printf
(
"q[%d]=%f\t"
,k,q[k]);
printf
(
"\n"
);
// 回代
x[n-1] = p[n-1];
for
(k = n-2; k >= 0; k--) {
x[k] = p[k]-q[k]*x[k+1];
}
for
(k = 0; k < n; k++) {
printf
(
"%f\t"
,x[k]);
}
printf
(
"\n"
);
}
void
ZhiJieSanJiaoXing()
{
printf
(
"直接三角形分解法:\n"
);
double
a[3][3] = {{2,2,3},{4,7,7},{-2,4,5}};
double
b[3] = {3,1,-7};
double
l[3][3],u[3][3];
int
n = 3;
int
i,j;
// LU分解
int
k = 0;;
int
r;
for
(k = 0; k < n; k++) {
// 先计算u
for
(j = 0; j < n; j++) {
if
(j
else
{
u[k][j] = a[k][j];
for
(r = 0; r < k && k > 0; r++) {
u[k][j] -= l[k][r]*u[r][j];
}
}
}
// 后计算l
for
(i = 0; i < n; i++) {
if
(i
else
if
(i==k) l[i][k]=1.;
else
{
l[i][k] = a[i][k];
for
(r = 0; r < k && k > 0; r++) {
l[i][k] -= l[i][r]*u[r][k];
}
l[i][k] /= u[k][k];
}
}
}
printf
(
"l=\n"
);
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,l[i][j]);
printf
(
"\n"
);
}
printf
(
"u=\n"
);
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,u[i][j]);
printf
(
"\n"
);
}
// 回代 求y
// Ly = b
double
y[3];
y[0] = b[0];
for
(i = 1; i < n; i++) {
y[i] = b[i];
for
(j = 0; j < i; j++) {
y[i] = y[i] - l[i][j]*y[j];
}
}
// 求x
//Ux=y
double
x[3];
x[n-1] = y[n-1]/u[n-1][n-1];
for
(i = n-2; i >=0; i--) {
x[i] = y[i];
for
(j = i+1; j < n; j++) {
x[i] = x[i] - u[i][j]*x[j];
}
x[i] /= u[i][i];
}
printf
(
"x= "
);
for
(i = 0; i < n; i++) {
printf
(
"%f\t"
,x[i]);
}
printf
(
"\n"
);
}
void
ZhuiGanMethod_II()
{
printf
(
"三对角方程追赶法II:\n"
);
double
p[3];
double
q[2];
double
a[3][3] = {{6,1,0},{1,4,1},{0,1,14}};
double
d[3] = {6,24,322};
double
x[3],y[3];
int
i;
int
n = 3;
// 追
p[0] = a[0][0];
q[0] = a[0][1]/p[0];
for
(i = 1; i < n; i++)
{
p[i] = a[i][i] - a[i][i-1]*q[i-1];
if
(i
}
PS(p,n,
"p"
);PS(q,n-1,
"q"
);
// 赶
for
(i=0;i
{
y[i] = d[i];
if
(i>0) y[i] -= a[i][i-1]*y[i-1];
y[i] /= p[i];
}
for
(i=n-1;i>=0;i--) {
x[i] = y[i];
if
(i
}
PS(y,n,
"y"
);PS(x,n,
"x"
);
}
void
PingFangGenMethod()
{
printf
(
"平方根法: A=LL'\n"
);
double
a[3][3] = {{6,1,0},{1,4,1},{0,1,14}};
double
b[3] = {6,24,322};
int
n = 3;
int
i,j,k;
double
l[3][3];
double
x[3],y[3];
for
(i=0;i
for
(j=0;j
l[i][j] = 0.;
}
}
// 分解
for
(i=0;i
// 对角元
l[i][i] = a[i][i];
for
(k=0;k
l[i][i] -= l[i][k]*l[i][k];
}
l[i][i] =
sqrt
(l[i][i]);
// 列元
for
(j=i+1;j
l[j][i] = a[j][i];
for
(k=0;k
l[j][i] -= l[j][k]*l[i][k];
// 转置!
}
l[j][i] /= l[i][i];
}
}
printf
(
"l=\n"
);
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,l[i][j]);
printf
(
"\n"
);
}
// 回代 ,L'y = b
for
(i=0;i
{
y[i] = b[i];
for
(j=0;j
y[i] -= l[i][j]*y[j];
}
y[i] /= l[i][i];
}
for
(i=n-1;i>=0;i--) {
x[i] = y[i];
for
(j=n-1;j>i;j--)
x[i]-=l[j][i]*x[j];
// 主意L 转置, L' x = y
x[i] /= l[i][i];
}
PS(y,n,
"y"
);PS(x,n,
"x"
);
}
void
GaiJinPingFangMethod()
//
{
printf
(
"改进的平方根法: A=LDL'\n"
);
double
a[3][3] = {{6,1,0},{1,4,1},{0,1,14}};
double
b[3] = {6,24,322};
int
n = 3;
int
i,j,k;
double
l[3][3],u[3][3];
for
(i=0;i
for
(j=0;j
u[i][j] = l[i][j] = 0.;
}
}
// LU分解
int
r;
for
(k = 0; k < n; k++) {
// 先计算u
for
(j = k; j < n; j++) {
u[k][j] = a[k][j];
for
(r = 0; r < k && k > 0; r++) {
u[k][j] -= l[k][r]*u[r][j];
}
}
// 后计算l, 主意与紧凑格式法差异,运算量减少
l[k][k] = 1.;
for
(i = k+1; i < n; i++) {
l[i][k] = u[k][i]/u[k][k];
}
}
printf
(
"l=\n"
);
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,l[i][j]);
printf
(
"\n"
);
}
printf
(
"u=\n"
);
for
(i = 0; i < n; i++)
{
for
(j = 0; j < n; j++)
printf
(
"%f\t"
,u[i][j]);
printf
(
"\n"
);
}
// 回代 求y
// Ly = b
double
y[3];
y[0] = b[0];
for
(i = 1; i < n; i++) {
y[i] = b[i];
for
(j = 0; j < i; j++) {
y[i] = y[i] - l[i][j]*y[j];
}
}
// 求x
//Ux=y
double
x[3];
x[n-1] = y[n-1]/u[n-1][n-1];
for
(i = n-2; i >=0; i--) {
x[i] = y[i];
for
(j = i+1; j < n; j++) {
x[i] = x[i] - u[i][j]*x[j];
}
x[i] /= u[i][i];
}
PS(x,n,
"x"
);
}