예제 #1
0
  /// Replace variables as needed
  void visit(VariableExpression& e)
  { 
    VariablePtr vold(e.var());
    OptimizerImplementation::VarMap::const_iterator v = p_vmap.find(vold->name());
    BOOST_ASSERT(v != p_vmap.end());
    VariablePtr vnew(v->second);

    BOOST_ASSERT(vold);
    BOOST_ASSERT(vnew);

    if (vold != vnew) {
      e.var(vnew);
    }
  }
예제 #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;
}