【无标题】

这段代码实现了一个使用OpenMP进行并行化的Gauss-Seidel迭代法,用于求解稀疏矩阵的线性方程组。程序首先检查B矩阵是否有全零列,然后进行迭代计算,每一步都考虑了矩阵元素的稀疏性以优化性能。在每次迭代中,它会计算误差范数并检查是否满足预设的精度要求。如果解超出指定范围或超过最大迭代次数,函数将返回相应错误码。
摘要由CSDN通过智能技术生成
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <fstream>
#include <sstream>
#include <time.h>
#include "omp.h"
using namespace std;
#define MAX_SIZE 2500 // 矩阵最大维数
#define bound pow(2,127) // 判断迭代发散边界
#define ZERO 0.000001 //当一个数字小于0.000001时认为其为0

// solve the problem with OpenMP
int Gauss_Seidel ( int n, float a[][MAX_SIZE], float b[], float x[], float TOL, int MAXN )
{
    //Turning "ax=b" into "x=Bx+f"
    float B[n][n]; //B矩阵为迭代矩阵
    int i,j;
    // 减少稀疏矩阵的计算开销
    int count[n]; //计算B矩阵的某一指定列中元素为0的个数
    for(i=0;i<n;i++)
    {
        B[i][i] = 0;
        for(j=0;j<n;j++)
        {
            if(j!=i)
                B[i][j] = -a[i][j]/a[i][i];
        }
    }
    //若B矩阵中有一列的元素值全为0,则Gauss_Seidel函数返回-1
    for(i=0;i<n;i++)
    {
        count[i] = 0;
        for(j=0;j<n;j++)
        {
            if(B[i][j] == 0)
                count[i]++;
        }
    }
    if(count[i]==n)
        return -1;
    //Iteration
    int k = 0; //定义并初始化迭代次数k=0
    float x_kp1[n]; //创建新的数组用于存储第k+1次后x的迭代值
    float sum;
    float max = 0; //用于存储最大范数
#pragma omp parallel for num_threads(thread_count)
    for(int k = 0; k < MAXN; ++k)
    {
        for(i=0;i<n;i++)
        {
            sum = 0;
            for(j=0;j<n;j++)
            {
                if(j<i)
                    sum += a[i][j]*x_kp1[j];
                if(j>i)
                    sum += a[i][j]*x[j];
            }
            x_kp1[i] = (b[i]-sum)/a[i][i];
        }
        //求第k+1次迭代所得的x与第k次迭代所得的x之间差的无穷范数
        max = fabs(x_kp1[0]-x[0]);
        for(i=1;i<n;i++)
        {
            if(max<fabs(x_kp1[i]-x[i]))
                max = fabs(x_kp1[i]-x[i]);
        }
        //若第k次迭代中x的任意某个分量值超出了最大区间[-bound,bound]限制
        //则Gauss_Seidel函数返回-2
        for(i=0;i<n;i++)
        {
            if(fabs(x_kp1[i])>bound)
               return -2;
            x[i] = x_kp1[i]; //重复利用x向量,用于存储第k次迭代的x值
        }

        for(i=0;i<n;i++)
            x[i] = x_kp1[i]; //重复利用x向量,用于存储第k次迭代的x值
        //若经过k次叠代达到了精度TOL的要求
        //则Gauss_Seidel函数返回k值(求得的解存储在x中)
        if(max<TOL)
            return k;
    }
    //若算法经过MAXN次叠代后还没有达到精度TOL要求
    //则Gauss_Seidel函数返回0
    return 0;
}

