LinearEquation* run_linbcg(LinearEquation *leq, float tolerance, int max_iterations) { int iterations; double error; /* Solves A · x = b for x[1..n], given b[1..n], by the iterative biconjugate gradient method. On input x[1..n] should be set to an initial guess of the solution (or all zeros); itol is 1,2,3, or 4, specifying which convergence test is applied (see text); itmax is the maximum number of allowed iterations; and tol is the desired convergence tolerance. On output, x[1..n] is reset to the improved solution, iter is the number of iterations actually taken, and err is the estimated error. The matrix A is referenced only through the user-supplied routines atimes, which computes the product of either A or its transpose on a vector; and asolve, which solves A · x = b or A' · x = b for some preconditioner matrix A (possibly the trivial diagonal part of A). */ linbcg(leq->sa, leq->ija, leq->n, leq->b, leq->x, 1, tolerance, max_iterations, &iterations, &error); return leq; }
// transform gradients to luminance static void transform_to_luminance(pyramid_t* pp, float* const x, pfstmo_progress_callback progress_cb, const bool bcg, const int itmax, const float tol) { pyramid_t* pC = pyramid_allocate(pp->cols, pp->rows); pyramid_calculate_scale_factor(pp, pC); // calculate (Cx,Cy) pyramid_scale_gradient(pp, pC); // scale small gradients by (Cx,Cy); float* b = matrix_alloc(pp->cols * pp->rows); pyramid_calculate_divergence_sum(pp, b); // calculate the sum of divergences (equal to b) // calculate luminances from gradients if (bcg) linbcg(pp, pC, b, x, itmax, tol, progress_cb); else lincg(pp, pC, b, x, itmax, tol, progress_cb); matrix_free(b); pyramid_free(pC); }
int main(void) { int i,ii,iter; double *b,*bcmp,*x,err; b=dvector(1,NP); bcmp=dvector(1,NP); x=dvector(1,NP); for (i=1;i<=NP;i++) { x[i]=0.0; b[i]=1.0; } b[1]=3.0; b[NP] = -1.0; linbcg(NP,b,x,ITOL,TOL,ITMAX,&iter,&err); printf("%s %15e\n","Estimated error:",err); printf("%s %6d\n","Iterations needed:",iter); printf("\nSolution vector:\n"); for (ii=1;ii<=NP/5;ii++) { for (i=5*(ii-1)+1;i<=5*ii;i++) printf("%12.6f",x[i]); printf("\n"); } for (i=1;i<=(NP % 5);i++) printf("%12.6f",x[5*(NP/5)+i]); printf("\n"); dsprsax(sa,ija,x,bcmp,NP); /* this is a double precision version of sprsax */ printf("\npress RETURN to continue...\n"); (void) getchar(); printf("test of solution vector:\n"); printf("%9s %12s\n","a*x","b"); for (i=1;i<=NP;i++) printf("%12.6f %12.6f\n",bcmp[i],b[i]); free_dvector(x,1,NP); free_dvector(bcmp,1,NP); free_dvector(b,1,NP); return 0; }