def CGsolve(self, x0, b, tol=1.0e-10, nmax = 1000, verbose=1):
		"""
		Solve self*x = b and return x using the conjugate gradient method
		"""
		if not vector.isVector(b):
			raise TypeError, self.__class__,' in solve '
		else:
			if self.size()[0] != len(b) or self.size()[1] != len(b):
				print '**Incompatible sizes in solve'
				print '**size()=', self.size()[0], self.size()[1]
				print '**len=', len(b)
			else:
				kvec = diag(self) # preconditionner
				n = len(b)
				x = x0 # initial guess
				r =  b - dot(self, x)
				try:
					w = r/kvec
				except: print '***singular kvec'
				p = vector.zeros(n);
				beta = 0.0;
				rho = vector.dot(r, w);
				err = vector.norm(dot(self,x) - b);
				k = 0
				if verbose: print " conjugate gradient convergence (log error)"
				while abs(err) > tol and k < nmax:
					p = w + beta*p;
					z = dot(self, p);
					alpha = rho/vector.dot(p, z);
					r = r - alpha*z;
					w = r/kvec;
					rhoold = rho;
					rho = vector.dot(r, w);
					x = x + alpha*p;
					beta = rho/rhoold;
					err = vector.norm(dot(self, x) - b);
					if verbose: print k,' %5.1f ' % math.log10(err)
					k = k+1
				return x

		Solve self*x = b and return x using the conjugate gradient method
		
recipes/Python/52275_sparse_dictionary_based_sparse_matrix/recipe-52275.py