雅克比迭代法:
这个方法是用来解线性方程的,即给定系数矩阵和右边的列向量,求满足的列向量。此处不讲原理,只给出实现方法。
输入:系数矩阵(保证是严格对角占优的)和列向量。
输出:列向量。
环境:
虽然结果是正确的,但是感觉加速比特别低…有懂的大佬可以探讨一下。
#include<omp.h>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<ctime>
#include<cmath>
#include<algorithm>
#define NUM_THREADS 16 //线程个数
#define eps 1e-6 //精度
using namespace std;
const int n = 10000; //矩阵大小
double matrix[n][n]; //系数矩阵
double x[n]; //待求解
double y[n]; //临时存储结果
double b[n]; //matrix * x = b
void init() //注意 系数矩阵A要生成严格对角占优的 这样才能保证雅克比迭代法的收敛性
{
srand(time(0));
double sum = 0;
for (int i = 0; i < n; i++)
{
sum = 0;
for (int j = 0; j < n; j++)
{
if (j == i)
continue;
matrix[i][j] = rand() % 10 - 5;
sum += abs(matrix[i][j]);
}
if (rand() & 1) //严格对角占优
matrix[i][i] = sum + 1;
else
matrix[i][i] = -sum - 1;
}
for (int i = 0; i < n; i++)
{
b[i] = rand() % 10 - 5;
x[i] = 0;
}
}
int main()
{
omp_set_num_threads(NUM_THREADS);
clock_t start = clock();
init();
int rownum = n / NUM_THREADS; //每个线程处理的行数
rownum = max(rownum, 1);
int myid; //线程id
double Max = 0;
#pragma omp parallel
{
myid = omp_get_thread_num(); //线程id
int rowmin = myid * rownum; //该线程需要计算的行的起点
int rowmax = rowmin + rownum;
rowmax = min(rowmax, n);
if (myid == NUM_THREADS - 1)
rowmax = n;
double sum = 0;
for(;;)
{
Max = 0;
for (int i = rowmin; i < rowmax; i++)
{
sum = b[i];
for (int j = 0; j < n; j++)
{
if (j == i)
continue;
sum -= matrix[i][j] * x[j];
}
y[i] = sum / matrix[i][i];
Max = max(Max, abs(y[i] - x[i])); //记录最大差距值
}
#pragma omp single
{
memcpy(x, y, sizeof(x));
}
if (Max <= eps)
break;
#pragma omp barrier
{
}
/*cout << Max << endl;*/
}
}
clock_t end = clock();
//cout << "系数矩阵为:\n";
//for (int i = 0; i < n; i++)
//{
// for (int j = 0; j < n; j++)
// printf("%-5.0f", matrix[i][j]);
// printf("\n");
//}
//cout << "\n向量为:\n";
//for (int i = 0; i < n; i++)
// printf("%.0f\n", b[i]);
//cout << "\n结果为:\n";
//for (int i = 0; i < n; i++)
// printf("%.4f\n", x[i]);
//cout << "\n";
cout << NUM_THREADS << "个线程耗时: " << end - start << "\n";
return 0;
}