线性方程组解的迭代改进算法实现

算法名称:
线性方程组解的迭代改进
 
算法描述:
       假定向量x是线性方程组
                                                                             1
的精确解,然而并不知道解x而仅仅知道一些略有误差的解x+δx,其中δx为未知的误差。当将其乘以矩阵A时,这个有误差的解使乘积与原来的右端项b也存在偏差,即
                                                                            (2
由(2)式减去(1)式得,
                                                                                          (3
但由(2)式也可求得δb,将其带入(3)式中得,
                               (4
该方程中整个右端项是已知量,因为x+δx是有待改进的有误差的解。然后,只需求解(4)式的偏差量δx,将其从有误差的解中减去便得到改进后的解。
       这种情况下,已经有了矩阵ALU分解形式,要求解(4)式,只需计算右端项再进行回代即可。
运行示例:
The origin matrix:
0.0 3.0 1.0 1.0
2.0 2.0 3.0 2.0
4.0 -3.0 0.0 1.0
6.0 1.0 -2.0 -5.0
--------------------------
The matrix (after LU decomposition):
6.0 1.0 -2.0 -5.0
0.0 3.0 1.0 1.0
0.3333333333333333 0.5555555555555556 3.1111111111111107 3.1111111111111107
0.6666666666666666 -1.222222222222222 0.8214285714285714 3.0000000000000004
--------------------------
The right vector:
0.0
-2.0
-5.0
6.0
--------------------------
The solution vector (before improvement):
-0.4523809523809522
0.42857142857142866
0.6190476190476184
-1.9047619047619044
--------------------------
The solution vector (after improvement):
-0.45238095238095233
0.4285714285714286
0.6190476190476188
-1.9047619047619049
--------------------------
 
代码示例:
package  com.nc4nr.chapter02.mprove;

public class Mprove 
{

    
//
 建议从构造函数看起,Mprove
    
    
// 4 * 4 coefficient matrix a

    double[][] a = {
            
{0.03.01.01.0}
,
            
{2.02.03.02.0}
,
            
{4.0-3.00.01.0}
,
            
{6.01.0-2.0-5.0}

    }
;
    
    
// 4 * 1 coefficient matrix b

    double[][] b = {
            
{0.0}
,
            
{-2.0}
,
            
{-5.0}
,
            
{6.0}

    }
;
    
    
int anrow = 4
;
    
int[] indx = new int
[anrow];
    
double[][] x = new double[anrow][1]; // 请留意后面的注释

    double[][] ora = new double[anrow][anrow];    // 拷贝分解前的系数矩阵a,因为a被分解后将被破坏
    
    
private void ludcmp() 
{
        
int n = anrow, imax = 0
;
        
double[] vv = new double
[anrow];
        
for (int i = 0; i < n; i++
{
            
double big = 0.0
;
            
for (int j = 0; j < n; j++
{
                
double temp =
 Math.abs(a[i][j]);
                
if (temp > big) big =
 temp;
            }

            
if (big == 0.0) System.out.println("lu: singular matrix");
            vv[i] 
= 1.0/
big;
        }

        
        
for (int j = 0; j < n; j++{
            
for (int i = 0; i < j; i++
{
                
double sum =
 a[i][j];
                
for (int k = 0; k < i; k++) sum -= a[i][k]*
a[k][j];
                a[i][j] 
=
 sum;
            }

            
double big = 0.0;
            
for (int i = j; i < n; i++
{
                
double sum =
 a[i][j];
                
for (int k = 0; k < j; k++) sum -= a[i][k]*
a[k][j];
                a[i][j] 
=
 sum;
                
double dum = Math.abs(vv[i]*
sum);
                
if (dum >= big) 
{
                    big 
=
 dum;
                    imax 
=
 i;
                }

            }

            
if (j != imax) {
                
for (int i = 0; i < n; i++
{
                    
double mid =
 a[imax][i];
                    a[imax][i] 
=
 a[j][i];
                    a[j][i] 
=
 mid;
                }

                vv[imax] 
= vv[j];
            }

            indx[j] 
= imax;
            
if (j != n-1
{
                
double dum = 1.0/
a[j][j];
                
for (int k = j+1; k < n; k++) a[k][j] *=
 dum;
            }

        }

    }

    
    
private void lubksb(double[][] alu, int[] idx, double[][] rb) {
        
int n = anrow, ii = 0
;
        
for (int i = 0; i < n; i++
{
            
int k =
 idx[i];
            
double sum = rb[k][0
];
            rb[k][
0= rb[i][0
];
            
if (ii != 0
)
                
for (int j = 0; j < i; j++) sum -= alu[i][j]*rb[j][0
];
            
else if (sum != 0
)
                ii 
= i+1
;
            rb[i][
0=
 sum;
        }

        
for (int i = n-1; i >= 0; i--{
            
double dum = 1.0/
alu[i][i];
            
double sum = rb[i][0
];
            
for (int k = i+1; k < n; k++) sum -= alu[i][k]*rb[k][0
];
            rb[i][
0= dum *
 sum;
        }

    }

    
    
private void mprove() {
        
int n =
 anrow;
        
double[][] r = new double[anrow][1
];
        
for (int i = 0; i < n; i++
{
            
double sdp = -b[i][0
];
            
for (int j = 0; j < n; j++
{
                sdp 
+= ora[i][j]*x[j][0
];
            }

            r[i][
0= sdp;
        }

        lubksb(a,indx,r);
        
for (int i = 0; i < n; i++) x[i][0-= r[i][0];
    }

    
    
private void output(double[][] m, int nrow, int ncol) {
        
for (int i = 0; i < nrow; i++
{
            String str 
= ""
;
            
for (int j = 0; j < ncol; j++) str += m[i][j] + " "
;
            System.out.println(str);
        }

        System.out.println(
"--------------------------");
    }

    
    
public Mprove() {
        
// 拷贝原始系数矩阵a到ora

        for (int i = 0; i < anrow; i++{
            
for (int j = 0; j < anrow; j++
{
                ora[i][j] 
=
 a[i][j];
            }

        }

        
// 拷贝原始右端项b
        for (int i = 0; i < anrow; i++{
            x[i][
0= b[i][0
];
        }

        System.out.println(
"The origin matrix:");
        output(ora,anrow,anrow);
        
// 这里将对a进行LU分解,并将分解结果存放到a

        ludcmp();
        System.out.println(
"The matrix (after LU decomposition):"
);
        output(a,anrow,anrow);
        System.out.println(
"The right vector:"
);
        output(b,anrow,
1
);
        
// 这里传入的是LU分解后的矩阵a,x将为带误差的解向量

        lubksb(a,indx,x);
        System.out.println(
"The solution vector (before improvement):"
);
        output(x,anrow,
1
);
        
// 这里将进行迭代改进x

        mprove();
        System.out.println(
"The solution vector (after improvement):"
);
        output(x,anrow,
1
);
        
// 本程序没有改变b和ora

    }

    
    
public static void main(String[] args) {
        
new
 Mprove();
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值