// // Big Vector and Sparse Matrix Classes // #include #include "vec3n.h" float conjgrad_lasterror; float conjgrad_epsilon = 0.1f; int conjgrad_loopcount; int conjgrad_looplimit = 100; /*EXPORTVAR(conjgrad_lasterror); EXPORTVAR(conjgrad_epsilon ); EXPORTVAR(conjgrad_loopcount); EXPORTVAR(conjgrad_looplimit); */ int ConjGradient(float3N &X, float3Nx3N &A, float3N &B) { // Solves for unknown X in equation AX=B conjgrad_loopcount=0; int n=B.count; float3N q(n),d(n),tmp(n),r(n); r = B - Mul(tmp,A,X); // just use B if X known to be zero d = r; float s = dot(r,r); float starget = s * squared(conjgrad_epsilon); while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit) { Mul(q,A,d); // q = A*d; float a = s/dot(d,q); X = X + d*a; if(conjgrad_loopcount%50==0) { r = B - Mul(tmp,A,X); } else { r = r - q*a; } float s_prev = s; s = dot(r,r); d = r+d*(s/s_prev); } conjgrad_lasterror = s; return conjgrad_loopcountstarget && conjgrad_loopcount++ < conjgrad_looplimit) { Mul(q,A,d); // q = A*d; q[hack[0]] = q[hack[1]] = q[hack[2]] = float3(0,0,0); float a = s/dot(d,q); X = X + d*a; if(conjgrad_loopcount%50==0) { r = B - Mul(tmp,A,X); r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0); } else { r = r - q*a; } float s_prev = s; s = dot(r,r); d = r+d*(s/s_prev); d[hack[0]] = d[hack[1]] = d[hack[2]] = float3(0,0,0); } conjgrad_lasterror = s; return conjgrad_loopcountstarget && conjgrad_loopcount++ < conjgrad_looplimit) { Mul(q,A,d); // q = A*d; filter(q,S); float a = s/dot(d,q); X = X + d*a; if(conjgrad_loopcount%50==0) { r = B - Mul(tmp,A,X); filter(r,S); } else { r = r - q*a; } float s_prev = s; s = dot(r,r); d = r+d*(s/s_prev); filter(d,S); } conjgrad_lasterror = s; return conjgrad_loopcount