-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathConfirmedSparseMatrix.cuh
87 lines (78 loc) · 2.87 KB
/
ConfirmedSparseMatrix.cuh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//
// Created by davidxu on 22-8-3.
//
#ifndef GPU_POISSONRECON_CONFIRMEDSPARSEMATRIX_CUH
#define GPU_POISSONRECON_CONFIRMEDSPARSEMATRIX_CUH
#include "SparseMatrix.cuh"
#include "ConfirmedVector.cuh"
template<int Rows,int Rowsize,class T>
class ConfirmedSparseSymmetricMatrix{
public:
MatrixEntry<T> m_ppElements[Rows][Rowsize];
template<int bSize,class T2>
__host__ __device__ ConfirmedVector<bSize,T2> Multiply( const ConfirmedVector<bSize,T2>& V ) const{
ConfirmedVector<Rows,T2> R;
for (int i=0; i<Rows; i++){
for(int ii=0;ii<Rowsize;ii++){
int j=this->m_ppElements[i][ii].N;
R(i)+=this->m_ppElements[i][ii].Value * V.m_pV[j];
R(j)+=this->m_ppElements[i][ii].Value * V.m_pV[i];
}
}
return R;
}
template<int bSize,class T2>
__host__ __device__ void Multiply( const ConfirmedVector<bSize,T2>& In, ConfirmedVector<bSize,T2>& Out ) const{
Out.SetZero();
for (int i=0; i<Rows; i++){
const MatrixEntry<T> *temp=this->m_ppElements[i];
const T2& in1=In.m_pV[i];
T2& out1=Out.m_pV[i];
for(int ii=0;ii<Rowsize;ii++){
const MatrixEntry<T>& temp2=temp[ii];
int j=temp2.N;
T2 v=temp2.Value;
out1+=v * In.m_pV[j];
Out.m_pV[j]+=v * in1;
}
}
}
template<int bSize,class T2>
__host__ __device__ static int Solve(const ConfirmedSparseSymmetricMatrix<Rows,Rowsize,T>& M,const ConfirmedVector<bSize,T2> &b,
const int& iters,
ConfirmedVector<bSize,T2> &solution,
const float eps=1e-8,const int& reset=1)
{
ConfirmedVector<bSize,T2> Md;
T2 alpha,beta,rDotR,bDotB;
if(reset){
solution.SetZero();
}
ConfirmedVector<bSize,T2> d=b-M.Multiply(solution); // error vector
ConfirmedVector<bSize,T2> r=d; // error vector
rDotR=r.Dot(r); // L2 distance of error vector
bDotB=b.Dot(b); // L2 distance of b
if(b.Dot(b)<=eps){
solution.SetZero();
return 0;
}
int i;
for(i=0;i<iters;i++){
T2 temp;
M.Multiply(d,Md); // vec Md = matrix M * vec d
temp=d.Dot(Md);
if(fabs(temp)<=eps){break;}
alpha=rDotR/temp;
r.SubtractScaled(Md,alpha);
temp=r.Dot(r);
if(temp/bDotB<=eps){break;}
beta=temp/rDotR;
solution.AddScaled(d,alpha);
if(beta<=eps){break;}
rDotR=temp;
ConfirmedVector<bSize,T2>::Add(d,beta,r,d);
}
return i;
}
};
#endif //GPU_POISSONRECON_CONFIRMEDSPARSEMATRIX_CUH