Jacobi迭代法求解方程组

JacobiFile.h

#include <iostream>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>

#include "Jacobi.h"

char matAb[20]; //存放矩阵mat_A和mat_b的文件
char matRes[20]; //存放每次迭代结果
///
JACOBI::JACOBI() {
	N=0;	eps=0.0;
	mat_A=NULL;	  
	mat_D=NULL;	mat_D_iv=NULL;	
	result=NULL;	
}

/
void JACOBI::red_matA(int n) { //读取矩阵mat_A和mat_b
	N = n;
	std::cout << "方阵的阶数为 " << N << '\n';
	std::cout << "read the mat_A" << '\n';
	mat_A = (double **)malloc(N*sizeof(double));
	for(int i=0; i<N; i++)
		*(mat_A+i) = (double *)malloc(N*sizeof(double));
	mat_b = (double *)malloc(N*sizeof(double));
	std::cout << "input filrname of matAb\n";
	std::cin >> matAb;
	FILE *fp;
	char ch;
	if((fp=fopen(matAb,"rt"))==NULL) { //covariance文件中每一行代表一个样本向量,列数为维数                            
		printf("Cannot open file strike any key exit!");
		exit(0);
	}

	ch=fgetc(fp);
	std::string str=""; //这里str是类string的一个对象
	while(ch!=EOF) {
		for(i=0; i<N; i++) { 
			while(ch==' ' || ch=='v' || ch=='\n')
				ch=fgetc(fp);
			//读取mat_A
			for(int j=0; j<N; j++) {
				while(ch==' ')
					ch=fgetc(fp);
				while(ch!=' ') {
					str+=ch;
					ch=fgetc(fp);
				}
				double aa=atof(str.c_str()); //将字符串转换成double型
				*(*(mat_A+i)+j) = aa; //读取*(*(mat_A+i)+j)
				str="";
			}
			//读取mat_A
			while(ch==' ')
				ch=fgetc(fp);
			while(ch!=' ' &&  ch!='\n') {
				str+=ch;
				ch=fgetc(fp);
			}
			double aa=atof(str.c_str()); //将字符串转换成double型
			*(mat_b+i) = aa; //读取mat_b+i
			str="";
			//ch=fgetc(fp);
		}
		ch=fgetc(fp);
	}
	std::cout << "read all the vectors" << '\n';
	fclose(fp);
}

/
void JACOBI::creatLUD() { //创建D和L+U
	mat_D = (double **)malloc(N*sizeof(double));
	for(int i=0; i<N; i++)
		*(mat_D+i) = (double *)malloc(N*sizeof(double));

	/*----创建D-----*/
	for(i=0; i<N; i++) {
		for(int j=0; j<N; j++)
			if(j==i)
				*(*(mat_D+i)+j) = *(*(mat_A+i)+j);
			else
				*(*(mat_D+i)+j) = 0;
	}
	/*----创建D-----*/

	/*----创建L+U-----*/
	for(i=0; i<N; i++)
		*(*(mat_A+i)+i) =0.0;
	/*----创建L+U-----*/

	//L U创建结束
	std::cout << "output mat_D \n";
	for(i=0; i<N; i++) {
		for(int j=0; j<N; j++)
			std::cout << *(*(mat_D+i)+j) << "  ";
		std::cout << '\n';
	}
	std::cout << "output L+U \n";
	for(i=0; i<N; i++) {
		for(int j=0; j<N; j++)
			std::cout << *(*(mat_A+i)+j) << "  ";
		std::cout << '\n';
	}
}

//
void JACOBI::creatD_iv() { //创建mat_D的逆矩阵
	/*-----初始化扩展矩阵mat_DI(mat_D和单位矩阵I组成)----*/
	double **mat_DI = (double **)malloc(N*sizeof(double));
	for(int i=0; i<N; i++)
		*(mat_DI+i) = (double *)malloc(N*sizeof(double));

	std::cout << "扩展矩阵为" << '\n';
	for(i=0; i<N; i++) {
		for(int j=0; j<N; j++) 
			*(*(mat_DI+i)+j) = *(*(mat_D+i)+j);
		for(j=N; j<2*N; j++) {
			if((j-N)==i)
				*(*(mat_DI+i)+j) = 1;
			else *(*(mat_DI+i)+j) = 0;
		}
	}
	for(i=0; i<N; i++) {
		for(int j=0; j<2*N; j++)
			std::cout << *(*(mat_DI+i)+j) << "  ";
		std::cout << '\n';
	}
	/*-----初始化扩展矩阵mat_DI(mat_D和单位矩阵I组成)----*/

	/*****************求逆模块***********************/
    for(i=0;i<N;i++)
    {
        if(*(*(mat_DI+i)+i)==0)
        {
            for(int k=i;k<N;k++)
            {
                if(*(*(mat_DI+k)+k)!=0)
                {
                    for(int j=0;j<2*N;j++)
                    {
                        double temp;
                        temp=*(*(mat_DI+i)+j);
                        *(*(mat_DI+i)+j)=*(*(mat_DI+k)+j);
                        *(*(mat_DI+k)+j)=temp;
                    }
                    break;
                }
            }
            if(k==N)
            {
                std::cout<<"该矩阵不可逆!"<< '\n';
            }
        }
        for(int j=2*N-1;j>=i;j--)
        {
            *(*(mat_DI+i)+j)/=*(*(mat_DI+i)+i);
        }
        for(int k=0;k<N;k++)
        {
            if(k!=i)
            {
                double temp=*(*(mat_DI+k)+i);
                for(int j=0;j<N;j++)
                {
                    *(*(mat_DI+k)+j)-=temp*(*(*(mat_DI+i)+j));
                }
            }
        }
    }
    /*****************求逆模块***********************/
	 //存储逆矩阵
	mat_D_iv = (double **)malloc(N*sizeof(double));
	for(i=0; i<N; i++)
		*(mat_D_iv+i) = (double *)malloc(N*sizeof(double)); 
	for(i=0;i<N;i++)
        for(int j=N;j<2*N;j++)
				*(*(mat_D_iv+i)+j-N) = *(*(mat_DI+i)+j);
	std::cout << "mat_D的逆矩阵为" << '\n';
	for(i=0; i<N; i++) {
		for(int j=0; j<N; j++)
			std::cout << *(*(mat_D_iv+i)+j) << "  ";
		std::cout << '\n';
	}
}


