Ejemplo n.º 1
0
//----------------------------------------------------------------------
//
//
//Note this needs to be changed for non-zero k-points!
doublevar Average_ekt::gen_sample(int nstep, doublevar  tstep, 
    int e, Array2 <dcomplex> & movals, Sample_point * sample) { 
  int ndim=3;
  Array1 <doublevar> r(ndim),rold(ndim);
  Array2 <dcomplex> movals_old(nmo,1);
  movals.Resize(nmo,1);

  sample->getElectronPos(e,rold);
  calc_mos(sample,e,movals_old);
  doublevar acc=0;

  for(int step=0; step < nstep; step++) { 
    for(int d=0; d< ndim; d++) { 
      r(d)=rold(d)+sqrt(tstep)*rng.gasdev();
    }
    sample->setElectronPos(e,r);
    calc_mos(sample,e,movals); 

    doublevar sum_old=0,sum=0;
    for(int mo=0; mo < nmo; mo++) { 
      sum_old+=norm(movals_old(mo,0));
      sum+=norm(movals(mo,0));
    }
    if(rng.ulec() < sum/sum_old) { 
      movals_old=movals;
      rold=r;
      acc++;
    }
  }
  //cout << "acceptance " << acc/nstep << endl;

  movals=movals_old;
  sample->setElectronPos(e,rold);

  doublevar sum=0;
  for(int mo=0; mo < nmo; mo++) {
    sum+=norm(movals(mo,0));
  }
  return sum;

}
Ejemplo n.º 2
0
Matrix<double> sparse_bicgstab(SpMatrix* A, Matrix<double> b, Matrix<double> xold, double tol, int maxiter)
// Solves general linear system Ax=b using stabilized biconjugate gradient method of van der Vorst
{
	Matrix<double> rold(b.rows(), 1);
	Matrix<double> r(b.rows(), 1);
	Matrix<double> rhat(b.rows(), 1);
	Matrix<double> t(b.rows(), 1);
	Matrix<double> vold(b.rows(), 1);
	Matrix<double> v(b.rows(), 1);
	Matrix<double> pold(b.rows(), 1);
	Matrix<double> p(b.rows(), 1);
	Matrix<double> s(b.rows(), 1);
	Matrix<double> errdiff(b.rows(), 1);
	Matrix<double> x(b.rows(), 1);
	double rhoold, rho, wold, w, alpha, beta;
	double error, initres;

	A->multiply(xold, &t);		// t = A*xold, initially (t is only a temp variable here)
	rold = b - t;
	initres = error = rold.l2norm();
	int steps = 0;
	int i;

	vold.zeros(); pold.zeros();

	rhat = rold;

	rhoold = alpha = wold = 1.0;

	while(error > tol && steps <= maxiter)
	{
		if(steps % 10 == 0 || steps == 1)
			cout << "sparse_bicgstab(): Iteration " << steps << ": relative error = " << error << endl;

		rho = rhat.dot_product(rold);
		beta = rho*alpha/(rhoold*wold);

		for(i = 0; i < b.rows(); i++)
			p(i) = rold.get(i) + beta * (pold.get(i) - wold*vold.get(i));

		A->multiply(p, &v);			// v = A*p
		alpha = rho / rhat.dot_product(v);

		for(i = 0; i < b.rows(); i++)
			s(i) = rold.get(i) - alpha*v.get(i);

		if(s.dabsmax() < tol*tol)
		{
			x = xold + p*alpha;
			break;
		}

		A->multiply(s, &t);			// t = A*s

		w = t.dot_product(s)/t.dot_product(t);

		for(i = 0; i < b.rows(); i++)
		{
			x(i) = xold.get(i) + alpha*p.get(i) + w*s.get(i);
			error += (x.get(i) - xold.get(i)) * (x.get(i)-xold.get(i));
		}

		error = sqrt(error);

		for(i = 0; i < b.rows(); i++)
			r(i) = s.get(i) - w*t.get(i);

		for(i = 0; i < b.rows(); i++)
		{
			xold(i) = x.get(i);
			rold(i) = r.get(i);
			vold(i) = v.get(i);
			pold(i) = p.get(i);
		}
		rhoold = rho;
		wold = w;
		steps++;
	}

	cout << "sparse_bicgstab(): Done. Iterations: " << steps << ", final relative error: " << error << endl;

	return x;
}
Ejemplo n.º 3
0
Matrix<double> sparsePCG(SpMatrix* A, Matrix<double> b, Matrix<double> xold, string precon, double tol, int maxiter)
/* Calculates solution of Ax=b where A is a SPD matrix in sparse format. The preconditioner is supplied by a function pointer.*/
{
	cout << "sparsePCG(): Solving " << A->rows() << "x" << A->cols() << " system by conjugate gradient method with diagonal preconditioner\n";
	
	void (*precond)(SpMatrix* lhs, const Matrix<double>& r, Matrix<double>& z);
	//const Matrix<double>& z_initial,
	
	if(precon == "jacobi") precond = &precon_jacobi;
	else if(precon == "lusgs") precond = &precon_lusgs;
	
	// check
	//if(A->rows() != b.rows() || A->rows() != xold.rows()) cout << "sparseCG_d(): ! Mismatch in number of rows!!" << endl;

	Matrix<double> x(A->rows(),1);		// solution vector
	Matrix<double> M(A->rows(), 1);		// diagonal preconditioner, or soon, inverse of preconditioner
	Matrix<double> rold(A->rows(),1);		// initial residual = b - A*xold
	Matrix<double> r(A->rows(),1);			// residual = b - A*x
	Matrix<double> z(A->rows(),1);
	Matrix<double> zold(A->rows(),1);
	Matrix<double> p(A->rows(),1);
	Matrix<double> pold(A->rows(),1);
	Matrix<double> temp(A->rows(),1);
	Matrix<double> diff(A->rows(),1);
	double temp1, temp2;
	double theta;
	double beta;
	double error = 1.0;
	double initres;

	//cout << "sparseCG_d(): Declared everything" << endl;

	//M.ones();		// disable preconditioner
	//cout << "sparseCG_d(): preconditioner enabled" << endl;

	A->multiply(xold, &temp);		// temp := A*xold
	rold = b - temp;
	error = initres = rold.l2norm();		// initial residue
	if(error < tol)
	{
		cout << "sparsePCG(): Initial residual is very small. Nothing to do." << endl;
		//x.zeros();
		return xold;
	}

	for(int i = 0; i < A->rows(); i++)
		//zold(i) = M(i)*rold(i);				// zold = M*rold
		zold(i) = rold(i);

	pold = zold;

	int steps = 0;

	do
	{
		if(steps % 10 == 0 || steps == 1)
			cout << "sparsePCG(): Iteration " << steps << ", relative residual = " << error << endl;
		int i;

		temp1 = rold.dot_product(zold);

		A->multiply(pold, &temp);
		//temp.mprint();

		temp2 = pold.dot_product(temp);
		if(temp2 <= 0) cout << "sparsePCG: ! Matrix A is not positive-definite!! temp2 is " << temp2 << "\n";
		theta = temp1/temp2;

		//#pragma omp parallel for default(none) private(i) shared(x,r,xold,rold,pold,temp,theta) //num_threads(nthreads_linalg)
		for(i = 0; i < x.rows(); i++)
		{
			//cout << "Number of threads " << omp_get_num_threads();
			x(i) = xold.get(i) + pold.get(i)*theta;
			rold(i) = rold.get(i) - temp.get(i)*theta;
			//diff(i) = x(i) - xold(i);
		}
		//cout << "x:\n"; x.mprint();
		//cout << "r:\n"; r.mprint();

		if(steps > 5)
		{
			// calculate zold as (M^-1)*rold
			precond(A, rold, zold);
		}
		else
		{
			//#pragma omp parallel for default(none) private(i) shared(zold,M,rold,A)
			for(i = 0; i < A->rows(); i++)
				zold(i) = rold(i);
		}

		beta = rold.dot_product(zold) / temp1;

		//#pragma omp parallel for default(none) private(i) shared(zold,x,p,pold,beta)
		for(i = 0; i < x.rows(); i++)
			pold(i) = zold.get(i) + pold.get(i)*beta;

		//calculate ||b - A*x||
		error = rold.l2norm();
		//calculate ||x - xold||
		//error = diff.l2norm();
		//if(steps == 0) initres = error;

		// set old variables
		xold = x;
		/*rold = r;
		zold = z;
		pold = p;*/

		if(steps > maxiter)
		{
			cout << "! sparsePCG(): Max iterations reached!\n";
			break;
		}
		steps++;
	} while(error > tol);

	cout << "sparsePCG(): Done. Number of iterations: " << steps << "; final residual " << error << ".\n";
	return xold;
}