7 #ifndef __solve_ConjugateGradient2_h__ 8 #define __solve_ConjugateGradient2_h__ 10 #define CG_NORMALIZE TRUE 14 #define CG_CHECK_SYMMETRY (FE_CODEGEN<=FE_DEBUG) 15 #define CG_CHECK_POSITIVE (FE_CODEGEN<=FE_DEBUG) 16 #define CG_CHECK_PEAK (FE_CODEGEN<=FE_DEBUG) 17 #define CG_VERIFY (FE_CODEGEN<=FE_DEBUG) 37 template <
typename MATRIX,
typename VECTOR>
50 m_preconditioning(e_none) {}
52 void solve(VECTOR& x,
const MATRIX& A,
const VECTOR& b);
54 void setThreshold(F64 threshold) { m_threshold=threshold; }
57 { m_preconditioning=preconditioning; }
66 VECTOR m_preconditionedVector;
70 MATRIX m_preconditionedMatrix;
75 template <
typename MATRIX,
typename VECTOR>
77 const MATRIX& A,
const VECTOR& b)
93 for(U32 iy=0;iy<N;iy++)
95 for(U32 ix=iy;ix<N;ix++)
97 if(fabs(A(ix,iy)-A(iy,ix))>1e-9f)
99 feLog(
"ConjugateGradient2 symmetry error %d,%d %.6G %.6G\n",
100 ix,iy,A(ix,iy),A(iy,ix));
107 feLog(
"\nA\n%s\nb=<%s>\n",print(A).c_str(),print(b).c_str());
110 if(magnitudeSquared(b)<m_threshold)
113 feLog(
"ConjugateGradient2::solve has trivial solution\n");
123 m_AT.setTranspose(A);
124 m_AT_A.setProduct(m_AT,A);
131 feLog(
"AT\n%s\n",print(m_AT).c_str());
132 feLog(
"AT*A\n%s\n",print(m_AT_A).c_str());
133 feLog(
"AT*b=<%s>\n",print(m_AT_b).c_str());
136 if(m_preconditioning==e_diagonal_A)
138 premultiplyInverseDiagonal(m_tempMatrix,m_AT_A,m_AT_A);
139 postmultiplyInverseDiagonal(m_preconditionedMatrix,
140 m_tempMatrix,m_AT_A);
141 pA=&m_preconditionedMatrix;
143 premultiplyInverseDiagonal(m_preconditionedVector,m_AT_A,m_AT_b);
144 pb=&m_preconditionedVector;
147 feLog(
"mid\n%s\n",print(m_tempMatrix).c_str());
148 feLog(
"A'\n%s\nb`=<%s>\n",print(*pA).
c_str(),print(*pb).
c_str());
152 else if(m_preconditioning==e_diagonal_A)
154 premultiplyInverseDiagonal(m_tempMatrix,A,A);
155 postmultiplyInverseDiagonal(m_preconditionedMatrix,
157 pA=&m_preconditionedMatrix;
159 premultiplyInverseDiagonal(m_preconditionedVector,A,b);
160 pb=&m_preconditionedVector;
163 feLog(
"mid\n%s\n",print(m_tempMatrix).c_str());
164 feLog(
"A'\n%s\nb`=<%s>\n",print(*pA).
c_str(),print(*pb).
c_str());
167 #if CG_CHECK_POSITIVE 172 feLog(
"ConjugateGradient2::solve" 173 " non-positive diagonal %d,%d %.6G\n",
178 #if CG_CHECK_POSITIVE 186 F64 value=fabs((*pA)(i,j));
197 feLog(
"ConjugateGradient2::solve non-diagonal peak %d,%d %.6G\n",
202 for(U32 k=1;k<=N;k++)
209 dot_r_1=dot(r_1,r_1);
217 dot_r_1=dot(r_1,r_1);
219 F64 beta=dot_r_1/dot(r_2,r_2);
228 transformVector(*pA,p,Ap);
229 F64 alpha=dot_r_1/dot(p,Ap);
232 if(magnitudeSquared(p)==0.0f)
235 feLog(
"\n%d alpha=%.6G r_1*r_1 %.6G y<%s>\n",
236 k,alpha,dot_r_1,print(y).c_str());
237 feLog(
"r_1<%s>\nr_2<%s>\n",
238 print(r_1).c_str(),print(r_2).c_str());
239 feLog(
"p<%s>\np_1<%s>\nA*p<%s>\n",
240 print(p).c_str(),print(p_1).c_str(),print(*pA*p).c_str());
243 if(magnitudeSquared(p)==0.0f)
245 feX(
"ConjugateGradient2::solve",
"direction lost its magnitude");
260 feLog(
"r<%s>\n",print(r).c_str());
263 feLog(
"ConjugateGradient2::solve ran %d/%d alpha %.6G r %.6G p %.6G\n",
264 k,N,alpha,magnitude(r),magnitude(p));
267 if(magnitudeSquared(r)<1e-4)
271 feLog(
"ConjugateGradient2::solve early solve %d/%d\n",k,N);
277 feLog(
"ConjugateGradient2::solve ran %d/%d\n",k,N);
281 if(m_preconditioning==e_diagonal_A)
283 premultiplyInverseDiagonal(x,A,y);
292 feLog(
"\ny=<%s>\nA'*y=<%s>\n",print(y).c_str(),print(*pA*y).c_str());
293 feLog(
"\nx=<%s>\nA*x=<%s>\n",print(x).c_str(),print(A*x).c_str());
300 if(FE_INVALID_SCALAR(x[k]))
306 F64 distance=magnitude(Ax-b);
307 if(invalid || distance>1.0f)
309 feLog(
"ConjugateGradient2::solve failed to converge (dist=%.6G)\n",
313 feLog(
" collecting state ...\n");
314 feLog(
"A=\n%s\nx=<%s>\nA*x=<%s>\nb=<%s>\n",
315 print(A).c_str(),print(x).c_str(),
316 print(Ax).c_str(),print(b).c_str());
solve Ax=b for x
Definition: ConjugateGradient2.h:38
const FESTRING_I8 * c_str(void) const
Return the contents of the 8-bit buffer cast as signed bytes.
Definition: String.h:352
kernel
Definition: namespace.dox:3
Preconditioning
Choice to alter matrix during solve.
Definition: ConjugateGradient2.h:42