雅克比迭代法:
這個方法是用來解線性方程的,即給定係數矩陣和右邊的列向量,求滿足的列向量。此處不講原理,只給出實現方法。
輸入:係數矩陣(保證是嚴格對角佔優的)和列向量。
輸出:列向量。
環境:
雖然結果是正確的,但是感覺加速比特別低…有懂的大佬可以探討一下。
#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;
}