// the size of the matrix?
// 读入稀疏矩阵
int main(int argc, char ** argv){ // row_size = 2500, col_size = 2500
    int thread_count = strtol(argv[1],NULL,10);
    int i, j, k, MAXN,n;// MAXN 最大迭代次数,n 计算稀疏矩阵特性的参数
    double TOL = ZERO; // TOL 精度要求
    float A[MAX_SIZE][MAX_SIZE], b[MAX_SIZE],x[MAX_SIZE];
    ifstream inFileA("./A5.txt");
    ifstream inFileb("./b.txt");
    float temp1;
    for(i = 0;i < MAX_SIZE;i++){
        for(j = 0;j < MAX_SIZE;j++){
            inFileA >> temp1;
            A[i][j] = temp1;
        }
    }
    int temp2;
    for(j = 0;j < MAX_SIZE;j++){
        inFileb >> temp2;
        b[j] = temp2;
        x[j] = 1;
    }
    n = MAX_SIZE;
    MAXN = 10; //最多迭代MAXN次,如果达到精度要求,则返回x,如果没有达到精度要求,则返回0
    Gauss_Seidel(n,A,b,x,TOL,MAXN);
}
/*
    vector<float> A;
    vector<int> b;
    // int row_size = 2500;
    // int col_size = 2500;
    ifstream inFile_A("./A5.txt");
    ifstream inFile_b("./b.txt");
    // 默认为char类型
    float temp1;
    while(!inFile_A.eof()){
        inFile_A >> temp1;
        A.push_back(temp1);
    }
    int temp2;
    while(!inFile_b.eof()){
        inFile_b >> temp2;
        b.push_back(temp2);
    }
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <fstream>
#include <sstream>
#include <time.h>
#include "omp.h"
using namespace std;
#define MAX_SIZE 2500 // 矩阵最大维数
#define bound 1024 // 判断迭代发散边界
#define ZERO 0.000001 //当一个数字小于0.000001时认为其为0

// solve the problem with OpenMP
int Gauss_Seidel ( int n, float a[][MAX_SIZE], float b[], float x[], float TOL, int MAXN,int thread_count)
{
    //Turning "ax=b" into "x=Bx+f"
    float B[n][n]; //B矩阵为迭代矩阵
    int i,j;
    // 减少稀疏矩阵的计算开销
    int count[n]; //计算B矩阵的某一指定列中元素为0的个数
    for(i=0;i<n;i++)
    {
        B[i][i] = 0;
        for(j=0;j<n;j++)
        {
            if(j!=i)
                B[i][j] = -a[i][j]/a[i][i];
        }
    }
    //若B矩阵中有一列的元素值全为0,则Gauss_Seidel函数返回-1
    for(i=0;i<n;i++)
    {
        count[i] = 0;
        for(j=0;j<n;j++)
        {
            if(B[i][j] == 0)
                count[i]++;
        }
    }
    if(count[i]==n)
        return -1;
    //Iteration
    int k = 0; //定义并初始化迭代次数k=0
    float x_kp1[n]; //创建新的数组用于存储第k+1次后x的迭代值
    float sum;
    float max = 0; //用于存储最大范数

    for(int k = 0; k < MAXN; ++k)
    {
        #pragma omp parallel for num_threads(thread_count)
        for(i=0;i<n;i++)
        {
            sum = 0;
            for(j=0;j<n;j++)
            {
                if(j<i)
                    sum += a[i][j]*x_kp1[j];
                if(j>i)
                    sum += a[i][j]*x[j];
            }
            x_kp1[i] = (b[i]-sum)/a[i][i];
        }
        //求第k+1次迭代所得的x与第k次迭代所得的x之间差的无穷范数
        max = fabs(x_kp1[0]-x[0]);
        for(i=1;i<n;i++)
        {
            if(max<fabs(x_kp1[i]-x[i]))
                max = fabs(x_kp1[i]-x[i]);
        }
        //若第k次迭代中x的任意某个分量值超出了最大区间[-bound,bound]限制
        //则Gauss_Seidel函数返回-2
        for(i=0;i<n;i++)
        {
            if(fabs(x_kp1[i])>bound)
               return -2;
            x[i] = x_kp1[i]; //重复利用x向量,用于存储第k次迭代的x值
        }

        for(i=0;i<n;i++)
            x[i] = x_kp1[i]; //重复利用x向量,用于存储第k次迭代的x值
        //若经过k次叠代达到了精度TOL的要求
        //则Gauss_Seidel函数返回k值(求得的解存储在x中)
        if(max<TOL)
            return k;
    }
    //若算法经过MAXN次叠代后还没有达到精度TOL要求
    //则Gauss_Seidel函数返回0
    return 0;
}

// the size of the matrix?
// 读入稀疏矩阵
int main(int argc, char ** argv){ // row_size = 2500, col_size = 2500
    int thread_count = strtol(argv[1],NULL,10);
    int i, j, k, MAXN,n;// MAXN 最大迭代次数,n 计算稀疏矩阵特性的参数
    double TOL = ZERO; // TOL 精度要求
    float A[MAX_SIZE][MAX_SIZE], b[MAX_SIZE],x[MAX_SIZE];
    ifstream inFileA("./A5.txt");
    ifstream inFileb("./b.txt");
    float temp1;
    for(i = 0;i < MAX_SIZE;i++){
        for(j = 0;j < MAX_SIZE;j++){
            inFileA >> temp1;
            A[i][j] = temp1;
        }
    }
    float temp2;
    for(j = 0;j < MAX_SIZE;j++){
        inFileb >> temp2;
        b[j] = temp2;
        x[j] = 1;
    }
    n = MAX_SIZE;
    MAXN = 10; //最多迭代MAXN次,如果达到精度要求,则返回x,如果没有达到精度要求,则返回0
    Gauss_Seidel(n,A,b,x,TOL,MAXN,thread_count);
}
/*
    vector<float> A;
    vector<int> b;
    // int row_size = 2500;
    // int col_size = 2500;
    ifstream inFile_A("./A5.txt");
    ifstream inFile_b("./b.txt");
    // 默认为char类型
    float temp1;
    while(!inFile_A.eof()){
        inFile_A >> temp1;
        A.push_back(temp1);
    }
    int temp2;
    while(!inFile_b.eof()){
        inFile_b >> temp2;
        b.push_back(temp2);
    }
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值