7 #ifndef __solve_BiconjugateGradient_h__ 8 #define __solve_BiconjugateGradient_h__ 10 #define BCG_DEBUG FALSE 11 #define BCG_TRACE FALSE 12 #define BCG_VERIFY (FE_CODEGEN<=FE_DEBUG) 33 template <
typename MATRIX,
typename VECTOR>
46 m_preconditioning(e_none) {}
48 void solve(VECTOR& x,
const MATRIX& A,
const VECTOR& b);
50 void setThreshold(F64 threshold) { m_threshold=threshold; }
53 { m_preconditioning=preconditioning; }
57 VECTOR rbar,rbar_1,rbar_2;
62 VECTOR m_preconditionedVector;
63 MATRIX m_preconditionedMatrix;
68 template <
typename MATRIX,
typename VECTOR>
70 const MATRIX& A,
const VECTOR& b)
86 feLog(
"\nA\n%s\nb=<%s>\n",fe::print(A).c_str(),fe::print(b).c_str());
89 if(magnitudeSquared(b)<m_threshold)
92 feLog(
"BiconjugateGradient::solve has trivial solution\n");
99 if(m_preconditioning==e_diagonal_A)
101 const MATRIX& preconditioner=A;
102 premultiplyInverseDiagonal(m_preconditionedMatrix,preconditioner,A);
103 pA=&m_preconditionedMatrix;
105 premultiplyInverseDiagonal(m_preconditionedVector,preconditioner,b);
106 pb=&m_preconditionedVector;
109 feLog(
"A'\n%s\nb`=<%s>\n",fe::print(*pA).
c_str(),fe::print(*pb).
c_str());
113 for(U32 k=1;k<=N;k++)
123 dot_r_1=dot(rbar_1,r_1);
135 dot_r_1=dot(rbar_1,r_1);
137 F64 beta=dot_r_1/dot(rbar_2,r_2);
152 transformVector(*pA,p,Ap);
153 F64 alpha=dot_r_1/dot(pbar,Ap);
156 if(magnitudeSquared(p)==0.0f)
159 feLog(
"\n%d alpha=%.6G x<%s>\n",k,alpha,fe::print(x).c_str());
160 feLog(
"r<%s>\nr_1<%s>\nr_2<%s>\n",
161 fe::print(r).c_str(),fe::print(r_1).c_str(),fe::print(r_2).c_str());
162 feLog(
"rbar<%s>\nrbar_1<%s>\nrbar_2<%s>\n",
163 fe::print(rbar).c_str(),fe::print(rbar_1).c_str(),
164 fe::print(rbar_2).c_str());
165 feLog(
"p<%s>\np_1<%s>\nA*p<%s>\n",
166 fe::print(p).c_str(),fe::print(p_1).c_str(),fe::print(*pA*p).c_str());
167 feLog(
"pbar<%s>\npbar_1<%s>\n",
168 fe::print(pbar).c_str(),fe::print(pbar_1).c_str());
171 if(magnitudeSquared(p)==0.0f)
173 feX(
"BiconjugateGradient::solve",
"direction lost its magnitude");
188 transposeTransformVector(*pA,pbar,temp);
193 if(magnitudeSquared(r)<m_threshold)
196 feLog(
"BiconjugateGradient::solve early solve %d/%d\n",k,N);
203 feLog(
"BiconjugateGradient::solve ran %d/%d\n",k,N);
209 feLog(
"\nx=<%s>\nA*x=<%s>\n",fe::print(x).c_str(),fe::print(A*x).c_str());
216 if(FE_INVALID_SCALAR(x[k]))
222 F64 distance=magnitude(Ax-b);
223 if(invalid || distance>1.0f)
225 feLog(
"BiconjugateGradient::solve failed to converge (dist=%.6G)\n",
229 feLog(
" collecting state ...\n");
230 feLog(
"A=\n%s\nx=<%s>\nA*x=<%s>\nb=<%s>\n",
231 fe::print(A).c_str(),fe::print(x).c_str(),
232 fe::print(Ax).c_str(),fe::print(b).c_str());
243 template <
typename T>
solve Ax=b for x
Definition: BiconjugateGradient.h:34
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
Matrix< 4, 4, T > & invert(Matrix< 4, 4, T > &a_inverted, const Matrix< 4, 4, T > &a_matrix)
4x4 full matrix inversion
Definition: Matrix.h:1033
General template for fixed size numeric matrices.
Definition: Matrix.h:42
Preconditioning
Choice to alter matrix during solve.
Definition: BiconjugateGradient.h:38
Partially specialized 4-component vector intended for spatial use.
Definition: Vector4.h:21