55 if (dot_prod_type == 0)
61 double local_dot = (x * y);
64 MPI_Allreduce(&local_dot, &global_dot, 1, MPI_DOUBLE, MPI_SUM, comm);
76 if (dot_prod_type == 0)
83 MPI_Comm_rank(comm, &rank);
151 double r0, nom, nom0, nomold = 1, cf;
167 nom0 = nom =
Dot(
z,
r);
171 nom0 = nom =
Dot(
r,
r);
175 cout <<
" Iteration : " << setw(3) << 0 <<
" (B r, r) = "
210 cf = sqrt(nom/nomold);
212 cout <<
" Iteration : " << setw(3) << i <<
" (B r, r) = "
213 << nom <<
"\tConv. rate: " << cf <<
'\n';
219 cout <<
"Number of SLI iterations: " << i <<
'\n'
220 <<
"Conv. rate: " << cf <<
'\n';
223 cout <<
"(B r_0, r_0) = " << nom0 <<
'\n'
224 <<
"(B r_N, r_N) = " << nom <<
'\n'
225 <<
"Number of SLI iterations: " << i <<
'\n';
237 cerr <<
"SLI: No convergence!" <<
'\n';
238 cout <<
"(B r_0, r_0) = " << nom0 <<
'\n'
239 <<
"(B r_N, r_N) = " << nom <<
'\n'
240 <<
"Number of SLI iterations: " <<
final_iter <<
'\n';
244 cout <<
"Average reduction factor = "
251 int print_iter,
int max_num_iter,
252 double RTOLERANCE,
double ATOLERANCE)
264 int print_iter,
int max_num_iter,
265 double RTOLERANCE,
double ATOLERANCE)
288 double r0, den, nom, nom0, betanom, alpha, beta;
310 nom0 = nom =
Dot(
d,
r);
313 cout <<
" Iteration : " << setw(3) << 0 <<
" (B r, r) = "
330 cout <<
"Negative denominator in step 0 of PCG: " << den <<
'\n';
361 cout <<
" Iteration : " << setw(3) << i <<
" (B r, r) = "
367 cout <<
"Number of PCG iterations: " << i <<
'\n';
370 cout <<
"(B r_0, r_0) = " << nom0 <<
'\n'
371 <<
"(B r_N, r_N) = " << betanom <<
'\n'
372 <<
"Number of PCG iterations: " << i <<
'\n';
391 cout <<
"PCG: The operator is not postive definite. (Ad, d) = "
398 cerr <<
"PCG: No convergence!" <<
'\n';
399 cout <<
"(B r_0, r_0) = " << nom0 <<
'\n'
400 <<
"(B r_N, r_N) = " << betanom <<
'\n'
401 <<
"Number of PCG iterations: " <<
final_iter <<
'\n';
405 cout <<
"Average reduction factor = "
406 << pow (betanom/nom0, 0.5/
final_iter) <<
'\n';
412 int print_iter,
int max_num_iter,
413 double RTOLERANCE,
double ATOLERANCE)
425 int print_iter,
int max_num_iter,
426 double RTOLERANCE,
double ATOLERANCE)
440 double &cs,
double &sn)
447 else if (fabs(dy) > fabs(dx))
449 double temp = dx / dy;
450 sn = 1.0 / sqrt( 1.0 + temp*temp );
455 double temp = dy / dx;
456 cs = 1.0 / sqrt( 1.0 + temp*temp );
463 double temp = cs * dx + sn * dy;
464 dy = -sn * dx + cs * dy;
474 for (
int i = k; i >= 0; i--)
477 for (
int j = i - 1; j >= 0; j--)
478 y(j) -= h(j,i) * y(i);
481 for (
int j = 0; j <= k; j++)
521 double beta =
Norm(r);
534 cout <<
" Pass : " << setw(2) << 1
535 <<
" Iteration : " << setw(3) << 0
536 <<
" ||B r|| = " << beta <<
'\n';
543 if (v[0] == NULL) v[0] =
new Vector(n);
544 v[0]->Set(1.0/beta, r);
545 s = 0.0; s(0) = beta;
547 for (i = 0; i <
m && j <=
max_iter; i++, j++)
559 for (k = 0; k <= i; k++)
561 H(k,i) =
Dot(w, *v[k]);
562 w.
Add(-H(k,i), *v[k]);
566 if (v[i+1] == NULL) v[i+1] =
new Vector(n);
567 v[i+1]->Set(1.0/H(i+1,i), w);
569 for (k = 0; k < i; k++)
576 resid = fabs(s(i+1));
578 cout <<
" Pass : " << setw(2) << (j-1)/
m+1
579 <<
" Iteration : " << setw(3) << j
580 <<
" ||B r|| = " << resid <<
'\n';
587 for (i = 0; i <=
m; i++)
595 cout <<
"Restarting..." <<
'\n';
614 for (i = 0; i <=
m; i++)
623 for (i = 0; i <=
m; i++)
648 double beta =
Norm(r);
661 cout <<
" Pass : " << setw(2) << 1
662 <<
" Iteration : " << setw(3) << 0
663 <<
" || r || = " << beta << endl;
667 for (i= 0; i<=
m; i++)
676 if (v[0] == NULL) v[0] =
new Vector(b.
Size());
678 v[0] ->
Add (1.0/beta, r);
679 s = 0.0; s(0) = beta;
684 if (z[i] == NULL) z[i] =
new Vector(b.
Size());
690 for (k = 0; k <= i; k++)
692 H(k,i) =
Dot( r, *v[k]);
693 r.Add(-H(k,i), (*v[k]));
697 if (v[i+1] == NULL) v[i+1] =
new Vector(b.
Size());
699 v[i+1] ->
Add (1.0/H(i+1,i), r);
701 for (k = 0; k < i; k++)
708 double resid = fabs(s(i+1));
710 cout <<
" Pass : " << setw(2) << j
711 <<
" Iteration : " << setw(3) << i+1
712 <<
" || r || = " << resid << endl;
719 for (i= 0; i<=
m; i++){
720 if (v[i])
delete v[i];
721 if (z[i])
delete z[i];
728 cout <<
"Restarting..." << endl;
740 for (i= 0; i<=
m; i++){
741 if (v[i])
delete v[i];
742 if (z[i])
delete z[i];
750 for (i = 0; i <=
m; i++)
752 if (v[i])
delete v[i];
753 if (z[i])
delete z[i];
762 int &max_iter,
int m,
double &tol,
double atol,
int printit)
779 int print_iter,
int max_num_iter,
int m,
double rtol,
double atol)
781 GMRES(A, x, b, B, max_num_iter, m, rtol, atol, print_iter);
803 double resid, tol_goal;
804 double rho_1, rho_2=1.0, alpha=1.0, beta, omega=1.0;
820 cout <<
" Iteration : " << setw(3) << 0
821 <<
" ||r|| = " << resid <<
'\n';
825 if (resid <= tol_goal)
839 cout <<
" Iteration : " << setw(3) << i
840 <<
" ||r|| = " << resid <<
'\n';
850 beta = (rho_1/rho_2) * (alpha/omega);
862 if (resid < tol_goal)
866 cout <<
" Iteration : " << setw(3) << i
867 <<
" ||s|| = " << resid <<
'\n';
874 cout <<
" Iteration : " << setw(3) << i
875 <<
" ||s|| = " << resid;
889 cout <<
" ||r|| = " << resid <<
'\n';
890 if (resid < tol_goal)
912 int &max_iter,
double &tol,
double atol,
int printit)
928 int print_iter,
int max_num_iter,
double rtol,
double atol)
930 BiCGSTAB(A, x, b, B, max_num_iter, rtol, atol, print_iter);
954 double beta, eta, gamma0, gamma1, sigma0, sigma1;
955 double alpha, delta, rho1, rho2, rho3, norm_goal;
973 eta = beta = sqrt(
Dot(*z,
v1));
974 gamma0 = gamma1 = 1.;
975 sigma0 = sigma1 = 0.;
980 cout <<
"MINRES: iteration " << setw(3) << 0 <<
": ||r||_B = "
983 if (eta <= norm_goal)
1000 delta = gamma1*alpha - gamma0*sigma1*beta;
1002 rho2 = sigma1*alpha + gamma0*gamma1*beta;
1012 rho1 = hypot(delta, beta);
1015 w0.
Set(1./rho1, *z);
1017 add(1./rho1, *z, -rho2/rho1,
w1,
w0);
1020 add(-rho3/rho1,
w0, -rho2/rho1,
w1,
w0);
1021 w0.
Add(1./rho1, *z);
1025 gamma1 = delta/rho1;
1027 x.
Add(gamma1*eta,
w0);
1035 cout <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1036 << fabs(eta) <<
'\n';
1038 if (fabs(eta) <= norm_goal)
1054 cout <<
"MINRES: number of iterations: " << it <<
'\n';
1056 cout <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1057 << fabs(eta) <<
'\n';
1065 eta = sqrt(
Dot(*z,
v1));
1066 cout <<
"MINRES: iteration " << setw(3) << it <<
": ||r||_B = "
1067 << eta <<
" (re-computed)" <<
'\n';
1071 cerr <<
"MINRES: No convergence!" <<
'\n';
1075 int max_it,
double rtol,
double atol)
1087 int print_it,
int max_it,
double rtol,
double atol)
1105 MFEM_ASSERT(
height ==
width,
"square Operator is required.");
1113 MFEM_ASSERT(
oper != NULL,
"the Operator is not set (use SetOperator).");
1114 MFEM_ASSERT(
prec != NULL,
"the Solver is not set (use SetSolver).");
1117 double norm, norm_goal;
1133 for (it = 0;
true; it++)
1136 cout <<
"Newton iteration " << setw(2) << it
1137 <<
" : ||r|| = " << norm <<
'\n';
1139 if (norm <= norm_goal)
1170 int m_max,
int m_min,
int m_step,
double cf,
1171 double &tol,
double &atol,
int printit)
1178 Vector s(m+1), cs(m+1), sn(m+1);
1185 double normb = w.Norml2();
1193 double beta = r.
Norml2();
1195 resid = beta / normb;
1197 if (resid * resid <= tol) {
1198 tol = resid * resid;
1204 cout <<
" Pass : " << setw(2) << 1
1205 <<
" Iteration : " << setw(3) << 0
1206 <<
" (r, r) = " << beta*beta <<
'\n';
1208 tol *= (normb*normb);
1209 tol = (atol > tol) ? atol : tol;
1213 for (i= 0; i<=m; i++) {
1219 while (j <= max_iter) {
1221 v[0] ->
Add (1.0/beta, r);
1222 s = 0.0; s(0) = beta;
1226 for (i = 0; i < m && j <= max_iter; i++) {
1230 for (k = 0; k <= i; k++) {
1231 H(k,i) = w * (*v[k]);
1232 w.
Add(-H(k,i), (*v[k]));
1235 H(i+1,i) = w.Norml2();
1237 v[i+1] ->
Add (1.0/H(i+1,i), w);
1239 for (k = 0; k < i; k++)
1246 resid = fabs(s(i+1));
1248 cout <<
" Pass : " << setw(2) << j
1249 <<
" Iteration : " << setw(3) << i+1
1250 <<
" (r, r) = " << resid*resid <<
'\n';
1252 if ( resid*resid < tol) {
1254 tol = resid * resid;
1256 for (i= 0; i<=m; i++)
1263 cout <<
"Restarting..." <<
'\n';
1271 if ( resid*resid < tol) {
1272 tol = resid * resid;
1274 for (i= 0; i<=m; i++)
1281 if (m - m_step >= m_min)
1290 tol = resid * resid;
1291 for (i= 0; i<=m; i++)
1311 mfem_error(
"SLBQPOptimizer::SetPreconditioner() : "
1312 "not meaningful for this solver");
1317 mfem_error(
"SLBQPOptimizer::SetOperator() : "
1318 "not meaningful for this solver");
1324 cout <<
"SLBQP iteration " << it <<
": residual = " << r
1325 <<
", lambda = " << l <<
'\n';
1347 const double smin = 0.1;
1353 cout <<
"SLBQP bracketing phase" <<
'\n';
1356 r =
solve(l,xt,x,nclip);
1370 llow = l; rlow = r; l = l + dl;
1373 r =
solve(l,xt,x,nclip);
1376 while ((r < 0) && (nclip <
max_iter))
1380 if (s < smin) { s = smin; }
1385 r =
solve(l,xt,x,nclip);
1393 lupp = l; rupp = r; l = l - dl;
1396 r =
solve(l,xt,x,nclip);
1399 while ((r > 0) && (nclip <
max_iter))
1403 if (s < smin) { s = smin; }
1408 r =
solve(l,xt,x,nclip);
1420 cout <<
"SLBQP secant phase" <<
'\n';
1422 s = 1.0 - rlow/rupp; dl = dl/s; l = lupp - dl;
1425 r =
solve(l,xt,x,nclip);
1428 while ( (fabs(r) > tol) && (nclip <
max_iter) )
1434 lupp = l; rupp = r; s = 1.0 - rlow/rupp;
1435 dl = (lupp - llow)/s; l = lupp - dl;
1440 if (s < smin) { s = smin; }
1442 lnew = 0.75*llow + 0.25*l;
1443 if (lnew < l-dl) { lnew = l-dl; }
1444 lupp = l; rupp = r; l = lnew;
1445 s = (lupp - llow)/(lupp - l);
1453 llow = l; rlow = r; s = 1.0 - rlow/rupp;
1454 dl = (lupp - llow)/s; l = lupp - dl;
1459 if (s < smin) { s = smin; }
1461 lnew = 0.75*lupp + 0.25*l;
1462 if (lnew < l+dl) { lnew = l+dl; }
1463 llow = l; rlow = r; l = lnew;
1464 s = (lupp - llow)/(lupp - l);
1469 r =
solve(l,xt,x,nclip);
1477 cerr <<
"SLBQP not converged!" <<
'\n';
1486 cout <<
"SLBQP iterations = " << nclip <<
'\n';
1487 cout <<
"SLBQP lamba = " << l <<
'\n';
1488 cout <<
"SLBQP residual = " << r <<
'\n';
1492 #ifdef MFEM_USE_SUITESPARSE
1515 umfpack_di_free_numeric(&
Numeric);
1519 umfpack_dl_free_numeric(&
Numeric);
1525 mfem_error(
"UMFPackSolver::SetOperator : not a SparseMatrix!");
1540 int status = umfpack_di_symbolic(
width,
width, Ap, Ai, Ax, &Symbolic,
1545 umfpack_di_report_status(
Control, status);
1547 " umfpack_di_symbolic() failed!");
1550 status = umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &
Numeric,
1555 umfpack_di_report_status(
Control, status);
1557 " umfpack_di_numeric() failed!");
1559 umfpack_di_free_symbolic(&Symbolic);
1563 SuiteSparse_long status;
1567 AI =
new SuiteSparse_long[
width + 1];
1568 AJ =
new SuiteSparse_long[Ap[
width]];
1569 for (
int i = 0; i <=
width; i++)
1570 AI[i] = (SuiteSparse_long)(Ap[i]);
1571 for (
int i = 0; i <= Ap[
width]; i++)
1572 AJ[i] = (SuiteSparse_long)(Ai[i]);
1574 status = umfpack_dl_symbolic(
width,
width,
AI,
AJ, Ax, &Symbolic,
1579 umfpack_dl_report_status(
Control, status);
1581 " umfpack_dl_symbolic() failed!");
1584 status = umfpack_dl_numeric(
AI,
AJ, Ax, Symbolic, &
Numeric,
1589 umfpack_dl_report_status(
Control, status);
1591 " umfpack_dl_numeric() failed!");
1593 umfpack_dl_free_symbolic(&Symbolic);
1600 mfem_error(
"UMFPackSolver::Mult : matrix is not set!"
1601 " Call SetOperator first!");
1608 umfpack_di_report_info(Control,
Info);
1611 umfpack_di_report_status(Control, status);
1612 mfem_error(
"UMFPackSolver::Mult : umfpack_di_solve() failed!");
1617 SuiteSparse_long status =
1620 umfpack_dl_report_info(Control,
Info);
1623 umfpack_dl_report_status(Control, status);
1624 mfem_error(
"UMFPackSolver::Mult : umfpack_dl_solve() failed!");
1632 mfem_error(
"UMFPackSolver::MultTranspose : matrix is not set!"
1633 " Call SetOperator first!");
1640 umfpack_di_report_info(Control,
Info);
1643 umfpack_di_report_status(Control, status);
1645 " umfpack_di_solve() failed!");
1650 SuiteSparse_long status =
1653 umfpack_dl_report_info(Control,
Info);
1656 umfpack_dl_report_status(Control, status);
1658 " umfpack_dl_solve() failed!");
1671 umfpack_di_free_numeric(&
Numeric);
1675 umfpack_dl_free_numeric(&
Numeric);
1680 #endif // MFEM_USE_SUITESPARSE
void ApplyPlaneRotation(double &dx, double &dy, double &cs, double &sn)
Conjugate gradient method.
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator.
double Info[UMFPACK_INFO]
void SetSize(int s)
Resizes the vector if the new size is different.
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols.
double Norml2() const
Returns the l2 norm of the vector.
int Size() const
Returns the size of the vector.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application.
bool iterative_mode
If true, use the second argument of Mult as an initial guess.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
void SortColumnIndices()
Sort the column indices corresponding to each row.
void add(const Vector &v1, const Vector &v2, Vector &v)
double Norm(const Vector &x) const
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
int BiCGSTAB(const Operator &A, Vector &x, const Vector &b, Solver &M, int &max_iter, double &tol, double atol, int printit)
BiCGSTAB method. (tolerances are squared)
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
virtual void Mult(const Vector &b, Vector &x) const
Operator application.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
void SetLinearConstraint(const Vector &_w, double _a)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
double solve(double l, const Vector &xt, Vector &x, int &nclip) const
Solve QP at fixed lambda.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
void MINRES(const Operator &A, const Vector &b, Vector &x, int print_it, int max_it, double rtol, double atol)
MINRES method without preconditioner. (tolerances are squared)
void Add(const double c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
void SetMaxIter(int max_it)
void CG(const Operator &A, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Conjugate gradient method. (tolerances are squared)
void print_iteration(int it, double r, double l) const
void PCG(const Operator &A, Solver &B, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Preconditioned conjugate gradient method. (tolerances are squared)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
double Dot(const Vector &x, const Vector &y) const
double * GetData() const
Return element data.
virtual void Mult(const Vector &b, Vector &x) const
Operator application.
int * GetI() const
Return the array I.
Stationary linear iteration: x <- x + B (b - A x)
void SetAbsTol(double atol)
void SetRelTol(double rtol)
double Control[UMFPACK_CONTROL]
void subtract(const Vector &x, const Vector &y, Vector &z)
void swap(Vector *v1, Vector *v2)
void mfem_error(const char *msg)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
void Update(Vector &x, int k, DenseMatrix &h, Vector &s, Array< Vector * > &v)
void SetDataAndSize(double *d, int s)
Vector & Set(const double a, const Vector &x)
(*this) = a * x
void SetBounds(const Vector &_lo, const Vector &_hi)
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
void GeneratePlaneRotation(double &dx, double &dy, double &cs, double &sn)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void Mult(const Vector &xt, Vector &x) const
Operator application.
virtual void SetOperator(const Operator &op)=0
Set/update the solver for the given operator.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
int aGMRES(const Operator &A, Vector &x, const Vector &b, const Operator &M, int &max_iter, int m_max, int m_min, int m_step, double cf, double &tol, double &atol, int printit)
virtual void SetPreconditioner(Solver &pr)
These are not currently meaningful for this solver and will error out.
int * GetJ() const
Return the array J.
virtual void Mult(const Vector &b, Vector &x) const
Operator application.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
void SLI(const Operator &A, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Stationary linear iteration. (tolerances are squared)
int GMRES(const Operator &A, Vector &x, const Vector &b, Solver &M, int &max_iter, int m, double &tol, double atol, int printit)
GMRES method. (tolerances are squared)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.