7 #ifndef __solve_ConjugateGradient_h__ 8 #define __solve_ConjugateGradient_h__ 10 #define CG_DEBUG FALSE 11 #define CG_TRACE FALSE 13 #define CG_CHECK_SYMMETRY (FE_CODEGEN<FE_DEBUG) 14 #define CG_CHECK_POSITIVE (FE_CODEGEN<FE_DEBUG) 15 #define CG_CHECK_PEAK (FE_CODEGEN<FE_DEBUG) 16 #define CG_VERIFY (FE_CODEGEN<=FE_DEBUG) 17 #define CG_EXCEPTION (FE_CODEGEN<=FE_DEBUG) 37 template <
typename MATRIX,
typename VECTOR>
44 void solve(VECTOR& x,
const MATRIX& A,
const VECTOR& b);
46 void setThreshold(F64 threshold) { m_threshold=threshold; }
56 template <
typename MATRIX,
typename VECTOR>
58 const MATRIX& A,
const VECTOR& b)
72 feLog(
"\nA\n%s\nb=<%s>\n",c_print(A),c_print(b));
76 for(U32 iy=0;iy<N;iy++)
78 for(U32 ix=iy;ix<N;ix++)
80 if(fabs(A(ix,iy)-A(iy,ix))>1e-9f)
82 feLog(
"ConjugateGradient symmetry error %d,%d %.6G %.6G\n",
83 ix,iy,A(ix,iy),A(iy,ix));
86 feX(
"ConjugateGradient::solve",
"unsymmetrical");
93 if(magnitudeSquared(b)<m_threshold)
96 feLog(
"ConjugateGradient::solve has trivial solution\n");
103 #if CG_CHECK_POSITIVE 108 feLog(
"ConjugateGradient::solve" 109 " non-positive diagonal %d,%d %.6G\n",
122 F64 value=fabs((*pA)(i,j));
133 feLog(
"ConjugateGradient::solve non-diagonal peak %d,%d %.6G\n",
145 transformVector(*pA,d,q);
147 feLog(
"\n%d q=A*d >>> %.6G <<<\n",i,dnew);
148 feLog(
"d<%s>\n",c_print(d));
149 feLog(
"q<%s>\n",c_print(q));
152 F64 alpha=dnew/dot(d,q);
154 feLog(
"alpha=dnew/dot(d,q) %.6G=%.6G/%.6G\n",alpha,dnew,dot(d,q));
158 feLog(
"x<%s>\n",c_print(x));
166 addScaled(x,alpha,d);
168 feLog(
"x+=alpha*d <%s>\n",c_print(temp));
169 feLog(
"x<%s>\n",c_print(x));
173 feLog(
"r<%s>\n",c_print(r));
181 addScaled(r,-alpha,q);
183 feLog(
"r-=alpha*q <%s>\n",c_print(temp));
184 feLog(
"r<%s>\n",c_print(r));
191 feLog(
"dnew=%.6G dold=%.6G beta=%.6G\n",dnew,dold,beta);
201 scaleAndAdd(d,beta,r);
204 feLog(
"d=r+beta*d <%s>\n",c_print(temp));
205 feLog(
"d<%s>\n",c_print(d));
208 if(magnitudeSquared(d)==0.0f)
213 feLog(
"ConjugateGradient::solve direction lost its magnitude\n");
221 feLog(
"ConjugateGradient::solve" 222 " ran %d/%d alpha %.6G |r| %.6G |d| %.6G\n",
223 i,N,alpha,magnitude(r),magnitude(d));
226 if(magnitudeSquared(r)<m_threshold)
229 feLog(
"ConjugateGradient::solve early solve %d/%d\n",i,N);
236 feLog(
"ConjugateGradient::solve ran %d/%d\n",i,N);
241 feLog(
"\nx=<%s>\nA*x=<%s>\n",c_print(x),c_print(A*x));
242 feLog(
"\nb=<%s>\n",c_print(b));
249 if(FE_INVALID_SCALAR(x[k]))
255 F64 distance=magnitude(Ax-b);
256 if(invalid || distance>1.0f)
258 feLog(
"ConjugateGradient::solve failed to converge (dist=%.6G)\n",
262 feLog(
" collecting state ...\n");
263 feLog(
"A=\n%s\nx=<%s>\nA*x=<%s>\nb=<%s>\n",
264 c_print(A),c_print(x),
265 c_print(Ax),c_print(b));
kernel
Definition: namespace.dox:3
solve Ax=b for x
Definition: ConjugateGradient.h:38