void JACOBI::cal(double _eps) { //求解方程组
	eps=_eps;
	double *temp = (double *)malloc(N*sizeof(double)); //迭代求解时用于存储临时值的数组
	for(int i=0; i<N; i++)
		*(temp+i) = 0; //初始化temp作为迭代起始值

	//迭代公式是x^(k+1)=(-mat_D_iv*(mat_L+mat_U))x^k+mat_D_iv*mat_b
	/*---求(-mat_D_iv*(mat_L+mat_U))---*/
	double **mat_LU = (double **)malloc(N*sizeof(double));
	for(i=0; i<N; i++)
		*(mat_LU+i) = (double *)malloc(N*sizeof(double));
	for(i=0; i<N; i++)
		for(int j=0; j<N; j++) {
			double sum=0.0;
			for(int k=0; k<N; k++)
				sum += *(*(mat_D_iv+i)+k) * (*(*(mat_A+k)+j));
			*(*(mat_LU+i)+j) = -1*sum;
		}
	std::cout << "\nthe matrix D^-1*(L+U)\n";
	for(i=0; i<N; i++) {
		for(int j=0; j<N; j++)
			std::cout << *(*(mat_LU+i)+j) << "  ";
		std::cout << '\n';
	} 
	/*---求(-mat_D_iv*(mat_L+mat_U))---*/

	/*---求mat_D_iv*mat_b---*/ 
	double *mat_Db = (double *)malloc(N*sizeof(double));
	for(i=0; i<N; i++) {
		double sum=0.0;
		for(int j=0; j<N; j++)
			sum += *(*(mat_D_iv+i)+j) * (*(mat_b+j));
		*(mat_Db+i) = sum;
	}
	std::cout << "\nthe matrix D^-1*b\n";
	for(i=0; i<N; i++) {
		std::cout << *(mat_Db+i) << '\n';
	std::cout << '\n';
	} 
	/*---求mat_D_iv*mat_b---*/ 
	
	/*---迭代开始---*/
	std::cout << "output the result\n";
	std::cout << "input the fileName to save the results\n";
	std::cin >> matRes;
	FILE *fp;
	if((fp=fopen(matRes,"w"))==NULL) {
		printf("Cannot build file strike any key exit!");
		exit(0);
	}
	result = (double *)malloc(N*sizeof(double));
	double sum_pre = 0.0; //计算x^k的和
	double sum_next = 0.0; //计算x^(k+1)的和
	double flag = 0;
	do {
		for(int i=0; i<N; i++) {
			double sum=0.0;
			for(int j=0; j<N; j++)
				sum += *(*(mat_LU+i)+j) * (*(temp+j));
			sum += *(mat_Db+i);
			*(result+i) = sum;
		}
		sum_pre = 0.0; //计算x^k的和
		sum_next = 0.0;
		for(i=0; i<N; i++) {
			sum_pre += *(temp+i);
			sum_next += *(result+i);
		}
		//将迭代结果输入文本文件
		fprintf(fp,"%s"," v  ");
		for(i=0; i<N; i++)
			fprintf(fp,"%.4f%s",*(temp+i),"  ");
		fprintf(fp,"%s","\n");
		fprintf(fp,"%s"," v  ");
		for(i=0; i<N; i++)
			fprintf(fp,"%.4f%s",*(result+i),"  ");
		fprintf(fp,"%s","\n");
		for(i=0; i<N; i++) {
			*(temp+i) = *(result+i);
			*(result+i) = 0;
		}
		flag=fabs(sum_pre-sum_next);
	}while(flag > eps); 
	/*---迭代结束---*/
	std::cout << "output the result \n";
	for(i=0; i<N; i++)
		std::cout << *(temp+i)<< '\n';
	fclose(fp);
	std::cout << "write all the vectors" << '\n';	                                                                                                                                                                                                                                                                                                                                                                    
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值